summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/Ship.h
blob: 2e04cba69694e5f04673d1f0cab57c1bdbeb9ad9 (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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
/*  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
    ========
    Starship (or space/ground station) class
*/

#pragma once

#include <cstdint>

#include <List.h>

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

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

class Ship;
class Shot;
class Drone;

class Bitmap;
class CombatUnit;
class Computer;
class Contact;
class Drive;
class Element;
class Farcaster;
class FlightComp;
class FlightDeck;
class Hangar;
class InboundSlot;
class Instruction;
class LandingGear;
class MotionController;
class NavLight;
class NavSystem;
class PowerSource;
class QuantumDrive;
class RadioMessage;
class Shield;
class ShieldRep;
class ShipDesign;
class ShipKiller;
class Solid;
class Skin;
class Sound;
class Sensor;
class System;
class Thruster;
class Weapon;
class WeaponDesign;
class WeaponGroup;

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

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

    enum CLASSIFICATION {
        DRONE             = 0x0001,
        FIGHTER           = 0x0002,
        ATTACK            = 0x0004,
        LCA               = 0x0008,
        COURIER           = 0x0010,
        CARGO             = 0x0020,
        CORVETTE          = 0x0040,
        FREIGHTER         = 0x0080,
        FRIGATE           = 0x0100,
        DESTROYER         = 0x0200,
        CRUISER           = 0x0400,
        BATTLESHIP        = 0x0800,
        CARRIER           = 0x1000,
        DREADNAUGHT       = 0x2000,

        STATION           = 0x4000,
        FARCASTER         = 0x8000,

        MINE              = 0x00010000,
        COMSAT            = 0x00020000,
        DEFSAT            = 0x00040000,
        SWACS             = 0x00080000,

        BUILDING          = 0x00100000,
        FACTORY           = 0x00200000,
        SAM               = 0x00400000,
        EWR               = 0x00800000,
        C3I               = 0x01000000,
        STARBASE          = 0x02000000,

        DROPSHIPS         = 0x0000000f,
        STARSHIPS         = 0x0000fff0,
        SPACE_UNITS       = 0x000f0000,
        GROUND_UNITS      = 0xfff00000
    };

    enum OP_MODE   { DOCKED, ALERT, LOCKED, LAUNCH, TAKEOFF, ACTIVE, APPROACH, RECOVERY, DOCKING };
    enum FLCS_MODE { FLCS_MANUAL, FLCS_AUTO, FLCS_HELM };
    enum TRAN_TYPE { TRANSITION_NONE,
        TRANSITION_DROP_CAM,
        TRANSITION_DROP_ORBIT,
        TRANSITION_MAKE_ORBIT,
        TRANSITION_TIME_SKIP,
        TRANSITION_DEATH_SPIRAL,
        TRANSITION_DEAD };

    enum FLIGHT_MODEL    { FM_STANDARD, FM_RELAXED, FM_ARCADE };
    enum LANDING_MODEL   { LM_STANDARD, LM_EASIER };

    // CONSTRUCTORS:
    Ship(const char* ship_name, const char* reg_num, ShipDesign* design, int IFF=0, int cmd_ai=0, const int* loadout=0);
    virtual ~Ship();

    int operator == (const Ship& s) const { return id == s.id; }

    static void       Initialize();
    static void       Close();

    virtual void      ExecFrame(double seconds);
    virtual void      AeroFrame(double seconds);
    virtual void      StatFrame(double seconds);
    virtual void      DockFrame(double seconds);
    virtual void      LinearFrame(double seconds);
    virtual void      ExecSensors(double seconds);

    void              ExecNavFrame(double seconds);
    void              ExecPhysics(double seconds);
    void              ExecThrottle(double seconds);
    void              ExecSystems(double seconds);

    virtual void      Activate(Scene& scene);
    virtual void      Deactivate(Scene& scene);
    virtual void      SelectDetail(double seconds);
    virtual void      SetRegion(SimRegion* rgn);
    virtual int       GetTextureList(List<Bitmap>& textures);

    // DIRECTION:
    virtual void      SetControls(MotionController* m);
    virtual void      SetNetworkControl(Director* net_ctrl=0);
    void              SetDirectorInfo(const char* msg) { director_info = msg; }
    const char*       GetDirectorInfo()          const { return director_info; }
    void              SetAIMode(int n)                 { ai_mode = static_cast<std::uint8_t>(n); }
    int               GetAIMode()                const { return (int) ai_mode; }
    void              SetCommandAILevel(int n)         { command_ai_level = static_cast<std::uint8_t>(n); }
    int               GetCommandAILevel()        const { return command_ai_level; }
    virtual int       GetFlightPhase()           const { return flight_phase; }
    virtual void      SetFlightPhase(OP_MODE phase);
    bool              IsNetObserver()            const { return net_observer_mode; }
    void              SetNetObserver(bool n)           { net_observer_mode = n;    }

    bool              IsInvulnerable()           const { return invulnerable;      }
    void              SetInvulnerable(bool n)          { invulnerable = n;         }

    double            GetHelmHeading()     const { return helm_heading;  }
    double            GetHelmPitch()       const { return helm_pitch;    }
    void              SetHelmHeading(double h);
    void              SetHelmPitch(double p);
    virtual void      ApplyHelmYaw(double y);
    virtual void      ApplyHelmPitch(double p);
    virtual void      ApplyPitch(double pitch_acc); // override for G limiter

    void              ArcadeStop()               { arcade_velocity *= 0; }

    // CAMERA:
    Point             BridgeLocation()     const { return bridge_vec;       }
    Point             ChaseLocation()      const { return chase_vec;        }
    Point             TransitionLocation() const { return transition_loc;   }

    // FLIGHT DECK:
    Ship*             GetController()    const;
    int               NumInbound()       const;
    int               NumFlightDecks()   const;
    FlightDeck*       GetFlightDeck(int i=0) const;
    Ship*             GetCarrier()       const { return carrier;       }
    FlightDeck*       GetDock()          const { return dock;          }
    void              SetCarrier(Ship* c, FlightDeck* d);
    void              Stow();
    InboundSlot*      GetInbound()      const { return inbound;       }
    void              SetInbound(InboundSlot* s);

    // DRIVE SYSTEMS:
    int               GetFuelLevel()       const; // (0-100) percent of full tank
    void              SetThrottle(double percent);
    void              SetAugmenter(bool  enable);
    double            Thrust(double seconds) const;
    double            VelocityLimit()      const { return vlimit;        }
    Drive*            GetDrive()           const { return main_drive;    }
    double            Throttle()           const { return throttle;      }
    bool              Augmenter()          const { return augmenter;     }
    QuantumDrive*     GetQuantumDrive()    const { return quantum_drive; }
    Farcaster*        GetFarcaster()       const { return farcaster;     }

    bool              IsAirborne()         const;
    bool              IsDropCam()          const { return transition_type == TRANSITION_DROP_CAM;     }
    bool              IsDropping()         const { return transition_type == TRANSITION_DROP_ORBIT;   }
    bool              IsAttaining()        const { return transition_type == TRANSITION_MAKE_ORBIT;   }
    bool              IsSkipping()         const { return transition_type == TRANSITION_TIME_SKIP;    }
    bool              IsDying()            const { return transition_type == TRANSITION_DEATH_SPIRAL; }
    bool              IsDead()             const { return transition_type == TRANSITION_DEAD;         }
    bool              InTransition()       const { return transition_type != TRANSITION_NONE;         }
    void              DropOrbit();
    void              MakeOrbit();
    bool              CanTimeSkip();
    bool              IsInCombat();
    void              TimeSkip();
    void              DropCam(double time=10, double range=0);
    void              DeathSpiral();
    void              CompleteTransition();
    void              SetTransition(double trans_time, int trans_type, const Point& trans_loc);

    double            CompassHeading()     const;
    double            CompassPitch()       const;
    double            AltitudeMSL()        const;
    double            AltitudeAGL()        const;
    double            GForce()             const;

    virtual void      SetupAgility();

    // FLIGHT CONTROL SYSTEM (FLCS):
    void              ExecFLCSFrame();
    void              CycleFLCSMode();
    void              SetFLCSMode(int mode);
    int               GetFLCSMode() const;
    void              SetTransX(double t);
    void              SetTransY(double t);
    void              SetTransZ(double t);

    bool              IsGearDown();
    void              LowerGear();
    void              RaiseGear();
    void              ToggleGear();
    void              ToggleNavlights();

    // WEAPON SYSTEMS:
    virtual void      CheckFriendlyFire();
    virtual void      CheckFire(bool c)          { check_fire = c;               }
    virtual bool      CheckFire()       const    { return (check_fire||net_observer_mode)?true:false; }
    virtual void      SelectWeapon(int n, int w);
    virtual bool      FireWeapon(int n);
    virtual bool      FirePrimary()              { return FireWeapon(primary);   }
    virtual bool      FireSecondary()            { return FireWeapon(secondary); }
    virtual bool      FireDecoy();
    virtual void      CyclePrimary();
    virtual void      CycleSecondary();
    virtual Weapon*   GetPrimary()      const;
    virtual Weapon*   GetSecondary()    const;
    virtual Weapon*   GetWeaponByIndex(int n);
    virtual WeaponGroup* GetPrimaryGroup()      const;
    virtual WeaponGroup* GetSecondaryGroup()    const;
    virtual Weapon*   GetDecoy()        const;
    virtual List<Shot>& GetActiveDecoys();
    virtual void      AddActiveDecoy(Drone* d);
    virtual int*      GetLoadout()               { return loadout; }

    List<Shot>&       GetThreatList();
    void              AddThreat(Shot* s);
    void              DropThreat(Shot* s);

    virtual bool         Update(SimObject* obj);
    virtual const char*  GetObserverName() const { return name; }

    virtual int       GetMissileEta(int index) const;
    virtual void      SetMissileEta(int id, int eta);

    virtual WeaponDesign*   GetPrimaryDesign()      const;
    virtual WeaponDesign*   GetSecondaryDesign()    const;

    virtual void      SetTarget(SimObject* t, System* sub=0, bool from_net=false);
    virtual SimObject* GetTarget()      const    { return target;     }
    virtual System*   GetSubTarget()    const    { return subtarget;  }
    virtual void      CycleSubTarget(int dir=1);
    virtual void      DropTarget();
    virtual void      LockTarget(int  type=SimObject::SIM_SHIP,
    bool closest=false,
    bool hostile=false);
    virtual void      LockTarget(SimObject* candidate);
    virtual bool      IsTracking(SimObject* tgt);
    virtual bool      GetTrigger(int i) const;
    virtual void      SetTrigger(int i);

    Ship*             GetWard()         const    { return ward;          }
    void              SetWard(Ship* s);

    // SHIELD SYSTEMS:
    virtual double    InflictDamage(double damage,
    Shot*  shot        = 0,
    int    hit_type    = 3,
    Point  hull_impact = Point(0,0,0));

    virtual double    InflictSystemDamage(double damage, Shot* shot, Point impact);

    virtual void      InflictNetDamage(double damage, Shot* shot=0);
    virtual void      InflictNetSystemDamage(System* system, double damage, std::uint8_t type);
    virtual void      SetNetSystemStatus(System* system, int status, int power, int reactor, double avail);
    virtual void      SetIntegrity(float n)      { integrity = n;        }

    virtual void      Destroy();
    virtual int       ShieldStrength()  const;
    virtual int       HullStrength()    const;
    virtual int       HitBy(Shot* shot, Point& impact);
    virtual int       CollidesWith(Physical& o);

    // SENSORS AND VISIBILITY:
    virtual int       GetContactID()    const    { return contact_id;    }
    virtual int       GetIFF()          const    { return IFF_code;      }
    virtual void      SetIFF(int iff);
    virtual Color     MarkerColor()     const;
    static  Color     IFFColor(int iff);
    virtual void      DoEMCON();
    virtual double    PCS()             const;
    virtual double    ACS()             const;
    int               NumContacts()     const;   // actual sensor contacts
    List<Contact>&    ContactList();
    virtual int       GetSensorMode()   const;
    virtual void      SetSensorMode(int mode);
    virtual void      LaunchProbe();
    virtual Weapon*   GetProbeLauncher() const   { return probe;         }
    virtual Drone*    GetProbe()        const    { return sensor_drone;  }
    virtual void      SetProbe(Drone* d);
    virtual int       GetEMCON()        const    { return emcon;         }
    virtual void      SetEMCON(int e, bool from_net=false);
    virtual Contact*  FindContact(SimObject* s) const;
    virtual bool      IsHostileTo(const SimObject* o) const;

    // GENERAL ACCESSORS:
    const char*       Registry()        const    { return regnum;        }
    void              SetName(const char* ident) { strcpy_s(name, ident);  }
    const ShipDesign* Design()          const    { return design;        }
    const char*       Abbreviation()    const;
    const char*       DesignName()      const;
    const char*       DesignFileName()  const;
    static const char* ClassName(int c);
    static int        ClassForName(const char* name);
    const char*       ClassName()       const;
    CLASSIFICATION    Class()           const;
    bool              IsGroundUnit()    const;
    bool              IsStarship()      const;
    bool              IsDropship()      const;
    bool              IsStatic()        const;
    bool              IsRogue()         const;
    void              SetRogue(bool r=true);
    int               GetFriendlyFire() const    { return ff_count;      }
    void              SetFriendlyFire(int f);
    void              IncFriendlyFire(int f=1);
    double            Agility()         const    { return agility;       }
    std::uint32_t     MissionClock()    const;
    Graphic*          Cockpit()         const;
    void              ShowCockpit();
    void              HideCockpit();
    int               Value()           const;
    double            AIValue()         const;
    static int        Value(int type);

    const Skin*       GetSkin()         const    { return skin;          }
    void              UseSkin(const Skin* s)     { skin = s;             }
    void              ShowRep();
    void              HideRep();
    void              EnableShadows(bool enable);

    int               RespawnCount()    const    { return respawns;      }
    void              SetRespawnCount(int r)     { respawns = r;         }
    const Point&      RespawnLoc()      const    { return respawn_loc;   }
    void              SetRespawnLoc(const Point& rl)
    { respawn_loc = rl;     }

    double            WarpFactor()      const    { return warp_fov;      }
    void              SetWarp(double w)          { warp_fov = (float) w; }

    void              MatchOrientation(const Ship& s);

    // ORDERS AND NAVIGATION:
    void                    ExecEvalFrame(double seconds);
    void                    SetLaunchPoint(Instruction* pt);
    void                    AddNavPoint(Instruction* pt, Instruction* afterPoint=0);
    void                    DelNavPoint(Instruction* pt);
    void                    ClearFlightPlan();
    Instruction*            GetNextNavPoint();
    int                     GetNavIndex(const Instruction* n);
    double                  RangeToNavPoint(const Instruction* n);
    void                    SetNavptStatus(Instruction* n, int status);
    List<Instruction>&      GetFlightPlan();
    int                     FlightPlanLength();
    CombatUnit*             GetCombatUnit()   const { return combat_unit; }
    Element*                GetElement()      const { return element; }
    Ship*                   GetLeader()       const;
    int                     GetElementIndex() const;
    int                     GetOrigElementIndex() const;
    void                    SetElement(Element* e);

    Instruction*            GetRadioOrders()  const;
    void                    ClearRadioOrders();
    void                    HandleRadioMessage(RadioMessage* msg);
    bool                    IsAutoNavEngaged();
    void                    SetAutoNav(bool engage=true);
    void                    CommandMode();

    void                    ClearTrack();
    void                    UpdateTrack();
    int                     TrackLength()     const { return ntrack;   }
    Point                   TrackPoint(int i) const;

    // DAMAGE CONTROL AND ENGINEERING:
    List<System>&           RepairQueue()        { return repair_queue; }
    double                  RepairSpeed() const;
    int                     RepairTeams() const;
    void                    RepairSystem(System* sys);
    void                    IncreaseRepairPriority(int task_index);
    void                    DecreaseRepairPriority(int task_index);
    void                    ExecMaintFrame(double seconds);
    bool                    AutoRepair()    const { return auto_repair;    }
    void                    EnableRepair(bool e)  { auto_repair = e;       }
    bool                    MasterCaution() const { return master_caution; }
    void                    ClearCaution()       { master_caution = 0; }

    // SYSTEM ACCESSORS:
    List<System>&           Systems()            { return systems;       }
    List<WeaponGroup>&      Weapons()            { return weapons;       }
    List<Drive>&            Drives()             { return drives;        }
    List<Computer>&         Computers()          { return computers;     }
    List<FlightDeck>&       FlightDecks()        { return flight_decks;  }
    List<PowerSource>&      Reactors()           { return reactors;      }
    List<NavLight>&         NavLights()          { return navlights;     }
    Shield*                 GetShield()          { return shield;        }
    Solid*                  GetShieldRep()       { return (Solid*) shieldRep; }
    Sensor*                 GetSensor()          { return sensor;        }
    NavSystem*              GetNavSystem()       { return navsys;        }
    FlightComp*             GetFLCS()            { return flcs;          }
    Thruster*               GetThruster()        { return thruster;      }
    Hangar*                 GetHangar()          { return hangar;        }
    LandingGear*            GetGear()            { return gear;          }

    System*                 GetSystem(int sys_id);

    static int              GetControlModel()       { return control_model; }
    static void             SetControlModel(int n)  { control_model = n;    }
    static int              GetFlightModel()        { return flight_model;  }
    static void             SetFlightModel(int f)   { flight_model = f;     }
    static int              GetLandingModel()       { return landing_model; }
    static void             SetLandingModel(int f)  { landing_model = f;    }
    static double           GetFriendlyFireLevel()  { return friendly_fire_level; }
    static void             SetFriendlyFireLevel(double f)
    { friendly_fire_level = f;    }

protected:
    int               CheckShotIntersection(Shot* shot, Point& ipt, Point& hpt, Weapon** wep=0);
    WeaponGroup*      FindWeaponGroup(const char* name);

    char              regnum[16];
    ShipDesign*       design;
    ShipKiller*       killer;
    DetailSet         detail;
    int               detail_level;
    Sim*              sim;
    double            vlimit;
    double            agility;
    double            throttle;
    double            throttle_request;
    bool              augmenter;
    float             wep_mass;
    float             wep_resist;

    int               IFF_code;
    int               cmd_chain_index;
    int               ff_count;
    OP_MODE           flight_phase;

    SimObject*        target;
    System*           subtarget;
    Ship*             ward;
    int               check_fire;
    int               primary;
    int               secondary;

    const Skin*       skin;
    Solid*            cockpit;
    Drive*            main_drive;
    QuantumDrive*     quantum_drive;
    Farcaster*        farcaster;
    Shield*           shield;
    ShieldRep*        shieldRep;
    NavSystem*        navsys;
    FlightComp*       flcs;
    Sensor*           sensor;
    LandingGear*      gear;
    Thruster*         thruster;
    Weapon*           decoy;
    Weapon*           probe;
    Drone*            sensor_drone;
    Hangar*           hangar;
    List<Shot>        decoy_list;
    List<Shot>        threat_list;

    List<System>      systems;
    List<PowerSource> reactors;
    List<WeaponGroup> weapons;
    List<Drive>       drives;
    List<Computer>    computers;
    List<FlightDeck>  flight_decks;
    List<NavLight>    navlights;
    List<System>      repair_queue;

    CombatUnit*       combat_unit;
    Element*          element;
    int               orig_elem_index;
    Instruction*      radio_orders;
    Instruction*      launch_point;

    Vec3              chase_vec;
    Vec3              bridge_vec;

    const char*       director_info;
    std::uint8_t      ai_mode;
    std::uint8_t      command_ai_level;
    std::uint8_t      flcs_mode;
    bool              net_observer_mode;

    float             pcs;  // passive sensor cross section
    float             acs;  // active  sensor cross section
    std::uint8_t      emcon;
    std::uint8_t      old_emcon;
    bool              invulnerable;

    std::uint32_t     launch_time;
    std::uint32_t     friendly_fire_time;

    Ship*             carrier;
    FlightDeck*       dock;
    InboundSlot*      inbound;

    Director*         net_control;

    Point*            track;
    int               ntrack;
    std::uint32_t     track_time;

    float             helm_heading;
    float             helm_pitch;

    float             altitude_agl;
    float             g_force;

    float             warp_fov;

    float             transition_time;
    int               transition_type;
    Point             transition_loc;
    Point             respawn_loc;
    int               respawns;

    bool              master_caution;
    bool              auto_repair;
    std::uint32_t     last_repair_time;
    std::uint32_t     last_eval_time;
    std::uint32_t     last_beam_time;
    std::uint32_t     last_bolt_time;

    int               missile_id[4];
    std::uint8_t      missile_eta[4];
    bool              trigger[4];
    int*              loadout;

    int               contact_id;

    static int        control_model;
    static int        flight_model;
    static int        landing_model;
    static double     friendly_fire_level;
};