Skip to content

Commit 060b423

Browse files
committed
bugfix(specialpower): Fix special power ready state during construction
1 parent 1eceff5 commit 060b423

File tree

6 files changed

+79
-20
lines changed

6 files changed

+79
-20
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class SpecialPowerModuleInterface
5252

5353
virtual Bool isModuleForPower( const SpecialPowerTemplate *specialPowerTemplate ) const = 0;
5454
virtual Bool isReady( void ) const = 0;
55-
// This is the althernate way to one-at-a-time BlackLotus' specials; we'll keep it commented her until Dustin decides, or until 12/10/02
55+
// This is the alternate way to one-at-a-time BlackLotus' specials; we'll keep it commented her until Dustin decides, or until 12/10/02
5656
// virtual Bool isBusy( void ) const = 0;
5757
virtual Real getPercentReady( void ) const = 0;
5858
virtual UnsignedInt getReadyFrame( void ) const = 0;
@@ -73,6 +73,7 @@ class SpecialPowerModuleInterface
7373

7474
//If the special power launches a construction site, we need to know the final product for placement purposes.
7575
virtual const ThingTemplate* getReferenceThingTemplate() const = 0;
76+
virtual void onConstructionCompleted() = 0;
7677
};
7778

7879
//-------------------------------------------------------------------------------------------------
@@ -165,8 +166,12 @@ class SpecialPowerModule : public BehaviorModule,
165166
//If the special power launches a construction site, we need to know the final product for placement purposes.
166167
virtual const ThingTemplate* getReferenceThingTemplate() const { return NULL; }
167168

169+
virtual void onConstructionCompleted();
170+
168171
protected:
169172

173+
void init();
174+
void initCountdown();
170175
Bool initiateIntentToDoSpecialPower( const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions );
171176
void triggerSpecialPower( const Coord3D *location );
172177
void createViewObject( const Coord3D *location );

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ class Object : public Thing, public Snapshot
213213
Bool isAirborneTarget() const { return m_status.test( OBJECT_STATUS_AIRBORNE_TARGET ); } ///< Our locomotor will control marking us as a valid target for anti air weapons or not
214214
Bool isUsingAirborneLocomotor( void ) const; ///< returns true if the current locomotor is an airborne one
215215

216+
void onConstructionCompleted();
217+
216218
/// central place for us to put any additional capture logic
217219
void onCapture( Player *oldOwner, Player *newOwner );
218220

GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIPlayer.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ void AIPlayer::onStructureProduced( Object *factory, Object *bldg )
127127

128128
info->setUnderConstruction(false);
129129
bldg->updateObjValuesFromMapProperties(&d);
130-
// clear the under construction status
131-
bldg->clearStatus( MAKE_OBJECT_STATUS_MASK2( OBJECT_STATUS_UNDER_CONSTRUCTION, OBJECT_STATUS_RECONSTRUCTING ) );
130+
131+
bldg->onConstructionCompleted();
132132

133133
// UnderConstruction just cleared, so update our upgrades
134134
bldg->updateUpgradeModules();
@@ -470,8 +470,7 @@ Object *AIPlayer::buildStructureNow(const ThingTemplate *bldgPlan, BuildListInfo
470470
info->setObjectID( bldg->getID() );
471471
info->setObjectTimestamp( TheGameLogic->getFrame()+1 ); // has to be non-zero, so just add 1.
472472

473-
// clear the under construction status
474-
bldg->clearStatus( MAKE_OBJECT_STATUS_MASK2( OBJECT_STATUS_UNDER_CONSTRUCTION, OBJECT_STATUS_RECONSTRUCTING ) );
473+
bldg->onConstructionCompleted();
475474

476475
// UnderConstruction just cleared, so update our upgrades
477476
bldg->updateUpgradeModules();

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4505,6 +4505,35 @@ void Object::removeUpgrade( const UpgradeTemplate *upgradeT )
45054505
}
45064506
}
45074507

