Skip to content

Commit bea4fed

Browse files
committed
Optimized ProjectileStreams calculations + Allowed Weapon FX Tweaks via External Code
1 parent 13de427 commit bea4fed

File tree

8 files changed

+231
-8
lines changed

8 files changed

+231
-8
lines changed

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DProjectileStreamDraw.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ void W3DProjectileStreamDraw::doDrawModule(const Matrix3D* )
132132
static NameKeyType key_ProjectileStreamUpdate = NAMEKEY("ProjectileStreamUpdate");
133133
ProjectileStreamUpdate* update = (ProjectileStreamUpdate*)me->findUpdateModule(key_ProjectileStreamUpdate);
134134

135+
// Requires ProjectileStreamUpdate for getting Vector Points
136+
if(!update)
137+
return;
138+
135139
const W3DProjectileStreamDrawModuleData *data = getW3DProjectileStreamDrawModuleData();
136140

137141
Vector3 allPoints[MAX_PROJECTILE_STREAM];
@@ -140,7 +144,6 @@ void W3DProjectileStreamDraw::doDrawModule(const Matrix3D* )
140144
update->getAllPoints( allPoints, &pointsUsed );
141145

142146
Vector3 stagingPoints[MAX_PROJECTILE_STREAM];
143-
Vector3 zeroVector(0, 0, 0);
144147

145148
Int linesMade = 0;
146149
Int currentMasterPoint = 0;
@@ -159,7 +162,10 @@ void W3DProjectileStreamDraw::doDrawModule(const Matrix3D* )
159162
// I'll keep doing this until I run out of valid points.
160163
while( currentMasterPoint < pointsUsed )
161164
{
162-
while( currentMasterPoint < pointsUsed && allPoints[currentMasterPoint] != zeroVector )
165+
// TheSuperHackers @ performance IamInnocent 03/01/26 - Changes ProjectileStreamDraw Update Requirement Vector from being equal zero Vector to any Vector above near zero.
166+
while( currentMasterPoint < pointsUsed &&
167+
(fabs(allPoints[currentMasterPoint].X) > WWMATH_EPSILON || fabs(allPoints[currentMasterPoint].Y) > WWMATH_EPSILON || fabs(allPoints[currentMasterPoint].Z) > WWMATH_EPSILON)
168+
)
163169
{
164170
// While I am not looking at a bad point (off edge or zero)
165171
stagingPoints[currentStagingPoint] = allPoints[currentMasterPoint];// copy to the staging

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ class BoneFXUpdate : public UpdateModule
243243

244244
virtual UpdateSleepTime update();
245245

246+
#if !PRESERVE_RETAIL_BEHAVIOR
247+
void setInactive() { m_inactive = TRUE; }
248+
#endif
249+
246250
protected:
247251

248252
virtual void onObjectCreated();
@@ -273,4 +277,8 @@ class BoneFXUpdate : public UpdateModule
273277
BodyDamageType m_curBodyState;
274278
Bool m_bonesResolved[BODYDAMAGETYPE_COUNT];
275279
Bool m_active;
280+
281+
#if !PRESERVE_RETAIL_BEHAVIOR
282+
Bool m_inactive;
283+
#endif
276284
};

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,13 @@ class PartitionCell : public Snapshot // not MPO: allocated in an array
304304
Short m_cellX; ///< x-coord of this cell within the Partition Mgr coords (NOT in world coords)
305305
Short m_cellY; ///< y-coord of this cell within the Partition Mgr coords (NOT in world coords)
306306

307+
#if !PRESERVE_RETAIL_BEHAVIOR
308+
typedef std::pair<AsciiString,Int> WeaponNameDurationPair;
309+
typedef std::vector<WeaponNameDurationPair> WeaponNameDurationVec;
310+
311+
WeaponNameDurationVec m_weaponNameDurationVec;
312+
#endif
313+
307314
public:
308315

309316
// Note, we allocate these in arrays, thus we must have a default ctor (and NOT descend from MPO)
@@ -359,6 +366,11 @@ class PartitionCell : public Snapshot // not MPO: allocated in an array
359366

360367
// intended only for CellAndObjectIntersection.
361368
void friend_removeFromCellList(CellAndObjectIntersection *coi);
369+
370+
#if !PRESERVE_RETAIL_BEHAVIOR
371+
Int getWeaponNameStack(const AsciiString& weaponName) const;
372+
void registerWeaponNameStack(const AsciiString& weaponName, UnsignedInt duration);
373+
#endif
362374
};
363375

