File: Weapon.h

package info (click to toggle)
spring 98.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 41,928 kB
  • ctags: 60,665
  • sloc: cpp: 356,167; ansic: 39,434; python: 12,228; java: 12,203; awk: 5,856; sh: 1,719; xml: 997; perl: 405; php: 253; objc: 194; makefile: 72; sed: 2
file content (203 lines) | stat: -rw-r--r-- 8,181 bytes parent folder | download
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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef WEAPON_H
#define WEAPON_H

#include <map>

#include "System/Object.h"
#include "Sim/Misc/DamageArray.h"
#include "Sim/Projectiles/ProjectileParams.h"
#include "System/float3.h"

class CUnit;
class CWeaponProjectile;
struct WeaponDef;

enum TargetType {
	Target_None,
	Target_Unit,
	Target_Pos,
	Target_Intercept
};

class CWeapon : public CObject
{
	CR_DECLARE(CWeapon)
public:
	CWeapon(CUnit* owner, const WeaponDef* def);
	virtual ~CWeapon();
	virtual void Init();

	void SetWeaponNum(int);

	void DependentDied(CObject* o);


	bool CheckTargetAngleConstraint(const float3& worldTargetDir, const float3& worldWeaponDir) const;
	bool SetTargetBorderPos(CUnit*, float3&, float3&, float3&);
	bool GetTargetBorderPos(const CUnit*, const float3&, float3&, float3&) const;

	void AdjustTargetPosToWater(float3& tgtPos, bool attackGround) const;

	/// test if the weapon is able to attack an enemy/mapspot just by its properties (no range check, no FreeLineOfFire check, ...)
	virtual bool TestTarget(const float3& pos, bool userTarget, const CUnit* unit) const;
	/// test if the enemy/mapspot is in range/angle
	virtual bool TestRange(const float3& pos, bool userTarget, const CUnit* unit) const;
	/// test if something is blocking our LineOfFire
	virtual bool HaveFreeLineOfFire(const float3& pos, bool userTarget, const CUnit* unit) const;

	virtual bool CanFire(bool ignoreAngleGood, bool ignoreTargetType, bool ignoreRequestedDir) const;

	bool TryTarget(const float3& pos, bool userTarget, const CUnit* unit) const;
	bool TryTarget(const CUnit* unit, bool userTarget) const;
	bool TryTargetRotate(CUnit* unit, bool userTarget);
	bool TryTargetRotate(float3 pos, bool userTarget);
	bool TryTargetHeading(short heading, float3 pos, bool userTarget, CUnit* unit = 0);

	float3 GetUnitPositionWithError( const CUnit* unit ) const;

	bool CobBlockShot(const CUnit* unit);
	float TargetWeight(const CUnit* unit) const;
	void SlowUpdate(bool noAutoTargetOverride);

	virtual void SlowUpdate();
	virtual void Update();
	virtual float GetRange2D(float yDiff) const;
	virtual void UpdateRange(float val) { range = val; }

	virtual bool AttackUnit(CUnit* newTargetUnit, bool isUserTarget);
	virtual bool AttackGround(float3 newTargetPos, bool isUserTarget);

	void AutoTarget();
	void AimReady(int value);
	void Fire(bool scriptCall);
	void HoldFire();

	float ExperienceErrorScale() const;
	float MoveErrorExperience() const;
	float AccuracyExperience() const { return (accuracyError * ExperienceErrorScale()); }
	float SprayAngleExperience() const { return (sprayAngle * ExperienceErrorScale()); }
	float3 SalvoErrorExperience() const { return (salvoError * ExperienceErrorScale()); }

	void StopAttackingAllyTeam(int ally);
	void UpdateInterceptTarget();

protected:
	virtual void FireImpl(bool scriptCall) {}

	void UpdateTargeting();
	void UpdateFire();
	bool UpdateStockpile();
	void UpdateSalvo();

	static bool TargetUnitOrPositionUnderWater(const float3& targetPos, const CUnit* targetUnit, float offset = 0.0f);
	static bool TargetUnitOrPositionInWater(const float3& targetPos, const CUnit* targetUnit, float offset = 0.0f);

protected:
	ProjectileParams GetProjectileParams();

private:
	inline bool AllowWeaponTargetCheck();

	void UpdateRelWeaponPos();

public:
	CUnit* owner;

	const WeaponDef* weaponDef;

	int weaponNum;							// the weapons order among the owner weapons
	bool haveUserTarget;