4508+
void Object::onConstructionCompleted()
4509+
{
4510+
if (!testStatus(OBJECT_STATUS_UNDER_CONSTRUCTION))
4511+
{
4512+
// Was already signaled completed.
4513+
DEBUG_ASSERTCRASH(!testStatus(OBJECT_STATUS_RECONSTRUCTING), ("Unexpected status"));
4514+
return;
4515+
}
4516+
4517+
DEBUG_ASSERTCRASH(
4518+
getConstructionPercent() == (Real)CONSTRUCTION_COMPLETE ||
4519+
getConstructionPercent() >= 100.0f,
4520+
("Is the construction really completed yet?"));
4521+
4522+
// clear the under construction status
4523+
clearStatus(MAKE_OBJECT_STATUS_MASK2(
4524+
OBJECT_STATUS_UNDER_CONSTRUCTION,
4525+
OBJECT_STATUS_RECONSTRUCTING
4526+
));
4527+
4528+
// tell all special powers that the construction has completed
4529+
for(BehaviorModule** m = getBehaviorModules(); *m; ++m)
4530+
{
4531+
SpecialPowerModuleInterface* sp = (*m)->getSpecialPower();
4532+
if (sp)
4533+
sp->onConstructionCompleted();
4534+
}
4535+
}
4536+
45084537
//-------------------------------------------------------------------------------------------------
45094538
/** Central point for onCapture logic */
45104539
//-------------------------------------------------------------------------------------------------

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

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa
9696
: BehaviorModule( thing, moduleData )
9797
{
9898

99-
#if RETAIL_COMPATIBLE_CRC
10099
m_availableOnFrame = 0;
101-
#else
102-
m_availableOnFrame = 0xFFFFFFFF;
103-
#endif
104100
m_pausedCount = 0;
105101
m_pausedOnFrame = 0;
106102
m_pausedPercent = 0.0f;
@@ -110,16 +106,37 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa
110106
// if we're pre-built, start counting down
111107
if( !getObject()->getStatusBits().test( OBJECT_STATUS_UNDER_CONSTRUCTION ) )
112108
{
113-
//A sharedNSync special only startPowerRecharges when first scienced or when executed,
114-
//Since a new modue with same SPTemplates may construct at any time.
115-
if ( getSpecialPowerTemplate()->isSharedNSync() == FALSE )
116-
startPowerRecharge();
109+
init();
110+
}
111+
else
112+
{
113+
#if RETAIL_COMPATIBLE_CRC
114+
initCountdown();
115+
#else
116+
// The Special Power will not be available until construction is done.
117+
m_availableOnFrame = UINT_MAX;
118+
#endif
117119
}
120+
121+
} // end SpecialPowerModule
122+
123+
void SpecialPowerModule::init()
124+
{
125+
//A sharedNSync special only startPowerRecharges when first scienced or when executed,
126+
//Since a new module with same SPTemplates may construct at any time.
127+
if ( getSpecialPowerTemplate()->isSharedNSync() == FALSE )
128+
startPowerRecharge();
129+
130+
initCountdown();
131+
}
132+
133+
void SpecialPowerModule::initCountdown()
134+
{
118135
// WE USED TO DO THE POLL-EVERYBODY-AND-VOTE-ON-WHO-TO-SYNC-TO THING HERE,
119136
// BUT NO MORE, NOW IT IS HANDLED IN PLAYER
120137

121138
// Some Special powers need to be activated by an Upgrade, so prevent the timer from going until then
122-
const SpecialPowerModuleData *md = (const SpecialPowerModuleData *)moduleData;
139+
const SpecialPowerModuleData *md = getSpecialPowerModuleData();
123140
if( md->m_startsPaused )
124141
pauseCountdown( TRUE );
125142

@@ -140,9 +157,7 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa
140157
getObject()->getID(),
141158
getSpecialPowerModuleData()->m_specialPowerTemplate );
142159
}
143-
144-
145-
} // end SpecialPowerModule
160+
}
146161

147162
//-------------------------------------------------------------------------------------------------
148163
const AudioEventRTS& SpecialPowerModule::getInitiateSound() const
@@ -380,6 +395,17 @@ Bool SpecialPowerModule::isScriptOnly() const
380395
return modData->m_scriptedSpecialPowerOnly;
381396
}
382397

398+
//-------------------------------------------------------------------------------------------------
399+
void SpecialPowerModule::onConstructionCompleted()
400+
{
401+
#if !RETAIL_COMPATIBLE_CRC
402+
DEBUG_ASSERTCRASH(m_availableOnFrame == UINT_MAX,
403+
("Unexpected state. Function must be called only after OBJECT_STATUS_UNDER_CONSTRUCTION was completed"));
404+
405+
m_availableOnFrame = 0;
406+
init();
407+
#endif
408+
}
383409

384410
//-------------------------------------------------------------------------------------------------
385411
/** A special power has been used ... start the recharge process by computing the frame

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,7 @@ StateReturnType DozerActionDoActionState::update( void )
555555
if( goalObject->getConstructionPercent() >= 100.0f )
556556
{
557557

558-
// clear the under construction status
559-
goalObject->clearStatus( MAKE_OBJECT_STATUS_MASK( OBJECT_STATUS_UNDER_CONSTRUCTION ) );
560-
goalObject->clearStatus( MAKE_OBJECT_STATUS_MASK( OBJECT_STATUS_RECONSTRUCTING ) );
558+
goalObject->onConstructionCompleted();
561559

562560
// stop playing the construction sound!
563561
dozerAI->finishBuildingSound();

0 commit comments

Comments
 (0)