Skip to content

Commit 68576e7

Browse files
authored
[GEN][ZH] Fix multiplayer mismatch on surrender in team games when owning a base structure that has been cleared of infantry before (#546)
1 parent 45bac4b commit 68576e7

File tree

2 files changed

+44
-0
lines changed
  • GeneralsMD/Code/GameEngine/Source/Common/RTS
  • Generals/Code/GameEngine/Source/Common/RTS

2 files changed

+44
-0
lines changed

Generals/Code/GameEngine/Source/Common/RTS/Player.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,29 @@ void Player::killPlayer(void)
16911691
}
16921692
if (isLocalPlayer() && !TheGameLogic->isInShellGame())
16931693
{
1694+
// TheSuperHackers @bugfix helmutbuhler 29/03/2025
1695+
// Avoid multiplayer mismatch on surrender in team games when owning a base structure that has
1696+
// been cleared of infantry before, by disabling this bugged logic.
1697+
//
1698+
// Note that becomingLocalPlayer calls recalcApparentControllingPlayer on all objects with a
1699+
// contain, which does two things:
1700+
// 1. Reset the teams of all objects with empty contains
1701+
// 2. Update m_hideGarrisonedStateFromNonallies
1702+
//
1703+
// Likely, the original intent was to reveal hidden garrisoned buildings for the new observer.
1704+
// But this does not appear to work anyway, so this call is useless.
1705+
//
1706+
// There is another bug: The Contain modules keep track of the object's team before any units
1707+
// got inside. And that team does not get updated when the player is killed and the units
1708+
// transfer to another team. That means resetting the team sets it to neutral, and when this
1709+
// is done only for the local player, then a mismatch occurs.
1710+
//
1711+
// When fixing disguises for observers or fixing the team bug in the Contain classes, then this
1712+
// code can be used again.
1713+
#if 0
16941714
becomingLocalPlayer(TRUE); // recalc disguises, etc
1715+
#endif
1716+
16951717
if (TheControlBar )
16961718
{
16971719
if (isPlayerActive())

GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,7 +2084,29 @@ void Player::killPlayer(void)
20842084
}
20852085
if (isLocalPlayer() && !TheGameLogic->isInShellGame())
20862086
{
2087+
// TheSuperHackers @bugfix helmutbuhler 29/03/2025
2088+
// Avoid multiplayer mismatch on surrender in team games when owning a base structure that has
2089+
// been cleared of infantry before, by disabling this bugged logic.
2090+
//
2091+
// Note that becomingLocalPlayer calls recalcApparentControllingPlayer on all objects with a
2092+
// contain, which does two things:
2093+
// 1. Reset the teams of all objects with empty contains
2094+
// 2. Update m_hideGarrisonedStateFromNonallies
2095+
//
2096+
// Likely, the original intent was to reveal hidden garrisoned buildings for the new observer.
2097+
// But this does not appear to work anyway, so this call is useless.
2098+
//
2099+
// There is another bug: The Contain modules keep track of the object's team before any units
2100+
// got inside. And that team does not get updated when the player is killed and the units
2101+
// transfer to another team. That means resetting the team sets it to neutral, and when this
2102+
// is done only for the local player, then a mismatch occurs.
2103+
//
2104+
// When fixing disguises for observers or fixing the team bug in the Contain classes, then this
2105+
// code can be used again.
2106+
#if 0
20872107
becomingLocalPlayer(TRUE); // recalc disguises, etc
2108+
#endif
2109+
20882110
if (TheControlBar )
20892111
{
20902112
if (isPlayerActive())

0 commit comments

Comments
 (0)