Skip to content

Commit ff65bfc

Browse files
authored
Merge pull request #96 from Andreas-W/feature/weapon-damage-range-variance-taper
Feature/weapon damage range variance taper
2 parents f3c2663 + bc00d07 commit ff65bfc

10 files changed

Lines changed: 242 additions & 11 deletions

File tree

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DumbProjectileBehavior.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class DumbProjectileBehavior : public UpdateModule, public ProjectileUpdateInter
9696
virtual Bool projectileHandleCollision( Object *other );
9797
virtual Bool projectileIsArmed() const { return true; }
9898
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; }
99+
virtual Bool projectileGetLaunchPos(Coord3D& pos) const { if (m_launcherID == INVALID_ID) return false; pos = m_flightPathStart; return true; }
99100
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) {}
100101
virtual void projectileNowJammed() {}
101102
virtual Object* getTargetObject();

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/FreeFallProjectileBehavior.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class FreeFallProjectileBehavior : public UpdateModule, public ProjectileUpdateI
9898
virtual Bool projectileHandleCollision( Object *other );
9999
virtual Bool projectileIsArmed() const { return true; }
100100
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; }
101+
virtual Bool projectileGetLaunchPos(Coord3D& pos) const { if (m_launcherID == INVALID_ID) return false; pos = m_launchPos; return true; }
101102
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) {}
102103
virtual void projectileNowJammed() {}
103104
virtual Object* getTargetObject();
@@ -114,6 +115,7 @@ class FreeFallProjectileBehavior : public UpdateModule, public ProjectileUpdateI
114115
ObjectID m_launcherID; ///< ID of object that launched us (zero if not yet launched)
115116
ObjectID m_victimID; ///< ID of object we are targeting (zero if not yet launched)
116117
Coord3D m_targetPos;
118+
Coord3D m_launchPos; ///< launcher's position at launch time (for DamageFactorAtMaxRange)
117119
const WeaponTemplate* m_detonationWeaponTmpl; ///< weapon to fire at end (or null)
118120
UnsignedInt m_lifespanFrame; ///< if we haven't collided by this frame, blow up anyway
119121
WeaponBonusConditionFlags m_extraBonusFlags;

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/MissileAIUpdate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
107107
virtual Bool projectileHandleCollision( Object *other );
108108
virtual Bool projectileIsArmed() const { return m_isArmed; }
109109
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; }
110+
virtual Bool projectileGetLaunchPos(Coord3D& pos) const { if (m_launcherID == INVALID_ID) return false; pos = m_launchPos; return true; }
110111
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ); ///< Number of frames till missile diverts to countermeasures.
111112
virtual void projectileNowJammed();///< We lose our Object target and scatter to the ground
112113
virtual Object* getTargetObject();
@@ -139,6 +140,7 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
139140
Real m_maxAccel;
140141
Coord3D m_originalTargetPos; ///< When firing uphill, we aim high to clear the brow of the hill. jba.
141142
Coord3D m_prevPos;
143+
Coord3D m_launchPos; ///< launcher's position at launch time (for DamageFactorAtMaxRange)
142144
WeaponBonusConditionFlags m_extraBonusFlags;
143145
const WeaponTemplate* m_detonationWeaponTmpl; ///< weapon to fire at end (or null)
144146
const ParticleSystemTemplate* m_exhaustSysTmpl;

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/NeutronMissileUpdate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class NeutronMissileUpdate : public UpdateModule,
9999
virtual void projectileFireAtObjectOrPosition( const Object *victim, const Coord3D *victimPos, const WeaponTemplate *detWeap, const ParticleSystemTemplate* exhaustSysOverride );
100100
virtual Bool projectileIsArmed() const { return m_isArmed; } ///< return true if the missile is armed and ready to explode
101101
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; } ///< Return firer of missile. Returns 0 if not yet fired.
102+
virtual Bool projectileGetLaunchPos(Coord3D& pos) const { if (m_launcherID == INVALID_ID) return false; pos = m_launchPos; return true; } ///< launcher's position at launch time (for DamageFactorAtMaxRange)
102103
virtual Bool projectileHandleCollision( Object *other );
103104
virtual const Coord3D *getVelocity() const { return &m_vel; } ///< get current velocity
104105
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) {}
@@ -114,6 +115,7 @@ class NeutronMissileUpdate : public UpdateModule,
114115
MissileStateType m_state; ///< the behavior state of the missile
115116
Coord3D m_targetPos; ///< the position of the target
116117
Coord3D m_intermedPos;
118+
Coord3D m_launchPos; ///< launcher's position at launch time (for DamageFactorAtMaxRange)
117119

