bugfix(specialpower): Charge uninitialized special powers on new buildings#2781
bugfix(specialpower): Charge uninitialized special powers on new buildings#2781bobtista wants to merge 1 commit into
Conversation
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp | Adds a sentinel-check loop in onStructureConstructionComplete() to make uninitialized special powers ready on build completion; logic is correct, but uses a bare 0xFFFFFFFF literal that is already repeated across the special-power subsystem without a named constant. |
Sequence Diagram
sequenceDiagram
participant Dozer as DozerAIUpdate
participant Player as Player
participant SPMod as SpecialPowerModule
participant SPCreate as SpecialPowerCreate
Note over SPMod: Constructor (UNDER_CONSTRUCTION)<br/>m_availableOnFrame = 0xFFFFFFFF<br/>startPowerRecharge() NOT called
Dozer->>Player: onStructureConstructionComplete()
activate Player
Note over Player: #if !RETAIL_COMPATIBLE_CRC
Player->>SPMod: getReadyFrame()
SPMod-->>Player: 0xFFFFFFFF (sentinel)
Player->>SPMod: setReadyFrame(currentFrame)
Note over SPMod: m_availableOnFrame = currentFrame<br/>isReady() → true
Player-->>Dozer:
deactivate Player
alt Building HAS SpecialPowerCreate
Dozer->>SPCreate: onBuildComplete()
activate SPCreate
SPCreate->>SPMod: onSpecialPowerCreation() → startPowerRecharge()
Note over SPMod: m_availableOnFrame = currentFrame + reloadTime<br/>(overwrites fix — correct countdown)
SPCreate-->>Dozer:
deactivate SPCreate
else Building has NO SpecialPowerCreate
Note over SPMod: m_availableOnFrame = currentFrame remains<br/>isReady() → true immediately
end
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp:1667
The sentinel value `0xFFFFFFFF` is repeated here as a bare literal — it already appears verbatim in `SpecialPowerModule.cpp` (constructor, `initiateIntentToDoSpecialPower`, `getReadyFrame`). Introducing a named constant shared between those sites (e.g. `SPECIAL_POWER_UNINITIALIZED_FRAME`) would make the intent explicit and ensure any future change to the sentinel propagates everywhere automatically.
```suggestion
if( specialPower->getReadyFrame() == SPECIAL_POWER_UNINITIALIZED_FRAME )
```
Reviews (1): Last reviewed commit: "bugfix(specialpower): Charge uninitializ..." | Re-trigger Greptile
|
I think this is now the third open pull for this issue. |
Let's merge one and close the others + issue |
|
Which fix is the best? |
1461 seems to actually fix the issue, the other two just let the building finish, then force the still-uninitialized power to ready-now. I'd test it, replicate to Generals and merge it |
With RETAIL_COMPATIBLE_CRC=0, special-power buttons on freshly built buildings that lack a SpecialPowerCreate module (Strategy Center battle plans, Intelligence) are permanently disabled. Addresses #2780
Cause
PR #1218 initialized SpecialPowerModule::m_availableOnFrame to 0xFFFFFFFF under !RETAIL_COMPATIBLE_CRC. The constructor only calls startPowerRecharge() when the object is not UNDER_CONSTRUCTION; for built structures the recharge is otherwise driven by SpecialPowerCreate::onBuildComplete(). Buildings without that module never leave the sentinel value, so isReady() never returns true.
Fix
In Player::onStructureConstructionComplete(), after a structure finishes building, charge any special-power module still at the 0xFFFFFFFF sentinel to ready-now (setReadyFrame(TheGameLogic->getFrame())). This restores retail's immediate availability for these powers. Guarded with #if !RETAIL_COMPATIBLE_CRC, so retail CRC/replay compatibility is unchanged.
Testing
Todo
[] Replicate to Generals