364376
//=====================================
@@ -1528,6 +1540,11 @@ class PartitionManager : public SubsystemInterface, public Snapshot
15281540
// If saveToFog is false, then we are writing STORE_PERMENANT_REVEAL
15291541
void storeFoggedCells(ShroudStatusStoreRestore &outPartitionStore, Bool storeToFog) const;
15301542
void restoreFoggedCells(const ShroudStatusStoreRestore &inPartitionStore, Bool restoreToFog);
1543+
1544+
#if !PRESERVE_RETAIL_BEHAVIOR
1545+
Int getWeaponNameStackAtCell(const Coord3D *pos, const AsciiString& weaponName) const;
1546+
void registerWeaponNameAtCell(const Coord3D *pos, const AsciiString& weaponName, UnsignedInt duration);
1547+
#endif
15311548
};
15321549

15331550
// -----------------------------------------------------------------------------

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,13 @@ class WeaponTemplate : public MemoryPoolObject
464464
Bool isPlayFXWhenStealthed() const { return m_playFXWhenStealthed; }
465465
Bool getDieOnDetonate() const { return m_dieOnDetonate; }
466466

467+
#if !PRESERVE_RETAIL_BEHAVIOR
468+
UnsignedInt getFXRenderingInterval() const { return m_fxRenderingInterval; }
469+
UnsignedInt getFXMaxStackInterval() const { return m_fxMaxStackInterval; }
470+
Int getFXMaxStackPerLoc() const { return m_fxMaxStackPerLoc; }
471+
Bool getCheckFireFXForFXMaxStack() const { return m_checkFireFXForFXMaxStack; }
472+
#endif
473+
467474
Bool shouldProjectileCollideWith(
468475
const Object* projectileLauncher,
469476
const Object* projectile,
@@ -563,6 +570,13 @@ class WeaponTemplate : public MemoryPoolObject
563570
UnsignedInt m_suspendFXDelay; ///< The fx can be suspended for any delay, in frames, then they will execute as normal
564571
Bool m_dieOnDetonate;
565572

573+
#if !PRESERVE_RETAIL_BEHAVIOR
574+
UnsignedInt m_fxRenderingInterval;
575+
UnsignedInt m_fxMaxStackInterval;
576+
Int m_fxMaxStackPerLoc;
577+
Bool m_checkFireFXForFXMaxStack;
578+
#endif
579+
566580
mutable HistoricWeaponDamageList m_historicDamage;
567581
mutable UnsignedInt m_historicDamageTriggerId;
568582
};
@@ -766,6 +780,11 @@ class Weapon : public MemoryPoolObject,
766780
void setClipPercentFull(Real percent, Bool allowReduction);
767781
UnsignedInt getSuspendFXFrame( void ) const { return m_suspendFXFrame; }
768782

783+
#if !PRESERVE_RETAIL_BEHAVIOR
784+
UnsignedInt getLastFXShotFrame( void ) const { return m_lastFXFireFrame; }
785+
void setLastFXShotFrame(UnsignedInt frame) { m_lastFXFireFrame = frame; }
786+
#endif
787+
769788
protected:
770789

771790
Weapon(const WeaponTemplate* tmpl, WeaponSlotType wslot);
@@ -811,6 +830,10 @@ class Weapon : public MemoryPoolObject,
811830
Bool m_pitchLimited;
812831
Bool m_leechWeaponRangeActive; ///< This weapon has unlimited range until attack state is aborted!
813832

833+
#if !PRESERVE_RETAIL_BEHAVIOR
834+
UnsignedInt m_lastFXFireFrame; ///< frame a shot was last fired on with FX Rendered
835+
#endif
836+
814837
// setter function for status that should not be used outside this class
815838
void setStatus( WeaponStatus status) { m_status = status; }
816839
};

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,10 @@ PartitionCell::PartitionCell()
12501250
// default threat value is 0
12511251
m_threatValue[i] = 0;
12521252
}
1253+
1254+
#if !PRESERVE_RETAIL_BEHAVIOR
1255+
m_weaponNameDurationVec.clear();
1256+
#endif
12531257
}
12541258

12551259
//-----------------------------------------------------------------------------
@@ -1499,6 +1503,46 @@ void PartitionCell::validateCoiList()
14991503
}
15001504
#endif
15011505