118120
ObjectID m_launcherID; ///< ID of object that launched us (zero if not yet launched)
119121
WeaponSlotType m_attach_wslot; ///< where to fire the missile from

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/UpdateModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ class ProjectileUpdateInterface
263263
virtual void projectileFireAtObjectOrPosition( const Object *victim, const Coord3D *victimPos, const WeaponTemplate *detWeap, const ParticleSystemTemplate* exhaustSysOverride ) = 0;
264264
virtual Bool projectileIsArmed() const = 0; ///< return true if the projectile is armed and ready to explode
265265
virtual ObjectID projectileGetLauncherID() const = 0; ///< All projectiles need to keep track of their firer
266+
virtual Bool projectileGetLaunchPos(Coord3D& pos) const { return false; } ///< launcher's position at launch time (for DamageFactorAtMaxRange); returns false if unknown
266267
virtual Bool projectileHandleCollision(Object *other) = 0;
267268
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) = 0; ///< Number of frames till missile diverts to countermeasures.
268269
virtual void projectileNowJammed() = 0;

GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ class WeaponTemplate : public MemoryPoolObject
494494

495495
protected:
496496

497+
// compute the range-based scaling factor (1.0 at point-blank to factorAtMaxRange at attack range)
498+
// for the engagement from 'source' to 'pos'. Uses launch-time position for projectile detonations.
499+
Real computeRangeScaleFactor(const Object* source, const Coord3D* pos, const WeaponBonus& bonus, Real factorAtMaxRange, Bool isProjectileDetonation) const;
500+
497501
// actually deal out the damage.
498502
void dealDamageInternal(ObjectID sourceID, ObjectID victimID, const Coord3D *pos, const WeaponBonus& bonus, Bool isProjectileDetonation) const;
499503
void trimOldHistoricDamage() const;
@@ -508,6 +512,8 @@ class WeaponTemplate : public MemoryPoolObject
508512
static void parseWeaponBonusSet( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
509513
static void parseScatterTarget( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
510514
static void parseShotDelay( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
515+
static void parsePrimaryDamage( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
516+
static void parseSecondaryDamage( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
511517

512518
static const FieldParse TheWeaponTemplateFieldParseTable[]; ///< the parse table for INI definition
513519

@@ -516,10 +522,17 @@ class WeaponTemplate : public MemoryPoolObject
516522
AsciiString m_projectileStreamName; ///< Name of object that tracks are stream, if we have one
517523
AsciiString m_laserName; ///< Name of the laser object that persists.
518524
AsciiString m_laserBoneName; ///< Where to put the laser object
519-
Real m_primaryDamage; ///< primary damage amount
525+
Real m_primaryDamage; ///< primary damage amount (nominal/max when variance is used)
526+
Real m_primaryDamageVariance; ///< if nonzero, actual primary damage is randomly reduced by up to this much (from Min:/Max: definition)
520527
Real m_primaryDamageRadius; ///< primary damage radius range
521-
Real m_secondaryDamage; ///< secondary damage amount
528+
Real m_secondaryDamage; ///< secondary damage amount (nominal/max when variance is used)
529+
Real m_secondaryDamageVariance; ///< if nonzero, actual secondary damage is randomly reduced by up to this much (from Min:/Max: definition)
522530
Real m_secondaryDamageRadius; ///< secondary damage radius range
531+
Real m_primaryDamageTaperOff; ///< factor of primary damage applied at the edge of the primary radius (1.0 = no taper)
532+
Real m_secondaryDamageTaperOff; ///< factor of secondary damage applied at the edge of the secondary radius (1.0 = no taper)
533+
Real m_damageFactorAtMaxRange; ///< scales damage based on engagement distance / attack range (1.0 = no scaling)
534+
Real m_radiusFactorAtMaxRange; ///< scales damage radii based on engagement distance / attack range (1.0 = no scaling)
535+
Real m_scatterRadiusFactorAtMaxRange; ///< scales ScatterRadius based on engagement distance / attack range (1.0 = no scaling)
523536
Real m_shockWaveAmount; ///( How much shockwave generated
524537
Real m_shockWaveRadius; ///( How far shockwave effect affects objects
525538
Real m_shockWaveTaperOff; ///( How much shockwave is left at the tip of the shockwave radius

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/FreeFallProjectileBehavior.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ FreeFallProjectileBehavior::FreeFallProjectileBehavior(Thing* thing, const Modul
111111
m_launcherID = INVALID_ID;
112112
m_victimID = INVALID_ID;
113113
m_targetPos.zero();
114+
m_launchPos.zero();
114115
m_detonationWeaponTmpl = NULL;
115116
m_lifespanFrame = 0;
116117
m_extraBonusFlags = 0;
@@ -142,6 +143,8 @@ void FreeFallProjectileBehavior::projectileLaunchAtObjectOrPosition(
142143
DEBUG_ASSERTCRASH(specificBarrelToUse >= 0, ("specificBarrelToUse must now be explicit"));
143144

144145
m_launcherID = launcher ? launcher->getID() : INVALID_ID;
146+
if (launcher)
147+
m_launchPos = *launcher->getPosition();
145148
m_extraBonusFlags = launcher ? launcher->getWeaponBonusCondition() : 0;
146149

147150
if (d->m_applyLauncherBonus && m_extraBonusFlags != 0) {
@@ -428,7 +431,8 @@ void FreeFallProjectileBehavior::xfer(Xfer* xfer)
428431
{
429432

430433
// version
431-
XferVersion currentVersion = 1;
434+
// 2: Added m_launchPos (for DamageFactorAtMaxRange)
435+
XferVersion currentVersion = 2;
432436
XferVersion version = currentVersion;
433437
xfer->xferVersion(&version, currentVersion);
434438

@@ -444,6 +448,10 @@ void FreeFallProjectileBehavior::xfer(Xfer* xfer)
444448
// target pos
445449
xfer->xferCoord3D(&m_targetPos);
446450

451+
// launch pos
452+
if (version >= 2)
453+
xfer->xferCoord3D(&m_launchPos);
454+
447455
// weapon template
448456
AsciiString weaponTemplateName = AsciiString::TheEmptyString;
449457
if (m_detonationWeaponTmpl)

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/MissileAIUpdate.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ MissileAIUpdate::MissileAIUpdate( Thing *thing, const ModuleData* moduleData ) :
164164
m_exhaustID = INVALID_PARTICLE_SYSTEM_ID;
165165
m_extraBonusFlags = 0;
166166
m_originalTargetPos.zero();
167+
m_launchPos.zero();
167168
m_framesTillDecoyed = 0;
168169
m_noDamage = FALSE;
169170
m_isJammed = FALSE;
@@ -225,6 +226,8 @@ void MissileAIUpdate::projectileLaunchAtObjectOrPosition(
225226
DEBUG_ASSERTCRASH(specificBarrelToUse>=0, ("specificBarrelToUse must now be explicit"));
226227

227228
m_launcherID = launcher ? launcher->getID() : INVALID_ID;
229+
if (launcher)
230+
m_launchPos = *launcher->getPosition();
228231
m_detonationWeaponTmpl = detWeap;
229232
m_extraBonusFlags = launcher ? launcher->getWeaponBonusCondition() : 0;
230233

@@ -1137,7 +1140,7 @@ void MissileAIUpdate::crc( Xfer *xfer )
11371140
void MissileAIUpdate::xfer( Xfer *xfer )
11381141
{
11391142
// version
1140-
const XferVersion currentVersion = 7;
1143+
const XferVersion currentVersion = 8;
11411144
XferVersion version = currentVersion;
11421145
xfer->xferVersion( &version, currentVersion );
11431146

@@ -1207,6 +1210,11 @@ void MissileAIUpdate::xfer( Xfer *xfer )
12071210
{
12081211
xfer->xferReal( &m_randomPathDistLeft);
12091212
}
1213+
1214+
if( version >= 8 )
1215+
{
1216+
xfer->xferCoord3D( &m_launchPos );
1217+
}
12101218
} // end xfer
12111219

12121220
// ------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileUpdate.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ NeutronMissileUpdate::NeutronMissileUpdate( Thing *thing, const ModuleData* modu
111111

112112
m_targetPos.zero();
113113
m_intermedPos.zero();
114+
m_launchPos.zero();
114115
m_accel.zero();
115116
m_vel.zero();
116117

@@ -147,6 +148,8 @@ void NeutronMissileUpdate::projectileLaunchAtObjectOrPosition(const Object *vict
147148
DEBUG_ASSERTCRASH(specificBarrelToUse>=0, ("specificBarrelToUse must now be explicit"));
148149

149150
m_launcherID = launcher ? launcher->getID() : INVALID_ID;
151+
if (launcher)
152+
m_launchPos = *launcher->getPosition();
150153
m_attach_wslot = wslot;
151154
m_attach_specificBarrelToUse = specificBarrelToUse;
152155

@@ -554,7 +557,8 @@ void NeutronMissileUpdate::xfer( Xfer *xfer )
554557
{
555558

556559
// version
557-
XferVersion currentVersion = 1;
560+
// 2: Added m_launchPos (for DamageFactorAtMaxRange)
561+
XferVersion currentVersion = 2;
558562
XferVersion version = currentVersion;
559563
xfer->xferVersion( &version, currentVersion );
560564

@@ -606,6 +610,10 @@ void NeutronMissileUpdate::xfer( Xfer *xfer )
606610
// height at launch
607611
xfer->xferReal( &m_heightAtLaunch );
608612

613+
// launch pos
614+
if( version >= 2 )
615+
xfer->xferCoord3D( &m_launchPos );
616+
609617
// decal, if any
610618
m_deliveryDecal.xferRadiusDecal(xfer);
611619

0 commit comments

Comments
 (0)