	float craterAreaOfEffect;
	float damageAreaOfEffect;

	float muzzleFlareSize;					// size of muzzle flare if drawn
	int useWeaponPosForAim;					// sometimes weapon pos is better to use than aimpos
	bool hasCloseTarget;					// might need to update weapon pos more often when enemy is near

	int reloadTime;							// time between succesive fires in ticks
	int reloadStatus;						// next tick the weapon can fire again

	float range;
	float heightMod;						// how much extra range the weapon gain per height difference

	float projectileSpeed;
	float accuracyError;					// inaccuracy of whole salvo
	float sprayAngle;						// inaccuracy of individual shots inside salvo

	int salvoDelay;							// delay between shots in a salvo
	int salvoSize;							// number of shots in a salvo
	int projectilesPerShot;					// number of projectiles per shot
	int nextSalvo;							// when the next shot in the current salvo will fire
	int salvoLeft;							// number of shots left in current salvo

	TargetType targetType;					// indicated if we have a target and what type
	CUnit* targetUnit;						// the targeted unit if targettype=unit

	float predict;							// how long time we predict it take for a projectile to reach target
	float predictSpeedMod;					// how the weapon predicts the speed of the units goes -> 1 when experience increases

	float metalFireCost;
	float energyFireCost;

	int fireSoundId;
	float fireSoundVolume;

	bool hasBlockShot;						// set when the script has a BlockShot() function for this weapon
	bool hasTargetWeight;					// set when there's a TargetWeight() function for this weapon
	bool angleGood;							// set when script indicated ready to fire
	bool avoidTarget;						// set when the script wants the weapon to pick a new target, reset once one has been chosen
	bool onlyForward;						// can only fire in the forward direction of the unit (for aircrafts mostly?)

	unsigned int badTargetCategory;			// targets in this category get a lot lower targetting priority
	unsigned int onlyTargetCategory;		// only targets in this category can be targeted (default 0xffffffff)

	// projectiles that are on the way to our interception zone
	// (eg. nuke toward a repulsor, or missile toward a shield)
	std::map<int, CWeaponProjectile*> incomingProjectiles;
	// projectile that we currently target for interception
	CWeaponProjectile* interceptTarget;

	int stockpileTime;            // how long it takes to stockpile 1 missile
	float buildPercent;           // how far we have come on building current missile if stockpiling
	int numStockpiled;            // how many missiles we have stockpiled
	int numStockpileQued;         // how many weapons the user have added to our que

	int lastRequest;              // when the last script call was done
	int lastTargetRetry;          // when we last recalculated target selection
	int lastErrorVectorUpdate;

	CWeapon* slavedTo;            // use this weapon to choose target

	float maxForwardAngleDif;     // for onlyForward/!turret weapons, max. angle between owner->frontdir and (targetPos - owner->pos) (derived from UnitDefWeapon::maxAngleDif)
	float maxMainDirAngleDif;     // for !onlyForward/turret weapons, max. angle from <mainDir> the weapon can aim (derived from WeaponDef::tolerance)

	float targetBorder;           // if nonzero, units will TryTarget wrt. edge of scaled collision volume instead of centre
	float cylinderTargeting;      // if greater than 0, range will be checked in a cylinder (height=range*cylinderTargeting) instead of a sphere
	float minIntensity;           // for beamlasers - always hit with some minimum intensity (a damage coeffcient normally dependent on distance). do not confuse with intensity tag, it's completely unrelated.
	float heightBoostFactor;      // controls cannon range height boost. default: -1 -- automatically calculate a more or less sane value

	unsigned int avoidFlags;
	unsigned int collisionFlags;

	float fuelUsage;

	float3 relWeaponPos;          // weaponpos relative to the unit
	float3 weaponPos;             // absolute weapon pos
	float3 relWeaponMuzzlePos;    // position of the firepoint
	float3 weaponMuzzlePos;
	float3 weaponDir;
	float3 mainDir;               // main aiming-direction of weapon
	float3 wantedDir;             // the angle we want to aim in, set by the weapon subclass
	float3 lastRequestedDir;      // last angle we called the script with
	float3 salvoError;            // error vector for the whole salvo
	float3 errorVector;
	float3 errorVectorAdd;

	float3 targetPos;             // the position of the target (even if targettype=unit)
	float3 targetBorderPos;       // <targetPos> adjusted for target-border factor
};

#endif /* WEAPON_H */