1506+
#if !PRESERVE_RETAIL_BEHAVIOR
1507+
//-----------------------------------------------------------------------------
1508+
Int PartitionCell::getWeaponNameStack(const AsciiString& weaponName) const
1509+
{
1510+
Int count = 0;
1511+
UnsignedInt now = TheGameLogic->getFrame();
1512+
for(WeaponNameDurationVec::const_iterator it = m_weaponNameDurationVec.begin(); it != m_weaponNameDurationVec.end(); ++it)
1513+
{
1514+
if(it->first == weaponName && it->second > now)
1515+
count++;
1516+
}
1517+
return count;
1518+
}
1519+
1520+
//-----------------------------------------------------------------------------
1521+
void PartitionCell::registerWeaponNameStack(const AsciiString& weaponName, UnsignedInt duration)
1522+
{
1523+
UnsignedInt now = TheGameLogic->getFrame();
1524+
1525+
// Clean the vector everytime we register a new stack
1526+
for (WeaponNameDurationVec::iterator it = m_weaponNameDurationVec.begin(); it != m_weaponNameDurationVec.end(); /* empty */ )
1527+
{
1528+
if (it->second <= now)
1529+
{
1530+
it = m_weaponNameDurationVec.erase(it);
1531+
}
1532+
else
1533+
{
1534+
++it;
1535+
}
1536+
}
1537+
1538+
WeaponNameDurationPair stack;
1539+
stack.first = weaponName;
1540+
stack.second = now + duration;
1541+
1542+
m_weaponNameDurationVec.push_back(stack);
1543+
}
1544+
#endif
1545+
15021546
// ------------------------------------------------------------------------------------------------
15031547
/** CRC */
15041548
// ------------------------------------------------------------------------------------------------
@@ -4593,6 +4637,32 @@ Bool PartitionManager::isClearLineOfSightTerrain(const Object* obj, const Coord3
45934637
#endif
45944638
}
45954639

4640+
#if !PRESERVE_RETAIL_BEHAVIOR
4641+
//-----------------------------------------------------------------------------
4642+
Int PartitionManager::getWeaponNameStackAtCell(const Coord3D *pos, const AsciiString& weaponName) const
4643+
{
4644+
Int cellX, cellY;
4645+
worldToCell(pos->x, pos->y, &cellX, &cellY);
4646+
const PartitionCell* cell = getCellAt(cellX, cellY); // might be null if off the edge
4647+
DEBUG_ASSERTCRASH(cell != NULL, ("off the map"));
4648+
if (cell)
4649+
return cell->getWeaponNameStack(weaponName);
4650+
else
4651+
return 0;
4652+
}
4653+
4654+
//-----------------------------------------------------------------------------
4655+
void PartitionManager::registerWeaponNameAtCell(const Coord3D *pos, const AsciiString& weaponName, UnsignedInt duration)
4656+
{
4657+
Int cellX, cellY;
4658+
worldToCell(pos->x, pos->y, &cellX, &cellY);
4659+
PartitionCell* cell = getCellAt(cellX, cellY); // might be null if off the edge
4660+
DEBUG_ASSERTCRASH(cell != NULL, ("off the map"));
4661+
if (cell)
4662+
cell->registerWeaponNameStack(weaponName, duration);
4663+
}
4664+
#endif
4665+
45964666
// ------------------------------------------------------------------------------------------------
45974667
/** CRC */
45984668
// ------------------------------------------------------------------------------------------------

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ BoneFXUpdate::BoneFXUpdate( Thing *thing, const ModuleData* moduleData ) : Updat
9090
}
9191
m_particleSystemIDs.clear();
9292
m_active = FALSE;
93+
#if !PRESERVE_RETAIL_BEHAVIOR
94+
m_inactive = FALSE;
95+
#endif
9396

9497
m_curBodyState = BODY_PRISTINE;
9598
}
@@ -292,6 +295,11 @@ UpdateSleepTime BoneFXUpdate::update( void )
292295
const BoneFXUpdateModuleData *d = getBoneFXUpdateModuleData();
293296
Int now = TheGameLogic->getFrame();
294297

