summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/SteerAI.h
blob: 0f5c8872892413ce4da1eefe9c1f4bfbce6bd1af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*  Starshatter: The Open Source Project
    Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors
    Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
    Copyright (c) 1997-2006, Destroyer Studios LLC.

    AUTHOR:       John DiCamillo


    OVERVIEW
    ========
    Steering (low-level) Artifical Intelligence class
*/

#pragma once

#include "Director.h"
#include "Geometry.h"
#include "SimObject.h"

// +--------------------------------------------------------------------+

class System;

// +--------------------------------------------------------------------+

struct Steer
{
    Steer() : yaw(0), pitch(0), roll(0), brake(0), stop(0) { }
    Steer(double y, double p, double r, double b=0) : yaw(y), pitch(p), roll(r), brake(b), stop(0) { }
    Steer(const Steer& s) : yaw(s.yaw), pitch(s.pitch), roll(s.roll), brake(s.brake), stop(s.stop) { }

    Steer& operator = (const Steer& s) { yaw=s.yaw; pitch=s.pitch; roll=s.roll; brake = s.brake; stop = s.stop; return *this; }

    Steer  operator+(const Steer& s) const;
    Steer  operator-(const Steer& s) const;
    Steer  operator*(double f)       const;
    Steer  operator/(double f)       const;

    Steer& operator+=(const Steer& s);
    Steer& operator-=(const Steer& s);

    double Magnitude() const;

    void Clear() { yaw=0; pitch=0; roll=0; brake=0; stop=0; }

    double yaw, pitch, roll;
    double brake;
    int    stop;
};

// +--------------------------------------------------------------------+

class SteerAI : public Director, public SimObserver
{
public:
    enum Type { SEEKER = 1000, FIGHTER, STARSHIP, GROUND };

    SteerAI(SimObject* self);
    virtual ~SteerAI();

    static Director*  Create(SimObject*, int type);

    virtual void      SetTarget(SimObject* targ, System* sub=0);
    virtual SimObject* GetTarget() const { return target; }
    virtual System*   GetSubTarget() const { return subtarget; }
    virtual void      DropTarget(double drop_time=1.5);
    virtual int       Type()      const { return ai_type; }

    virtual bool         Update(SimObject* obj);
    virtual const char*  GetObserverName() const;

    // debug:
    virtual Point        GetObjective() const { return obj_w; }
    virtual SimObject*   GetOther()     const { return other; }

protected:

    // accumulate behaviors:
    virtual void      Navigator();
    virtual int       Accumulate(const Steer& steer);

    // steering functions:
    virtual Steer     Seek(const Point& point);
    virtual Steer     Flee(const Point& point);
    virtual Steer     Avoid(const Point& point, float radius);
    virtual Steer     Evade(const Point& point, const Point& vel);

    // compute the goal point based on target stats:
    virtual void      FindObjective();
    virtual Point     ClosingVelocity();

    virtual Point     Transform(const Point& pt);
    virtual Point     AimTransform(const Point& pt);

    int               seeking;

    SimObject*        self;
    SimObject*        target;
    System*           subtarget;
    SimObject*        other;

    Point             obj_w;
    Point             objective;

    double            distance;
    double            az[3], el[3];

    Steer             accumulator;
    double            magnitude;
    std::uint32_t     evade_time;

    double            seek_gain;
    double            seek_damp;

    int               ai_type;
};