1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef UNITDEF_H
4 #define UNITDEF_H
5 
6 #include <vector>
7 
8 #include "Rendering/Icon.h"
9 #include "Sim/Misc/GuiSoundSet.h"
10 #include "Sim/Objects/SolidObject.h"
11 #include "Sim/Objects/SolidObjectDef.h"
12 #include "System/float3.h"
13 
14 
15 struct Command;
16 struct WeaponDef;
17 struct MoveDef;
18 struct UnitDefImage;
19 class LuaTable;
20 
21 
22 struct UnitDefWeapon {
23 	UnitDefWeapon();
24 	UnitDefWeapon(const WeaponDef* weaponDef);
25 	UnitDefWeapon(const WeaponDef* weaponDef, const LuaTable& weaponTable);
UnitDefWeaponUnitDefWeapon26 	UnitDefWeapon(const UnitDefWeapon& udw) { *this = udw; }
27 
28 	// unused
29 	std::string name;
30 
31 	const WeaponDef* def;
32 	int slavedTo;
33 
34 	float fuelUsage; /// How many seconds of fuel it costs for the owning unit to fire this weapon
35 	float maxMainDirAngleDif;
36 
37 	unsigned int badTargetCat;
38 	unsigned int onlyTargetCat;
39 
40 	float3 mainDir;
41 };
42 
43 
44 struct UnitDef: public SolidObjectDef
45 {
46 public:
47 	UnitDef(const LuaTable& udTable, const std::string& unitName, int id);
48 	UnitDef();
49 	~UnitDef();
50 
DontLandUnitDef51 	bool DontLand() const { return dlHoverFactor >= 0.0f; }
52 	void SetNoCost(bool noCost);
53 	bool CheckTerrainConstraints(const MoveDef* moveDef, float rawHeight, float* clampedHeight = NULL) const;
54 
IsTransportUnitUnitDef55 	bool IsTransportUnit()     const { return (transportCapacity > 0 && transportMass > 0.0f); }
IsImmobileUnitUnitDef56 	bool IsImmobileUnit()      const { return (pathType == -1U && !canfly && speed <= 0.0f); }
IsBuildingUnitUnitDef57 	bool IsBuildingUnit()      const { return (IsImmobileUnit() && !yardmap.empty()); }
IsBuilderUnitUnitDef58 	bool IsBuilderUnit()       const { return (builder && buildSpeed > 0.0f && buildDistance > 0.0f); }
IsMobileBuilderUnitUnitDef59 	bool IsMobileBuilderUnit() const { return (IsBuilderUnit() && !IsImmobileUnit()); }
IsStaticBuilderUnitUnitDef60 	bool IsStaticBuilderUnit() const { return (IsBuilderUnit() &&  IsImmobileUnit()); }
IsFactoryUnitUnitDef61 	bool IsFactoryUnit()       const { return (IsBuilderUnit() &&  IsBuildingUnit()); }
IsExtractorUnitUnitDef62 	bool IsExtractorUnit()     const { return (extractsMetal > 0.0f && extractRange > 0.0f); }
IsGroundUnitUnitDef63 	bool IsGroundUnit()        const { return (pathType != -1U && !canfly); }
IsAirUnitUnitDef64 	bool IsAirUnit()           const { return (pathType == -1U &&  canfly); }
IsStrafingAirUnitUnitDef65 	bool IsStrafingAirUnit()   const { return (IsAirUnit() && !(IsBuilderUnit() || IsTransportUnit() || hoverAttack)); }
IsHoveringAirUnitUnitDef66 	bool IsHoveringAirUnit()   const { return (IsAirUnit() &&  (IsBuilderUnit() || IsTransportUnit() || hoverAttack)); }
IsFighterAirUnitUnitDef67 	bool IsFighterAirUnit()    const { return (IsStrafingAirUnit() && !weapons.empty() && !HasBomberWeapon()); }
IsBomberAirUnitUnitDef68 	bool IsBomberAirUnit()     const { return (IsStrafingAirUnit() && !weapons.empty() &&  HasBomberWeapon()); }
69 
RequireMoveDefUnitDef70 	bool RequireMoveDef() const { return (canmove && speed > 0.0f && !canfly); }
71 	bool HasBomberWeapon() const;
GetYardMapUnitDef72 	const std::vector<YardMapStatus>& GetYardMap() const { return yardmap; }
73 
SetModelExplosionGeneratorIDUnitDef74 	void SetModelExplosionGeneratorID(unsigned int idx, unsigned int egID) { modelExplGenIDs[idx] = egID; }
SetPieceExplosionGeneratorIDUnitDef75 	void SetPieceExplosionGeneratorID(unsigned int idx, unsigned int egID) { pieceExplGenIDs[idx] = egID; }
76 
GetModelExplosionGeneratorIDUnitDef77 	unsigned int GetModelExplosionGeneratorID(unsigned int idx) const {
78 		if (modelExplGenIDs.empty())
79 			return -1u;
80 		return (modelExplGenIDs[idx % modelExplGenIDs.size()]);
81 	}
GetPieceExplosionGeneratorIDUnitDef82 	unsigned int GetPieceExplosionGeneratorID(unsigned int idx) const {
83 		if (pieceExplGenIDs.empty())
84 			return -1u;
85 		return (pieceExplGenIDs[idx % pieceExplGenIDs.size()]);
86 	}
87 
88 public:
89 	int cobID;              ///< associated with the COB \<GET COB_ID unitID\> call
90 
91 	const UnitDef* decoyDef;
92 
93 	int techLevel;
94 
95 	float metalUpkeep;
96 	float energyUpkeep;
97 	float metalMake;		///< metal will always be created
98 	float makesMetal;		///< metal will be created when unit is on and enough energy can be drained
99 	float energyMake;
100 	float buildTime;
101 	float extractsMetal;
102 	float extractRange;
103 	float windGenerator;
104 	float tidalGenerator;
105 	float metalStorage;
106 	float energyStorage;
107 	float harvestStorage;
108 
109 	float autoHeal;     ///< amount autohealed
110 	float idleAutoHeal; ///< amount autohealed only during idling
111 	int idleTime;       ///< time a unit needs to idle before its considered idling
112 
113 	float power;
114 	unsigned int category;
115 
116 	float speed;        ///< maximum forward speed the unit can attain (elmos/sec)
117 	float rSpeed;       ///< maximum reverse speed the unit can attain (elmos/sec)
118 	float turnRate;
119 	bool turnInPlace;
120 
121 	///< for units with turnInPlace=false, defines the
122 	///< minimum speed to slow down to while turning
123 	float turnInPlaceSpeedLimit;
124 	///< for units with turnInPlace=true, defines the
125 	///< maximum angle of a turn that can be entered
126 	///< without slowing down
127 	float turnInPlaceAngleLimit;
128 
129 	bool collide;
130 
131 	float losHeight;
132 	float radarHeight;
133 
134 	float losRadius;
135 	float airLosRadius;
136 	int radarRadius;
137 	int sonarRadius;
138 	int jammerRadius;
139 	int sonarJamRadius;
140 	int seismicRadius;
141 	float seismicSignature;
142 	bool stealth;
143 	bool sonarStealth;
144 
145 	bool  buildRange3D;
146 	float buildDistance;
147 	float buildSpeed;
148 	float reclaimSpeed;
149 	float repairSpeed;
150 	float maxRepairSpeed;
151 	float resurrectSpeed;
152 	float captureSpeed;
153 	float terraformSpeed;
154 
155 	bool canSubmerge;
156 	bool canfly;
157 	bool floatOnWater;
158 	bool pushResistant;
159 	bool strafeToAttack;  /// should the unit move sideways when it can't shoot?
160 	float minCollisionSpeed;
161 	float slideTolerance;
162 	float maxHeightDif;   /// maximum terraform height this building allows
163 	float waterline;
164 	float minWaterDepth;
165 	float maxWaterDepth;
166 
167 	unsigned int pathType;
168 
169 	float armoredMultiple;
170 	int armorType;
171 
172 	/**
173 	 * 0: no flanking bonus
174 	 * 1: global coords, mobile
175 	 * 2: unit coords, mobile
176 	 * 3: unit coords, locked
177 	 */
178 	int flankingBonusMode;
179 	float3 flankingBonusDir; ///< units takes less damage when attacked from this dir (encourage flanking fire)
180 	float  flankingBonusMax; ///< damage factor for the least protected direction
181 	float  flankingBonusMin; ///< damage factor for the most protected direction
182 	float  flankingBonusMobilityAdd; ///< how much the ability of the flanking bonus direction to move builds up each frame
183 
184 	std::string humanName;
185 	std::string decoyName;
186 	std::string scriptName;     ///< the name of the unit's script, e.g. "armjeth.cob"
187 	std::string tooltip;
188 	std::string wreckName;
189 	std::string categoryString;
190 	std::string buildPicName;
191 
192 	std::vector<UnitDefWeapon> weapons;
193 
194 	///< The unrotated yardmap for buildings
195 	///< (only non-mobile ground units can have these)
196 	std::vector<YardMapStatus> yardmap;
197 
198 	std::vector<std::string> modelCEGTags;
199 	std::vector<std::string> pieceCEGTags;
200 
201 	// TODO: privatize
202 	std::vector<unsigned int> modelExplGenIDs;
203 	std::vector<unsigned int> pieceExplGenIDs;
204 
205 	std::map<int, std::string> buildOptions;
206 
207 	const WeaponDef* shieldWeaponDef;
208 	const WeaponDef* stockpileWeaponDef;
209 	float maxWeaponRange;
210 	float maxCoverage;
211 
212 	const WeaponDef* deathExpWeaponDef;
213 	const WeaponDef* selfdExpWeaponDef;
214 
215 	mutable UnitDefImage* buildPic;
216 	mutable icon::CIcon iconType;
217 
218 	int selfDCountdown;
219 
220 	bool builder;
221 	bool activateWhenBuilt;
222 	bool onoffable;
223 	bool fullHealthFactory;
224 	bool factoryHeadingTakeoff;
225 
226 	bool capturable;
227 	bool repairable;
228 
229 	// order-capabilities for CommandAI
230 	bool canmove;
231 	bool canAttack;
232 	bool canFight;
233 	bool canPatrol;
234 	bool canGuard;
235 	bool canRepeat;
236 	bool canResurrect;
237 	bool canCapture;
238 	bool canCloak;
239 	bool canSelfD;
240 	bool canKamikaze;
241 
242 	bool canRestore;
243 	bool canRepair;
244 	bool canReclaim;
245 	bool canAssist;
246 
247 	bool canBeAssisted;
248 	bool canSelfRepair;
249 
250 	bool canFireControl;
251 	bool canManualFire;
252 
253 	int fireState;
254 	int moveState;
255 
256 	//aircraft stuff
257 	float wingDrag;
258 	float wingAngle;
259 	float frontToSpeed;
260 	float speedToFront;
261 	float myGravity;
262 
263 	float maxBank;
264 	float maxPitch;
265 	float turnRadius;
266 	float wantedHeight;
267 	float verticalSpeed;
268 
269 	bool useSmoothMesh;
270 	bool hoverAttack;
271 	bool airStrafe;
272 	float dlHoverFactor; ///< < 0 means it can land, >= 0 indicates how much the unit will move during hovering on the spot
273 	bool bankingAllowed;
274 
275 	float maxAcc;
276 	float maxDec;
277 	float maxAileron;
278 	float maxElevator;
279 	float maxRudder;
280 	float crashDrag;
281 
282 	float loadingRadius;							///< for transports
283 	float unloadSpread;
284 	int transportCapacity;
285 	int transportSize;
286 	int minTransportSize;
287 	bool isAirBase;
288 	bool isFirePlatform;							///< should the carried units still be able to shoot?
289 	float transportMass;
290 	float minTransportMass;
291 	bool holdSteady;
292 	bool releaseHeld;
293 	bool cantBeTransported;                         /// defaults to true for immobile units, false for all other unit-types
294 	bool transportByEnemy;
295 	int transportUnloadMethod;						///< 0 - land unload, 1 - flyover drop, 2 - land flood
296 	float fallSpeed;								///< dictates fall speed of all transported units
297 	float unitFallSpeed;							///< sets the transported units fbi, overrides fallSpeed
298 
299 	bool startCloaked;								///< if the units want to start out cloaked
300 	float cloakCost;								///< energy cost per second to stay cloaked when stationary
301 	float cloakCostMoving;							///< energy cost per second when moving
302 	float decloakDistance;							///< if enemy unit come within this range decloaking is forced
303 	bool decloakSpherical;							///< use a spherical test instead of a cylindrical test?
304 	bool decloakOnFire;								///< should the unit decloak upon firing
305 	int cloakTimeout;								///< minimum time between decloak and subsequent cloak
306 
307 	float kamikazeDist;
308 	bool kamikazeUseLOS;
309 
310 	bool targfac;
311 	bool needGeo;
312 	bool isFeature;
313 	bool hideDamage;
314 	bool showPlayerName;
315 
316 	int highTrajectoryType;							///< 0 (default) = only low, 1 = only high, 2 = choose
317 
318 	unsigned int noChaseCategory;
319 
320 	struct SoundStruct {
321 		GuiSoundSet select;
322 		GuiSoundSet ok;
323 		GuiSoundSet arrived;
324 		GuiSoundSet build;
325 		GuiSoundSet repair;
326 		GuiSoundSet working;
327 		GuiSoundSet underattack;
328 		GuiSoundSet cant;
329 		GuiSoundSet activate;
330 		GuiSoundSet deactivate;
331 	};
332 	SoundStruct sounds;
333 
334 	bool canDropFlare;
335 	float flareReloadTime;
336 	float flareEfficiency;
337 	float flareDelay;
338 	float3 flareDropVector;
339 	int flareTime;
340 	int flareSalvoSize;
341 	int flareSalvoDelay;
342 
343 	bool canLoopbackAttack;                         ///< only matters for fighter aircraft
344 	bool levelGround;                               ///< only matters for buildings
345 
346 	bool showNanoFrame;								///< Does the nano frame animation get shown during construction?
347 	bool showNanoSpray;								///< Does nano spray get shown at all?
348 	float3 nanoColor;								///< If nano spray is displayed what color is it?
349 
350 	float maxFuel;									///< max flight time in seconds before the aircraft needs to return to a air repair bay to refuel
351 	float refuelTime;								///< time to fully refuel unit
352 	float minAirBasePower;							///< min build power for airbases that this aircraft can land on
353 
354 	int maxThisUnit;                                ///< number of units of this type allowed simultaneously in the game
355 
356 private:
357 	void ParseWeaponsTable(const LuaTable& weaponsTable);
358 	void CreateYardMap(std::string yardMapStr);
359 
360 	float realMetalCost;
361 	float realEnergyCost;
362 	float realMetalUpkeep;
363 	float realEnergyUpkeep;
364 	float realBuildTime;
365 };
366 
367 #endif /* UNITDEF_H */
368