-
Notifications
You must be signed in to change notification settings - Fork 173
bugfix(battleplan): Battle plans are now transferred to the new owner on capture #2257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -247,6 +247,16 @@ void BattlePlanUpdate::onObjectCreated() | |||||||||||||||||||||||||||||||||||
| enableTurret( false ); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| //------------------------------------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||
| void BattlePlanUpdate::onCapture(Player* oldOwner, Player* newOwner) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| #if !RETAIL_COMPATIBLE_CRC | ||||||||||||||||||||||||||||||||||||
| // TheSuperHackers @bugfix Stubbjax 04/11/2025 Transfer battle plan bonuses on capture. | ||||||||||||||||||||||||||||||||||||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
| oldOwner->changeBattlePlan(m_planAffectingArmy, -1, m_bonuses); | ||||||||||||||||||||||||||||||||||||
| newOwner->changeBattlePlan(m_planAffectingArmy, 1, m_bonuses); | ||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+251
to
+257
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing null pointer guard for The // however, player CAN legitimately be null during game reset cycles
if( player && m_planAffectingArmy != PLANSTATUS_NONE )The new
Suggested change
The same issue is present in Prompt To Fix With AIThis is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameLogic/Object/Update/BattlePlanUpdate.cpp
Line: 251-257
Comment:
**Missing null pointer guard for `oldOwner`**
The `onDelete` method (line ~194) has an explicit comment noting that the controlling player *can legitimately be null* during game reset cycles, and guards accordingly:
```cpp
// however, player CAN legitimately be null during game reset cycles
if( player && m_planAffectingArmy != PLANSTATUS_NONE )
```
The new `onCapture` doesn't apply the same safety check. If `oldOwner` is null (e.g., capturing from a neutral entity during a reset cycle), calling `oldOwner->changeBattlePlan(...)` will crash. `newOwner` should similarly be guarded.
```suggestion
void BattlePlanUpdate::onCapture(Player* oldOwner, Player* newOwner)
{
#if !RETAIL_COMPATIBLE_CRC
// TheSuperHackers @bugfix Stubbjax 04/11/2025 Transfer battle plan bonuses on capture.
if( oldOwner )
oldOwner->changeBattlePlan(m_planAffectingArmy, -1, m_bonuses);
if( newOwner )
newOwner->changeBattlePlan(m_planAffectingArmy, 1, m_bonuses);
#endif
}
```
The same issue is present in `GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/BattlePlanUpdate.cpp:251`.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we care for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably not - captures happen during active gameplay between two valid players, not during reset cycles like deletion. The However, it's a low-cost safety check (just two If they're only player-built, the guards aren't needed. If there's any scenario where a neutral Strategy Center exists and can be captured, then |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| //------------------------------------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||
| Bool BattlePlanUpdate::initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions ) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do wonder, is this CRC safe?
This function is called like so:
So
m_bonuseswill be written here by the original code.But now with this change,
m_bonuseswill remain unmodified. Does this not carry the risk of mismatch? If not, why?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tested a multiplayer match between one client @ 7cb5a62 and another @ 6e41efa and did not observe any mismatches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it does not mismatch because
This resets the scalars after every removal to restore a clean slate.
It could only mismatch if this reset was not happening after a battle plan removal.