Skip to content

Commit b80c622

Browse files
committed
More fixes 2
1 parent 3302375 commit b80c622

File tree

7 files changed

+103
-64
lines changed

7 files changed

+103
-64
lines changed

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/OCLSpecialPower.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ void OCLSpecialPower::doSpecialPowerAtLocation( const Coord3D *loc, Real angle,
177177
SpecialPowerModule::doSpecialPowerAtLocation( &targetCoord, angle, commandOptions );
178178

179179
#if RETAIL_COMPATIBLE_CRC
180-
// TheSuperHackers @info we need to leave early if we are in the MissileLauncherBuildingUpdate crash fix codepath
181-
if (m_availableOnFrame == 0xFFFFFFFF)
180+
// TheSuperHackers @info Leave early if we are in the special power crash fix code path
181+
if (m_availableOnFrame == ~0u)
182182
return;
183183
#endif
184184

@@ -244,6 +244,12 @@ void OCLSpecialPower::doSpecialPower( UnsignedInt commandOptions )
244244
// call the base class action cause we are *EXTENDING* functionality
245245
SpecialPowerModule::doSpecialPowerAtLocation( &creationCoord, INVALID_ANGLE, commandOptions );
246246

247+
#if RETAIL_COMPATIBLE_CRC
248+
// TheSuperHackers @info Leave early if we are in the special power crash fix code path
249+
if (m_availableOnFrame == ~0u)
250+
return;
251+
#endif
252+
247253
const ObjectCreationList* ocl = findOCL();
248254
ObjectCreationList::create( ocl, getObject(), &creationCoord, &creationCoord, false );
249255
}

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ SpecialPowerModuleData::SpecialPowerModuleData()
9595
SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleData )
9696
: BehaviorModule( thing, moduleData )
9797
{
98-
9998
m_availableOnFrame = 0;
10099
m_pausedCount = 0;
101100
m_pausedOnFrame = 0;
@@ -113,12 +112,11 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa
113112
#if RETAIL_COMPATIBLE_CRC
114113
initCountdown();
115114
#else
116-
// The Special Power will not be available until construction is done.
115+
// TheSuperHackers @bugfix The Special Power will not be available until construction is done.
117116
m_availableOnFrame = ~0u;
118117
#endif
119118
}
120-
121-
} // end SpecialPowerModule
119+
}
122120

