File: UnitDef.h

package info (click to toggle)
spring 105.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,860 kB
  • sloc: cpp: 467,785; ansic: 302,607; python: 12,925; java: 12,201; awk: 5,889; sh: 2,371; xml: 655; perl: 405; php: 276; objc: 194; makefile: 75; sed: 2
file content (388 lines) | stat: -rw-r--r-- 12,186 bytes parent folder | download | duplicates (3)
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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef UNITDEF_H
#define UNITDEF_H

#include <vector>

#include "Rendering/Icon.h"
#include "Sim/Misc/GlobalConstants.h"
#include "Sim/Misc/GuiSoundSet.h"
#include "Sim/Objects/SolidObject.h"
#include "Sim/Objects/SolidObjectDef.h"
#include "System/float3.h"
#include "System/UnorderedMap.hpp"

#define MAX_UNITDEF_EXPGEN_IDS 32


struct Command;
struct WeaponDef;
struct MoveDef;
struct UnitDefImage;
class LuaTable;


struct UnitDefWeapon {
	UnitDefWeapon() = default;
	UnitDefWeapon(const WeaponDef* weaponDef);
	UnitDefWeapon(const WeaponDef* weaponDef, const LuaTable& weaponTable);
	UnitDefWeapon(const UnitDefWeapon& udw) { *this = udw; }

	// unused
	// std::string name;

	const WeaponDef* def = nullptr;

	int slavedTo = 0;

	float maxMainDirAngleDif = -1.0f;

	unsigned int badTargetCat = 0;
	unsigned int onlyTargetCat = 0;

	float3 mainDir = FwdVector;
};


struct UnitDef: public SolidObjectDef
{
public:
	UnitDef(const LuaTable& udTable, const std::string& unitName, int id);
	UnitDef();

	void SetNoCost(bool noCost);

	bool IsTransportUnit()     const { return (transportCapacity > 0 && transportMass > 0.0f); }
	bool IsImmobileUnit()      const { return (pathType == -1U && !canfly && speed <= 0.0f); }
	bool IsBuildingUnit()      const { return (IsImmobileUnit() && !yardmap.empty()); }
	bool IsBuilderUnit()       const { return (builder && buildSpeed > 0.0f && buildDistance > 0.0f); }
	bool IsMobileBuilderUnit() const { return (IsBuilderUnit() && !IsImmobileUnit()); }
	bool IsStaticBuilderUnit() const { return (IsBuilderUnit() &&  IsImmobileUnit()); }
	bool IsFactoryUnit()       const { return (IsBuilderUnit() &&  IsBuildingUnit()); }
	bool IsExtractorUnit()     const { return (extractsMetal > 0.0f && extractRange > 0.0f); }
	bool IsGroundUnit()        const { return (pathType != -1U && !canfly); }
	bool IsAirUnit()           const { return (pathType == -1U &&  canfly); }
	bool IsStrafingAirUnit()   const { return (IsAirUnit() && !(IsBuilderUnit() || IsTransportUnit() || hoverAttack)); }
	bool IsHoveringAirUnit()   const { return (IsAirUnit() &&  (IsBuilderUnit() || IsTransportUnit() || hoverAttack)); }
	bool IsFighterAirUnit()    const { return (IsStrafingAirUnit() && HasWeapon(0) && !HasBomberWeapon(0)); }
	bool IsBomberAirUnit()     const { return (IsStrafingAirUnit() && HasWeapon(0) &&  HasBomberWeapon(0)); }

	bool DontLand() const { return (dlHoverFactor >= 0.0f); }
	bool RequireMoveDef() const { return (canmove && speed > 0.0f && !canfly); }
	bool CanChangeFireState() const { return (canFireControl && (canKamikaze || HasWeapons() || IsFactoryUnit())); }

	bool HasWeapons() const { return (HasWeapon(0)); }
	bool HasWeapon(unsigned int idx) const { return (weapons[idx].def != nullptr); }
	bool HasBomberWeapon(unsigned int idx) const;

	bool CanAttack() const { return (canAttack && (canKamikaze || HasWeapons() || IsFactoryUnit())); }
	bool CanDamage() const { return (canKamikaze || (canAttack && HasWeapons())); }

	unsigned int NumWeapons() const {
		unsigned int n = 0;

		while (n < weapons.size() && HasWeapon(n)) {
			n++;
		}

		return n;
	}

	const UnitDefWeapon& GetWeapon(unsigned int idx) const { return weapons[idx]; }
	const YardMapStatus* GetYardMapPtr() const { return (yardmap.data()); }


	void AddModelExpGenID(unsigned int egID) { modelExplGenIDs[1 + modelExplGenIDs[0]] = egID; modelExplGenIDs[0] += (egID != -1u); }
	void AddPieceExpGenID(unsigned int egID) { pieceExplGenIDs[1 + pieceExplGenIDs[0]] = egID; pieceExplGenIDs[0] += (egID != -1u); }
	void AddCrashExpGenID(unsigned int egID) { crashExplGenIDs[1 + crashExplGenIDs[0]] = egID; crashExplGenIDs[0] += (egID != -1u); }

