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 */
|