123121
void SpecialPowerModule::init()
124122
{
@@ -144,7 +142,7 @@ void SpecialPowerModule::initCountdown()
144142

145143
// Now, if we find that we have just come into being,
146144
// but there is already a science granted for our shared superweapon,
147-
// lets make sure TheIngameUI knows about our public timer
145+
// lets make sure TheInGameUI knows about our public timer
148146
// add this weapon to the UI if it has a public timer for all to see
149147
if( m_pausedCount == 0 &&
150148
getSpecialPowerTemplate()->isSharedNSync() == TRUE &&
@@ -401,7 +399,7 @@ void SpecialPowerModule::onConstructionCompleted()
401399
{
402400
#if !RETAIL_COMPATIBLE_CRC
403401
DEBUG_ASSERTCRASH(m_availableOnFrame == ~0u,
404-
("Unexpected state. Function must be called only after OBJECT_STATUS_UNDER_CONSTRUCTION was completed"));
402+
("Unexpected state. Function must be called only after OBJECT_STATUS_UNDER_CONSTRUCTION was removed"));
405403

406404
m_availableOnFrame = 0;
407405
init();
@@ -455,6 +453,13 @@ void SpecialPowerModule::startPowerRecharge()
455453
//-------------------------------------------------------------------------------------------------
456454
Bool SpecialPowerModule::initiateIntentToDoSpecialPower( const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
457455
{
456+
#if !RETAIL_COMPATIBLE_CRC
457+
if( getObject()->testStatus(OBJECT_STATUS_UNDER_CONSTRUCTION) )
458+
{
459+
return false;
460+
}
461+
#endif
462+
458463
Bool valid = false;
459464
// tell our update modules that we intend to do this special power.
460465
for( BehaviorModule** u = getObject()->getBehaviorModules(); *u; ++u )
@@ -482,26 +487,20 @@ Bool SpecialPowerModule::initiateIntentToDoSpecialPower( const Object *targetObj
482487
}
483488

484489
#if RETAIL_COMPATIBLE_CRC
485-
// TheSuperHackers @info we need to leave early if we are in the MissileLauncherBuildingUpdate crash fix codepath
490+
// TheSuperHackers @info Leave early if we are in the special power crash fix code path
486491
if (m_availableOnFrame == ~0u)
487492
{
488-
DEBUG_ASSERTCRASH(!valid, ("Using MissileLauncherBuildingUpdate escape path when valid is set to true"));
493+
DEBUG_ASSERTCRASH(!valid, ("Using special power escape path when valid is set to true"));
489494
return false;
490495
}
491496
#endif
492497

493-
getObject()->getControllingPlayer()->getAcademyStats()->recordSpecialPowerUsed( getSpecialPowerModuleData()->m_specialPowerTemplate );
494-
495-
//If we depend on our update module to trigger the special power, make sure we have the
496-
//appropriate update module!
497-
if( !valid && getSpecialPowerModuleData()->m_updateModuleStartsAttack )
498-
{
499-
DEBUG_CRASH( ("Object does not contain a special power module to execute. Did you forget to add it to the object INI?"));
500-
//DEBUG_CRASH(( "Object does not contain special power module (%s) to execute. Did you forget to add it to the object INI?",
501-
// command->m_specialPower->getName().str() ));
502-
}
498+
//If we depend on our update module to trigger the special power, make sure we have the appropriate update module!
499+
DEBUG_ASSERTCRASH(valid || !getSpecialPowerModuleData()->m_updateModuleStartsAttack,
500+
("Object does not contain a special power module to execute. Did you forget to add it to the object INI?"));
503501

504-
return valid;
502+
getObject()->getControllingPlayer()->getAcademyStats()->recordSpecialPowerUsed( getSpecialPowerModuleData()->m_specialPowerTemplate );
503+
return true;
505504
}
506505

507506
//-------------------------------------------------------------------------------------------------
@@ -704,15 +703,16 @@ void SpecialPowerModule::doSpecialPower( UnsignedInt commandOptions )
704703

705704
//This tells the update module that we want to do our special power. The update modules
706705
//will then start processing each frame.
707-
initiateIntentToDoSpecialPower( NULL, NULL, NULL, commandOptions );
708-
709-
//Only trigger the special power immediately if the updatemodule doesn't start the attack.
710-
//An example of a case that wouldn't trigger immediately is for a unit that needs to
711-
//close to range before firing the special attack. A case that would trigger immediately
712-
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
713-
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
706+
if (initiateIntentToDoSpecialPower( NULL, NULL, NULL, commandOptions ))
714707
{
715-
triggerSpecialPower( NULL );// Location-less trigger
708+
//Only trigger the special power immediately if the update module doesn't start the attack.
709+
//An example of a case that wouldn't trigger immediately is for a unit that needs to
710+
//close to range before firing the special attack. A case that would trigger immediately
711+
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
712+
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
713+
{
714+
triggerSpecialPower( NULL );// Location-less trigger
715+
}
716716
}
717717
}
718718

@@ -726,15 +726,16 @@ void SpecialPowerModule::doSpecialPowerAtObject( Object *obj, UnsignedInt comman
726726

727727
//This tells the update module that we want to do our special power. The update modules
728728
//will then start processing each frame.
729-
initiateIntentToDoSpecialPower( obj, NULL, NULL, commandOptions );
730-
731-
//Only trigger the special power immediately if the updatemodule doesn't start the attack.
732-
//An example of a case that wouldn't trigger immediately is for a unit that needs to
733-
//close to range before firing the special attack. A case that would trigger immediately
734-
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
735-
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
729+
if (initiateIntentToDoSpecialPower( obj, NULL, NULL, commandOptions ))
736730
{
737-
triggerSpecialPower( obj->getPosition() );
731+
//Only trigger the special power immediately if the update module doesn't start the attack.
732+
//An example of a case that wouldn't trigger immediately is for a unit that needs to
733+
//close to range before firing the special attack. A case that would trigger immediately
734+
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
735+
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
736+
{
737+
triggerSpecialPower( obj->getPosition() );
738+
}
738739
}
739740
}
740741

@@ -748,21 +749,16 @@ void SpecialPowerModule::doSpecialPowerAtLocation( const Coord3D *loc, Real angl
748749

749750
//This tells the update module that we want to do our special power. The update modules
750751
//will then start processing each frame.
751-
initiateIntentToDoSpecialPower( NULL, loc, NULL, commandOptions );
752-
753-
#if RETAIL_COMPATIBLE_CRC
754-
// TheSuperHackers @info we need to leave early if we are in the MissileLauncherBuildingUpdate crash fix codepath
755-
if (m_availableOnFrame == ~0u)
756-
return;
757-
#endif
758-
759-
//Only trigger the special power immediately if the updatemodule doesn't start the attack.
760-
//An example of a case that wouldn't trigger immediately is for a unit that needs to
761-
//close to range before firing the special attack. A case that would trigger immediately
762-
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
763-
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
752+
if (initiateIntentToDoSpecialPower( NULL, loc, NULL, commandOptions ))
764753
{
765-
triggerSpecialPower( loc );
754+
//Only trigger the special power immediately if the update module doesn't start the attack.
755+
//An example of a case that wouldn't trigger immediately is for a unit that needs to
756+
//close to range before firing the special attack. A case that would trigger immediately
757+
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
758+
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
759+
{
760+
triggerSpecialPower( loc );
761+
}
766762
}
767763
}
768764

@@ -776,15 +772,16 @@ void SpecialPowerModule::doSpecialPowerUsingWaypoints( const Waypoint *way, Unsi
776772

777773
//This tells the update module that we want to do our special power. The update modules
778774
//will then start processing each frame.
779-
initiateIntentToDoSpecialPower( NULL, NULL, way, commandOptions );
780-
781-
//Only trigger the special power immediately if the updatemodule doesn't start the attack.
782-
//An example of a case that wouldn't trigger immediately is for a unit that needs to
783-
//close to range before firing the special attack. A case that would trigger immediately
784-
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
785-
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
775+
if (initiateIntentToDoSpecialPower( NULL, NULL, way, commandOptions ))
786776
{
787-
triggerSpecialPower( NULL );// This type doesn't create view objects
777+
//Only trigger the special power immediately if the update module doesn't start the attack.
778+
//An example of a case that wouldn't trigger immediately is for a unit that needs to
779+
//close to range before firing the special attack. A case that would trigger immediately
780+
//is the napalm strike. If we don't call this now, it's up to the update module to do so.
781+
if( !getSpecialPowerModuleData()->m_updateModuleStartsAttack )
782+
{
783+
triggerSpecialPower( NULL );// This type doesn't create view objects
784+
}
788785
}
789786
}
790787

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ void BattlePlanUpdate::onObjectCreated()
261261
//-------------------------------------------------------------------------------------------------
262262
Bool BattlePlanUpdate::initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
263263
{
264+
#if RETAIL_COMPATIBLE_CRC
265+
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
266+
if (!m_specialPowerModule) {
267+
Object* us = getObject();
268+
us->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(0xFFFFFFFF);
269+
return FALSE;
270+
}
271+
#endif
272+
264273
if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate )
265274
{
266275
//Check to make sure our modules are connected.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,14 @@ void MissileLauncherBuildingUpdate::switchToState(DoorStateType dst)
205205
//-------------------------------------------------------------------------------------------------
206206
Bool MissileLauncherBuildingUpdate::initiateIntentToDoSpecialPower( const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
207207
{
208-
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
209-
if( getObject()->testStatus(OBJECT_STATUS_UNDER_CONSTRUCTION) )
210-
{
211208
#if RETAIL_COMPATIBLE_CRC
212-
getObject()->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(~0u);
213-
#endif
209+
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
210+
if (!m_specialPowerModule) {
211+
Object* us = getObject();
212+
us->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(0xFFFFFFFF);
214213
return FALSE;
215214
}
215+
#endif
216216

217217
if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate )
218218
{

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,15 @@ void ParticleUplinkCannonUpdate::onObjectCreated()
267267
//-------------------------------------------------------------------------------------------------
268268
Bool ParticleUplinkCannonUpdate::initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
269269
{
270+
#if RETAIL_COMPATIBLE_CRC
271+
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
272+
if (!m_specialPowerModule) {
273+
Object* us = getObject();
274+
us->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(0xFFFFFFFF);
275+
return FALSE;
276+
}
277+
#endif
278+
270279
const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData();
271280

272281
if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate )

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ void SpectreGunshipDeploymentUpdate::onObjectCreated()
139139
//-------------------------------------------------------------------------------------------------
140140
Bool SpectreGunshipDeploymentUpdate::initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
141141
{
142+
#if RETAIL_COMPATIBLE_CRC
143+
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
144+
if (!m_specialPowerModule) {
145+
Object* us = getObject();
146+
us->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(0xFFFFFFFF);
147+
return FALSE;
148+
}
149+
#endif
150+
142151
const SpectreGunshipDeploymentUpdateModuleData *data = getSpectreGunshipDeploymentUpdateModuleData();
143152

144153
if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate )

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,15 @@ void SpectreGunshipUpdate::onObjectCreated()
183183
//-------------------------------------------------------------------------------------------------
184184
Bool SpectreGunshipUpdate::initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions )
185185
{
186+
#if RETAIL_COMPATIBLE_CRC
187+
// TheSuperHackers @bugfix Mauller 29/06/2025 prevent a game crash when told to launch before ready to do so
188+
if (!m_specialPowerModule) {
189+
Object* us = getObject();
190+
us->getSpecialPowerModule(specialPowerTemplate)->setReadyFrame(0xFFFFFFFF);
191+
return FALSE;
192+
}
193+
#endif
194+
186195
const SpectreGunshipUpdateModuleData *data = getSpectreGunshipUpdateModuleData();
187196

188197
if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate )

0 commit comments

Comments
 (0)