Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion GeneralsMD/Code/GameEngine/Source/Common/RTS/Team.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,7 @@ Player *Team::getControllingPlayer() const
// ------------------------------------------------------------------------
void Team::setControllingPlayer(Player *newController)
{
Player* oldOwner = m_proto->getControllingPlayer();
// NULL is not allowed, but is caught by TeamPrototype::setControllingPlayer()
m_proto->setControllingPlayer(newController);

Expand All @@ -1399,6 +1400,7 @@ void Team::setControllingPlayer(Player *newController)
// The Team doesn't change, it just starts to return a different answer when you ask for
// the controlling player. I don't want to make the major change of onCapture on everyone,
// so I will do the minor fix for the specific bug, which is harmless even when misused.
// TheSuperHackers @fix xezon 07/12/2025 Now does onCapture on everyone.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth cleaning up the legacy comment as it no longer applies anymore

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not want to nuke the EA comment so I just appended information. If you have a suggestion for how to rewrite the EA comment, please write.


// Tell all members to redo their looking status, as their Player has changed, but they don't know.
for (DLINK_ITERATOR<Object> iter = iterate_TeamMemberList(); !iter.done(); iter.advance())
Expand All @@ -1407,7 +1409,14 @@ void Team::setControllingPlayer(Player *newController)
if (!obj)
continue;

obj->handlePartitionCellMaintenance();
if constexpr (RETAIL_COMPATIBLE_CRC) // Not sure if necessary. But likely is.
{
obj->handlePartitionCellMaintenance();
}
else
{
obj->onCapture(oldOwner, newController);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked ok in GLA 03 mission and avoids the tunnel transfer issue, but I do not know if it creates new problems. Something to keep an eye on.

Copy link

@Mauller Mauller Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handlePartitionCellMaintenance gets called within object::onCapture so shouldn't need calling here.
it also gets called within tunnelContain::onCapture as well which will get triggered by object::onCapture as it loops through all behaviour modules and calls their onCapture function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are exclusive calls depending on RETAIL_COMPATIBLE_CRC

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we test if the object is a tunnel and perform TunnelContain::onCapture() only on the tunnels? since they are a special case in this instance due to the tunnel system needing to be updated properly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I used RETAIL_COMPATIBLE_CRC is to avoid any chance of mismatch because it looks risky for any object.

The crash is avoided anyway with the fix in TunnelTracker::onTunnelDestroyed.

}
}

}
Expand Down
15 changes: 12 additions & 3 deletions GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,18 @@ void TunnelTracker::onTunnelCreated( const Object *newTunnel )
// ------------------------------------------------------------------------
void TunnelTracker::onTunnelDestroyed( const Object *deadTunnel )
{
m_tunnelCount--;
m_tunnelIDs.remove( deadTunnel->getID() );
m_needsFullHealTimeUpdate = true;
{
std::list<ObjectID>::iterator it = std::find(m_tunnelIDs.begin(), m_tunnelIDs.end(), deadTunnel->getID());
if (it == m_tunnelIDs.end())
{
DEBUG_CRASH(("TunnelTracker::onTunnelDestroyed - Attempting to remove object '%s' that has never been tracked as a tunnel", deadTunnel->getName().str()));
return;
}

m_tunnelCount--;
m_tunnelIDs.erase(it);
m_needsFullHealTimeUpdate = true;
}

if( m_tunnelCount == 0 )
{
Expand Down
Loading