forked from pioneerspacesim/pioneer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShip.h
330 lines (256 loc) · 10.7 KB
/
Ship.h
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
// Copyright © 2008-2018 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
#ifndef _SHIP_H
#define _SHIP_H
#include "libs.h"
#include "Camera.h"
#include "DynamicBody.h"
#include "galaxy/SystemPath.h"
#include "NavLights.h"
#include "Planet.h"
#include "Sensors.h"
#include "ShipType.h"
#include "Space.h"
#include "scenegraph/SceneGraph.h"
#include "scenegraph/ModelSkin.h"
#include "LuaTable.h"
#include <list>
#include <unordered_map>
#include "Propulsion.h"
#include "FixedGuns.h"
class SpaceStation;
class HyperspaceCloud;
class AICommand;
class ShipController;
class CargoBody;
class Missile;
namespace Graphics { class Renderer; }
struct HeatGradientParameters_t {
matrix3x3f heatingMatrix;
vector3f heatingNormal; // normalised
float heatingAmount; // 0.0 to 1.0 used for `u` component of heatGradient texture
};
struct shipstats_t {
int used_capacity;
int used_cargo;
int free_capacity;
int static_mass; // cargo, equipment + hull
float hull_mass_left; // effectively hitpoints
float hyperspace_range;
float hyperspace_range_max;
float shield_mass;
float shield_mass_left;
float fuel_tank_mass_left;
};
struct HyperdriveSoundsTable {
std::string jump_sound;
std::string warmup_sound;
std::string abort_sound;
};
class Ship: public DynamicBody {
friend class ShipController; //only controllers need access to AITimeStep
friend class PlayerShipController;
public:
OBJDEF(Ship, DynamicBody, SHIP);
Ship(const ShipType::Id &shipId);
Ship() {} //default constructor used before Load
virtual ~Ship();
virtual void SetFrame(Frame *f) override;
void SetController(ShipController *c); //deletes existing
ShipController *GetController() const { return m_controller; }
virtual void SetDockedWith(SpaceStation *, int port);
/** Use GetDockedWith() to determine if docked */
SpaceStation *GetDockedWith() const { return m_dockedWith; }
int GetDockingPort() const { return m_dockedWithPort; }
bool IsDocked() const { return GetFlightState() == Ship::DOCKED; }
bool IsLanded() const { return GetFlightState() == Ship::LANDED; }
virtual void SetLandedOn(Planet *p, float latitude, float longitude);
virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override;
inline void ClearThrusterState() {
ClearAngThrusterState();
if (m_launchLockTimeout <= 0.0f) ClearLinThrusterState();
}
void UpdateLuaStats();
void UpdateEquipStats();
void UpdateFuelStats();
void UpdateGunsStats();
const shipstats_t &GetStats() const { return m_stats; }
void Explode();
virtual bool DoCrushDamage(float kgDamage); // can be overloaded in Player to add "crush" audio
void SetGunState(int idx, int state);
float GetGunTemperature(int idx) const { return GetFixedGuns()->GetGunTemperature(idx); }
void UpdateMass();
virtual bool SetWheelState(bool down); // returns success of state change, NOT state itself
void Blastoff();
bool Undock();
virtual void TimeStepUpdate(const float timeStep) override;
virtual void StaticUpdate(const float timeStep) override;
void TimeAccelAdjust(const float timeStep);
bool IsDecelerating() const { return m_decelerating; }
virtual void NotifyRemoved(const Body* const removedBody) override;
virtual bool OnCollision(Object *o, Uint32 flags, double relVel) override;
virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override;
enum FlightState { // <enum scope='Ship' name=ShipFlightState public>
FLYING, // open flight (includes autopilot)
DOCKING, // in docking animation
UNDOCKING, // in docking animation
DOCKED, // docked with station
LANDED, // rough landed (not docked)
JUMPING, // between space and hyperspace ;)
HYPERSPACE, // in hyperspace
};
FlightState GetFlightState() const { return m_flightState; }
void SetFlightState(FlightState s);
float GetWheelState() const { return m_wheelState; }
int GetWheelTransition() const { return m_wheelTransition; }
bool SpawnCargo(CargoBody * c_body) const;
LuaRef GetEquipSet() const { return m_equipSet; }
virtual bool IsInSpace() const override { return (m_flightState != HYPERSPACE); }
void SetHyperspaceDest(const SystemPath &dest) { m_hyperspace.dest = dest; }
const SystemPath &GetHyperspaceDest() const { return m_hyperspace.dest; }
double GetHyperspaceDuration() const { return m_hyperspace.duration; }
double GetECMRechargeRemain() const { return m_ecmRecharge; }
enum HyperjumpStatus { // <enum scope='Ship' name=ShipJumpStatus prefix=HYPERJUMP_ public>
HYPERJUMP_OK,
HYPERJUMP_CURRENT_SYSTEM,
HYPERJUMP_NO_DRIVE,
HYPERJUMP_INITIATED,
HYPERJUMP_DRIVE_ACTIVE,
HYPERJUMP_OUT_OF_RANGE,
HYPERJUMP_INSUFFICIENT_FUEL,
HYPERJUMP_SAFETY_LOCKOUT
};
Ship::HyperjumpStatus CheckHyperjumpCapability() const;
virtual Ship::HyperjumpStatus InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks);
virtual void AbortHyperjump();
float GetHyperspaceCountdown() const { return m_hyperspace.countdown; }
bool IsHyperspaceActive() const { return (m_hyperspace.countdown > 0.0); }
// 0 to 1.0 is alive, > 1.0 = death
double GetHullTemperature() const;
// Calculate temperature we would have with wheels down
double ExtrapolateHullTemperature() const;
enum ECMResult {
ECM_NOT_INSTALLED,
ECM_ACTIVATED,
ECM_RECHARGING,
};
ECMResult UseECM();
virtual Missile * SpawnMissile(ShipType::Id missile_type, int power=-1);
enum AlertState { // <enum scope='Ship' name=ShipAlertStatus prefix=ALERT_ public>
ALERT_NONE,
ALERT_SHIP_NEARBY,
ALERT_SHIP_FIRING,
};
AlertState GetAlertState() { return m_alertState; }
void AIClearInstructions(); // Note: defined in Ship-AI.cpp
bool AIIsActive() { return m_curAICmd ? true : false; }
void AIGetStatusText(char *str); // Note: defined in Ship-AI.cpp
void AIKamikaze(Body *target); // Note: defined in Ship-AI.cpp
void AIKill(Ship *target); // Note: defined in Ship-AI.cpp
//void AIJourney(SystemBodyPath &dest);
void AIDock(SpaceStation *target); // Note: defined in Ship-AI.cpp
void AIFlyTo(Body *target); // Note: defined in Ship-AI.cpp
void AIOrbit(Body *target, double alt); // Note: defined in Ship-AI.cpp
void AIHoldPosition(); // Note: defined in Ship-AI.cpp
void AIBodyDeleted(const Body* const body) {}; // Note: defined in Ship-AI.cpp // todo: signals
const AICommand *GetAICommand() const { return m_curAICmd; }
virtual void PostLoadFixup(Space *space) override;
const ShipType *GetShipType() const { return m_type; }
virtual void SetShipType(const ShipType::Id &shipId);
const SceneGraph::ModelSkin &GetSkin() const { return m_skin; }
void SetSkin(const SceneGraph::ModelSkin &skin);
void SetPattern(unsigned int num);
void SetLabel(const std::string &label) override;
void SetShipName(const std::string &shipName);
float GetPercentShields() const;
float GetPercentHull() const;
void SetPercentHull(float);
void EnterSystem();
HyperspaceCloud *GetHyperspaceCloud() const { return m_hyperspaceCloud; }
sigc::signal<void> onDock; // JJ: check what these are for
sigc::signal<void> onUndock;
sigc::signal<void> onLanded;
// mutable because asking to know when state changes is not the same as
// actually changing state
mutable sigc::signal<void> onFlavourChanged;
bool IsInvulnerable() const { return m_invulnerable; }
void SetInvulnerable(bool b) { m_invulnerable = b; }
Sensors *GetSensors() const { return m_sensors.get(); }
Uint8 GetRelations(Body *other) const; //0=hostile, 50=neutral, 100=ally
void SetRelations(Body *other, Uint8 percent);
double GetLandingPosOffset() const { return m_landingMinOffset; }
protected:
virtual void SaveToJson(Json::Value &jsonObj, Space *space) override;
virtual void LoadFromJson(const Json::Value &jsonObj, Space *space) override;
bool AITimeStep(float timeStep); // Called by controller. Returns true if complete
virtual void SetAlertState(AlertState as);
virtual void OnEnterHyperspace();
virtual void OnEnterSystem();
SpaceStation *m_dockedWith;
int m_dockedWithPort;
float m_ecmRecharge;
ShipController *m_controller;
struct HyperspacingOut {
SystemPath dest;
// > 0 means active
float countdown;
bool now;
double duration;
LuaRef checks; // A Lua function to check all the conditions before the jump
HyperdriveSoundsTable sounds;
} m_hyperspace;
LuaRef m_equipSet;
private:
float GetECMRechargeTime();
void DoThrusterSounds() const;
void Init();
void TestLanded();
void UpdateAlertState();
void UpdateFuel(float timeStep);
void SetShipId(const ShipType::Id &shipId);
void EnterHyperspace();
void InitMaterials();
void InitEquipSet();
bool m_invulnerable;
static const float DEFAULT_SHIELD_COOLDOWN_TIME;
float m_shieldCooldown;
shipstats_t m_stats;
const ShipType *m_type;
SceneGraph::ModelSkin m_skin;
FlightState m_flightState;
bool m_testLanded;
float m_launchLockTimeout;
float m_wheelState;
int m_wheelTransition;
AlertState m_alertState;
double m_lastAlertUpdate;
double m_lastFiringAlert;
bool m_shipNear;
bool m_shipFiring;
Space::BodyNearList m_nearbyBodies;
HyperspaceCloud *m_hyperspaceCloud;
AICommand *m_curAICmd;
double m_landingMinOffset; // offset from the centre of the ship used during docking
int m_dockedWithIndex; // deserialisation
SceneGraph::Animation *m_landingGearAnimation;
std::unique_ptr<NavLights> m_navLights;
static HeatGradientParameters_t s_heatGradientParams;
std::unique_ptr<Sensors> m_sensors;
std::unordered_map<Body*, Uint8> m_relationsMap;
std::string m_shipName;
public:
void ClearAngThrusterState() { GetPropulsion()->ClearAngThrusterState(); }
void ClearLinThrusterState() { GetPropulsion()->ClearLinThrusterState(); }
double GetAccelFwd() { return GetPropulsion()->GetAccelFwd(); }
void SetAngThrusterState(const vector3d &levels) { GetPropulsion()->SetAngThrusterState(levels); }
double GetFuel() const { return GetPropulsion()->GetFuel(); }
double GetAccel(Thruster thruster) const { return GetPropulsion()->GetAccel(thruster); }
void SetFuel(const double f) { GetPropulsion()->SetFuel(f); }
void SetFuelReserve(const double f) { GetPropulsion()->SetFuelReserve(f); }
bool AIMatchVel(const vector3d &vel) { return GetPropulsion()->AIMatchVel(vel); }
double AIFaceDirection(const vector3d &dir, double av=0) { return GetPropulsion()->AIFaceDirection(dir, av); }
void AIMatchAngVelObjSpace(const vector3d &angvel) { return GetPropulsion()->AIMatchAngVelObjSpace(angvel); }
void SetThrusterState(int axis, double level) { return GetPropulsion()->SetThrusterState(axis, level); }
void AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double softness) { return GetPropulsion()->AIModelCoordsMatchAngVel(desiredAngVel, softness); }
};
#endif /* _SHIP_H */