298+
#if !PRESERVE_RETAIL_BEHAVIOR
299+
if(m_inactive == TRUE)
300+
return UPDATE_SLEEP_NONE;
301+
#endif
302+
295303
if (m_active == FALSE) {
296304
initTimes();
297305
m_active = TRUE;
@@ -569,7 +577,11 @@ void BoneFXUpdate::xfer( Xfer *xfer )
569577
{
570578

571579
// version
580+
#if !RETAIL_COMPATIBLE_XFER_SAVE && !PRESERVE_RETAIL_BEHAVIOR
581+
XferVersion currentVersion = 2;
582+
#else
572583
XferVersion currentVersion = 1;
584+
#endif
573585
XferVersion version = currentVersion;
574586
xfer->xferVersion( &version, currentVersion );
575587

@@ -646,6 +658,11 @@ void BoneFXUpdate::xfer( Xfer *xfer )
646658
// active
647659
xfer->xferBool( &m_active );
648660

661+
#if !PRESERVE_RETAIL_BEHAVIOR
662+
if( version >= 2)
663+
xfer->xferBool( &m_inactive );
664+
#endif
665+
649666
}
650667

651668
// ------------------------------------------------------------------------------------------------

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ void ProjectileStreamUpdate::addProjectile( ObjectID sourceID, ObjectID newID, O
9191
{
9292
// Changed targets, insert a hole to break the stream
9393
m_projectileIDs[ m_nextFreeIndex ] = INVALID_ID;
94-
m_nextFreeIndex = (m_nextFreeIndex + 1) % MAX_PROJECTILE_STREAM;
94+
95+
// TheSuperHackers @ performance IamInnocent 03/01/26 - Refractor the usage of Modulo to Comparison
96+
if(++m_nextFreeIndex >= MAX_PROJECTILE_STREAM)
97+
m_nextFreeIndex -= MAX_PROJECTILE_STREAM;
9598

9699
// And mark this as our new target
97100
m_targetObject = victimID;
@@ -106,7 +109,8 @@ void ProjectileStreamUpdate::addProjectile( ObjectID sourceID, ObjectID newID, O
106109
{
107110
// New position, so insert hole
108111
m_projectileIDs[ m_nextFreeIndex ] = INVALID_ID;
109-
m_nextFreeIndex = (m_nextFreeIndex + 1) % MAX_PROJECTILE_STREAM;
112+
if(++m_nextFreeIndex >= MAX_PROJECTILE_STREAM)
113+
m_nextFreeIndex -= MAX_PROJECTILE_STREAM;
110114

111115
// And mark this as our new target
112116
m_targetPosition = (*victimPos);
@@ -122,7 +126,8 @@ void ProjectileStreamUpdate::addProjectile( ObjectID sourceID, ObjectID newID, O
122126

123127
// Keep track of the id in a circular array
124128
m_projectileIDs[ m_nextFreeIndex ] = newID;
125-
m_nextFreeIndex = (m_nextFreeIndex + 1) % MAX_PROJECTILE_STREAM;
129+
if(++m_nextFreeIndex >= MAX_PROJECTILE_STREAM)
130+
m_nextFreeIndex -= MAX_PROJECTILE_STREAM;
126131
DEBUG_ASSERTCRASH( m_nextFreeIndex != m_firstValidIndex, ("Need to increase the allowed number of simultaneous particles in ProjectileStreamUpdate.") );
127132
}
128133

@@ -131,7 +136,8 @@ void ProjectileStreamUpdate::cullFrontOfList()
131136
while( (m_firstValidIndex != m_nextFreeIndex) && (TheGameLogic->findObjectByID( m_projectileIDs[m_firstValidIndex] ) == NULL) )
132137
{
133138
// Chew off the front if they are gone. Don't chew on the middle, as bad ones there are just a break in the chain
134-
m_firstValidIndex = (m_firstValidIndex + 1) % MAX_PROJECTILE_STREAM;
139+
if(++m_nextFreeIndex >= MAX_PROJECTILE_STREAM)
140+
m_nextFreeIndex -= MAX_PROJECTILE_STREAM;
135141
}
136142
}
137143

@@ -194,7 +200,8 @@ void ProjectileStreamUpdate::getAllPoints( Vector3 *points, Int *count )
194200
points[pointCount].Z = 0;
195201
}
196202

197-
pointIndex = (pointIndex + 1) % MAX_PROJECTILE_STREAM;
203+
if(++pointIndex >= MAX_PROJECTILE_STREAM)
204+
pointIndex -= MAX_PROJECTILE_STREAM;
198205
pointCount++;
199206
}
200207

0 commit comments

Comments
 (0)