	// UnitScript::EmitSFX can pass in any index, unlike PieceProjectile and AAirMoveType code
	unsigned int GetModelExpGenID(unsigned int idx) const { return modelExplGenIDs[1 + (idx % MAX_UNITDEF_EXPGEN_IDS)]; }
	unsigned int GetPieceExpGenID(unsigned int idx) const { return pieceExplGenIDs[1 + (idx                         )]; }
	unsigned int GetCrashExpGenID(unsigned int idx) const { return crashExplGenIDs[1 + (idx                         )]; }

	unsigned int GetModelExpGenCount() const { return modelExplGenIDs[0]; }
	unsigned int GetPieceExpGenCount() const { return pieceExplGenIDs[0]; }
	unsigned int GetCrashExpGenCount() const { return crashExplGenIDs[0]; }

public:
	int cobID;              ///< associated with the COB \<GET COB_ID unitID\> call

	const UnitDef* decoyDef;

	float metalUpkeep;
	float energyUpkeep;
	float metalMake;		///< metal will always be created
	float makesMetal;		///< metal will be created when unit is on and enough energy can be drained
	float energyMake;
	float buildTime;
	float extractsMetal;
	float extractRange;
	float windGenerator;
	float tidalGenerator;
	float metalStorage;
	float energyStorage;
	float harvestMetalStorage;
	float harvestEnergyStorage;

	float autoHeal;     ///< amount autohealed
	float idleAutoHeal; ///< amount autohealed only during idling
	int idleTime;       ///< time a unit needs to idle before its considered idling

	float power;
	unsigned int category;

	float speed;        ///< maximum forward speed the unit can attain (elmos/sec)
	float rSpeed;       ///< maximum reverse speed the unit can attain (elmos/sec)
	float turnRate;
	bool turnInPlace;

	///< for units with turnInPlace=false, defines the
	///< minimum speed to slow down to while turning
	float turnInPlaceSpeedLimit;
	///< for units with turnInPlace=true, defines the
	///< maximum angle of a turn that can be entered
	///< without slowing down
	float turnInPlaceAngleLimit;

	bool collide;

	float losHeight;
	float radarHeight;

	float losRadius;
	float airLosRadius;
	int radarRadius;
	int sonarRadius;
	int jammerRadius;
	int sonarJamRadius;
	int seismicRadius;
	float seismicSignature;
	bool stealth;
	bool sonarStealth;

	bool  buildRange3D;
	float buildDistance;
	float buildSpeed;
	float reclaimSpeed;
	float repairSpeed;
	float maxRepairSpeed;
	float resurrectSpeed;
	float captureSpeed;
	float terraformSpeed;

	bool canSubmerge;
	bool canfly;
	bool floatOnWater;
	bool pushResistant;
	bool strafeToAttack;  /// should the unit move sideways when it can't shoot?
	bool stopToAttack;
	float minCollisionSpeed;
	float slideTolerance;
	float maxHeightDif;   /// maximum terraform height this building allows
	float waterline;
	float minWaterDepth;
	float maxWaterDepth;

	unsigned int pathType;

	float armoredMultiple;
	int armorType;

	/**
	 * 0: no flanking bonus
	 * 1: global coords, mobile
	 * 2: unit coords, mobile
	 * 3: unit coords, locked
	 */
	int flankingBonusMode;
	float3 flankingBonusDir; ///< units takes less damage when attacked from this dir (encourage flanking fire)
	float  flankingBonusMax; ///< damage factor for the least protected direction
	float  flankingBonusMin; ///< damage factor for the most protected direction
	float  flankingBonusMobilityAdd; ///< how much the ability of the flanking bonus direction to move builds up each frame

	std::string humanName;
	std::string decoyName;
	std::string scriptName;     ///< the name of the unit's script, e.g. "armjeth.cob"
	std::string tooltip;
	std::string wreckName;
	std::string categoryString;
	std::string buildPicName;

	std::array<UnitDefWeapon, MAX_WEAPONS_PER_UNIT> weapons;

	///< The unrotated yardmap for buildings
	///< (only non-mobile ground units can have these)
	std::vector<YardMapStatus> yardmap;

	///< buildingMask used to disallow construction on certain map squares
	std::uint16_t buildingMask;

	std::array<char[64], MAX_UNITDEF_EXPGEN_IDS> modelCEGTags;
	std::array<char[64], MAX_UNITDEF_EXPGEN_IDS> pieceCEGTags;
	std::array<char[64], MAX_UNITDEF_EXPGEN_IDS> crashCEGTags;

