summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/Weapon.h
blob: 4fadd8028c977e672a7f4bcd46fae7a06eaed9bc (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*  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
    ========
    Weapon (gun or missile launcher) class
*/

#pragma once

#include <cstdint>

#include "Text.h"

#include "SimObject.h"
#include "System.h"
#include "WeaponDesign.h"
#include "Geometry.h"

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

class Weapon;
class Ship;
class Shot;

class Solid;

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

class Weapon : public System, public SimObserver
{
public:
    static const char* TYPENAME() { return "Weapon"; }

    enum Constants { MAX_BARRELS=8 };
    enum Orders    { MANUAL, AUTO, POINT_DEFENSE };
    enum Control   { SINGLE_FIRE, RIPPLE_FIRE, SALVO_FIRE };
    enum Sweep     { SWEEP_NONE, SWEEP_TIGHT, SWEEP_WIDE };

    Weapon(WeaponDesign* d, int nmuz, Vec3* muzzles, double az=0, double el=0);
    Weapon(const Weapon& rhs);
    virtual ~Weapon();

    int operator==(const Weapon& w) const { return this == &w; }

    int               Track(SimObject* targ, System* sub);
    Shot*             Fire();
    Shot*             NetFirePrimary(SimObject* targ, System* sub, int count);
    Shot*             NetFireSecondary(SimObject* targ, System* sub, std::uint32_t objid);
    void              SetTarget(SimObject* t, System* sub);
    void              SelectTarget();
    bool              CanTarget(std::uint32_t classification) const;  // TODO
    SimObject*         GetTarget() const { return target;     }
    System*           GetSubTarget() const { return subtarget; }
    void              SetFiringOrders(int o);
    int               GetFiringOrders()          const    { return orders; }
    void              SetControlMode(int m);
    int               GetControlMode()           const    { return control; }
    void              SetSweep(int s);
    int               GetSweep()                 const    { return sweep;   }

    void              Enable()    { enabled = true; }
    void              Disable()   { enabled = false; }

    const WeaponDesign* Design()  const { return design;        }
    const char*       Group()     const { return group;         }
    int               Enabled()   const { return enabled;       }
    int               Ammo()      const { return ammo;          }
    int               Guided()    const { return guided;        }
    int               Locked()    const { return locked;        }
    float             Velocity()  const { return shot_speed;    }
    float             Mass()      const { return mass*ammo;     }
    float             Resistance()const { return resist*ammo;   }
    Shot*             GetBeam(int i);

    // needed to set proper ammo level when joining multiplayer in progress:
    void              SetAmmo(int a);

    bool              IsPrimary() const;
    bool              IsDrone()   const;
    bool              IsDecoy()   const;
    bool              IsProbe()   const;
    bool              IsMissile() const;
    bool              IsBeam()    const;

    virtual void      ExecFrame(double factor);
    virtual void      Orient(const Physical* rep);
    virtual void      Distribute(double delivered_energy, double seconds);

    const Ship*       Owner() const              { return ship;  }
    void              SetOwner(Ship* ship);
    int               GetIndex()  const          { return index; }
    void              SetIndex(int n)            { index = n;    }

    Point             GetAimVector() const       { return aim_cam.vpn();       }
    void              SetAzimuth(double a)       { aim_azimuth = (float) a;    }
    double            GetAzimuth()   const       { return aim_azimuth;         }
    void              SetElevation(double e)     { aim_elevation = (float) e;  }
    double            GetElevation() const       { return aim_elevation;       }

    void              SetRestAzimuth(double a)   { aim_az_rest = (float) a;    }
    double            GetRestAzimuth()   const   { return aim_az_rest;         }
    void              SetRestElevation(double e) { aim_el_rest = (float) e;    }
    double            GetRestElevation() const   { return aim_el_rest;         }

    void              SetAzimuthMax(double a)    { aim_az_max = (float) a;     }
    double            GetAzimuthMax() const      { return aim_az_max;          }
    void              SetAzimuthMin(double a)    { aim_az_min = (float) a;     }
    double            GetAzimuthMin() const      { return aim_az_min;          }

    void              SetElevationMax(double e)  { aim_el_max = (float) e;     }
    double            GetElevationMax() const    { return aim_el_max;          }
    void              SetElevationMin(double e)  { aim_el_min = (float) e;     }
    double            GetElevationMin() const    { return aim_el_min;          }

    void              SetGroup(const char* n)    { group = n;                  }

    bool              IsBlockedFriendly() const  { return blocked;             }
    void              SetBlockedFriendly(bool b) { blocked = b;                }

    Solid*            GetTurret();
    Solid*            GetTurretBase();
    Solid*            GetVisibleStore(int i);

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

protected:
    Shot*             FireBarrel(int n);
    Shot*             CreateShot(const Point& loc, const Camera& cam, WeaponDesign* dsn, const Ship* owner);

    void              SetBeamPoints(bool aim=false);
    void              Aim();
    void              AimTurret(double az, double el);
    void              ZeroAim();
    void              FindObjective();
    Point             Transform(const Point& pt);
    bool              CanLockPoint(const Point& test, double& az, double& el, Point* obj=0);

    // data members:
    WeaponDesign*     design;
    Text              group;
    Point             muzzle_pts[MAX_BARRELS];
    Point             rel_pts[MAX_BARRELS];
    Solid*            turret;
    Solid*            turret_base;
    Solid*            visible_stores[MAX_BARRELS];
    int               nbarrels;
    int               active_barrel;

    float             refire;
    int               ammo;
    int               ripple_count;

    // carrying costs per shot:
    float             mass;
    float             resist;

    // for targeting computer:
    int               guided;
    bool              enabled;
    bool              locked;
    bool              centered;
    bool              firing;
    bool              blocked;
    float             shot_speed;

    int               index;

    int               orders;
    int               control;
    int               sweep;

    SimObject*        target;
    System*           subtarget;

    Point             objective;
    Point             obj_w;
    Camera            aim_cam;
    float             aim_azimuth;
    float             aim_elevation;
    float             old_azimuth;
    float             old_elevation;

    // auto-aiming arc
    float             aim_az_max;       // maximum deflection in azimuth
    float             aim_az_min;       // minimum deflection in azimuth
    float             aim_az_rest;      // azimuth of turret at rest
    float             aim_el_max;       // maximum deflection in elevation
    float             aim_el_min;       // minimum deflection in elevation
    float             aim_el_rest;      // elevation of turret at rest

    std::uint32_t     aim_time;

    Shot**            beams;
};