	// *ExplGenIDs[0] stores the number of valid CEG's (TODO: privatize)
	// valid CEG id's are all in front s.t. they can be randomly sampled
	std::array<unsigned int, 1 + MAX_UNITDEF_EXPGEN_IDS> modelExplGenIDs;
	std::array<unsigned int, 1 + MAX_UNITDEF_EXPGEN_IDS> pieceExplGenIDs;
	std::array<unsigned int, 1 + MAX_UNITDEF_EXPGEN_IDS> crashExplGenIDs;

	spring::unordered_map<int, std::string> buildOptions;

	const WeaponDef* shieldWeaponDef;
	const WeaponDef* stockpileWeaponDef;
	float maxWeaponRange;
	float maxCoverage;

	const WeaponDef* deathExpWeaponDef;
	const WeaponDef* selfdExpWeaponDef;

	mutable UnitDefImage* buildPic;
	mutable icon::CIcon iconType;

	int selfDCountdown;

	bool builder;
	bool activateWhenBuilt;
	bool onoffable;
	bool fullHealthFactory;
	bool factoryHeadingTakeoff;

	bool capturable;
	bool repairable;

	// order-capabilities for CommandAI
	bool canmove;
	bool canAttack;
	bool canFight;
	bool canPatrol;
	bool canGuard;
	bool canRepeat;
	bool canResurrect;
	bool canCapture;
	bool canCloak;
	bool canSelfD;
	bool canKamikaze;

	bool canRestore;
	bool canRepair;
	bool canReclaim;
	bool canAssist;

	bool canBeAssisted;
	bool canSelfRepair;

	bool canFireControl;
	bool canManualFire;

	int fireState;
	int moveState;

	//aircraft stuff
	float wingDrag;
	float wingAngle;
	float frontToSpeed;
	float speedToFront;
	float myGravity;

	float maxBank;
	float maxPitch;
	float turnRadius;
	float wantedHeight;
	float verticalSpeed;

	bool useSmoothMesh;
	bool hoverAttack;
	bool airStrafe;
	float dlHoverFactor; ///< < 0 means it can land, >= 0 indicates how much the unit will move during hovering on the spot
	bool bankingAllowed;

	float maxAcc;
	float maxDec;
	float maxAileron;
	float maxElevator;
	float maxRudder;
	float crashDrag;

	float loadingRadius;							///< for transports
	float unloadSpread;
	int transportCapacity;
	int transportSize;
	int minTransportSize;
	bool isFirePlatform;							///< should the carried units still be able to shoot?
	float transportMass;
	float minTransportMass;
	bool holdSteady;
	bool releaseHeld;
	bool cantBeTransported;                         /// defaults to true for immobile units, false for all other unit-types
	bool transportByEnemy;
	int transportUnloadMethod;						///< 0 - land unload, 1 - flyover drop, 2 - land flood
	float fallSpeed;								///< dictates fall speed of all transported units
	float unitFallSpeed;							///< sets the transported units fbi, overrides fallSpeed

	bool startCloaked;								///< if the units want to start out cloaked
	float cloakCost;								///< energy cost per second to stay cloaked when stationary
	float cloakCostMoving;							///< energy cost per second when moving
	float decloakDistance;							///< if enemy unit come within this range decloaking is forced
	bool decloakSpherical;							///< use a spherical test instead of a cylindrical test?
	bool decloakOnFire;								///< should the unit decloak upon firing

	float kamikazeDist;
	bool kamikazeUseLOS;

	bool targfac;
	bool needGeo;
	bool isFeature;
	bool hideDamage;
	bool showPlayerName;

	int highTrajectoryType;							///< 0 (default) = only low, 1 = only high, 2 = choose

	unsigned int noChaseCategory;

	struct SoundStruct {
		GuiSoundSet select;
		GuiSoundSet ok;
		GuiSoundSet arrived;
		GuiSoundSet build;
		GuiSoundSet repair;
		GuiSoundSet working;
		GuiSoundSet underattack;
		GuiSoundSet cant;
		GuiSoundSet activate;
		GuiSoundSet deactivate;
	};
	SoundStruct sounds;

	bool canDropFlare;
	float flareReloadTime;
	float flareEfficiency;
	float flareDelay;
	float3 flareDropVector;
	int flareTime;
	int flareSalvoSize;
	int flareSalvoDelay;

	bool canLoopbackAttack;                         ///< only matters for fighter aircraft
	bool levelGround;                               ///< only matters for buildings

	bool showNanoFrame;								///< Does the nano frame animation get shown during construction?
	bool showNanoSpray;								///< Does nano spray get shown at all?
	float3 nanoColor;								///< If nano spray is displayed what color is it?

	int maxThisUnit;                                ///< number of units of this type allowed simultaneously in the game

private:
	void ParseWeaponsTable(const LuaTable& weaponsTable);
	void CreateYardMap(std::string&& yardMapStr);

	float realMetalCost;
	float realEnergyCost;
	float realMetalUpkeep;
	float realEnergyUpkeep;
	float realBuildTime;
};

#endif /* UNITDEF_H */