From 1b36e51e7f496cd7d437079184f70d4b82b4ff48 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sat, 15 Nov 2025 18:32:21 +1100 Subject: [PATCH 1/7] refactor: Use new utility logic for handling observed player behaviour --- .../Code/GameEngine/Source/GameClient/Drawable.cpp | 8 ++++---- Generals/Code/GameEngine/Source/GameClient/Eva.cpp | 3 ++- .../Code/GameEngine/Source/GameClient/InGameUI.cpp | 13 +++++-------- .../Source/GameClient/MessageStream/CommandXlat.cpp | 8 ++++---- .../W3DDevice/GameClient/W3dWaypointBuffer.cpp | 3 ++- .../Code/GameEngine/Source/GameClient/Drawable.cpp | 8 ++++---- .../Code/GameEngine/Source/GameClient/Eva.cpp | 3 ++- .../Code/GameEngine/Source/GameClient/InGameUI.cpp | 13 +++++-------- .../Source/GameClient/MessageStream/CommandXlat.cpp | 8 ++++---- .../W3DDevice/GameClient/W3dWaypointBuffer.cpp | 3 ++- 10 files changed, 34 insertions(+), 36 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp index eb1aadc85df..cba6fb5adb4 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -2273,7 +2273,7 @@ Bool Drawable::drawsAnyUIText( void ) return FALSE; const Object *obj = getObject(); - if ( !obj || obj->getControllingPlayer() != TheControlBar->getCurrentlyViewedPlayer()) + if ( !obj || obj->getControllingPlayer() != rts::getObservedOrLocalPlayer()) return FALSE; Player *owner = obj->getControllingPlayer(); @@ -2422,7 +2422,7 @@ void Drawable::drawAmmo( const IRegion2D *healthBarRegion ) if (!( TheGlobalData->m_showObjectHealth && (isSelected() || (TheInGameUI && (TheInGameUI->getMousedOverDrawableID() == getID()))) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer() + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() )) return; @@ -2480,7 +2480,7 @@ void Drawable::drawContained( const IRegion2D *healthBarRegion ) if (!( TheGlobalData->m_showObjectHealth && (isSelected() || (TheInGameUI && (TheInGameUI->getMousedOverDrawableID() == getID()))) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer() + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() )) return; @@ -2953,7 +2953,7 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion) UnsignedInt now = TheGameLogic->getFrame(); if( obj->testWeaponSetFlag( WEAPONSET_CARBOMB ) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer()) + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer()) { if( !getIconInfo()->m_icon[ ICON_CARBOMB ] ) getIconInfo()->m_icon[ ICON_CARBOMB ] = newInstance(Anim2D)( s_animationTemplates[ ICON_CARBOMB ], TheAnim2DCollection ); diff --git a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp index caa2a740133..b7bf148f0aa 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp @@ -28,6 +28,7 @@ #include "GameClient/ControlBar.h" #include "GameClient/Eva.h" +#include "Common/GameUtility.h" #include "Common/Player.h" #include "Common/PlayerList.h" #include "GameLogic/GameLogic.h" @@ -212,7 +213,7 @@ void Eva::update() return; } - m_localPlayer = TheControlBar->getCurrentlyViewedPlayer(); + m_localPlayer = rts::getObservedOrLocalPlayer(); UnsignedInt frame = TheGameLogic->getFrame(); // Don't update for the first few frames. This way, we don't have to deal with our initial power diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index bd9b5c51aa3..628c4be04e6 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5563,10 +5563,10 @@ void InGameUI::removeIdleWorker( Object *obj, Int playerNumber ) void InGameUI::selectNextIdleWorker( void ) { - Int index = TheControlBar->getCurrentlyViewedPlayer()->getPlayerIndex(); + Int index = rts::getObservedOrLocalPlayer()->getPlayerIndex(); if(m_idleWorkers[index].empty()) { - DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getLocalPlayer()->getPlayerDisplayName().str())); + DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); return; return; } Object *selectThisObject = NULL; @@ -5653,13 +5653,10 @@ ObjectPtrVector InGameUI::getUniqueIdleWorkers(const ObjectList& idleWorkers) Int InGameUI::getIdleWorkerCount( void ) { - if (Player* player = TheControlBar->getCurrentlyViewedPlayer()) - { - Int index = player->getPlayerIndex(); - return m_idleWorkers[index].size(); - } + Player* player = rts::getObservedOrLocalPlayer(); - return 0; + Int index = player->getPlayerIndex(); + return m_idleWorkers[index].size(); } void InGameUI::showIdleWorkerLayout( void ) diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index f71498c242a..f6130c6e9dd 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -886,8 +886,8 @@ void findCommandCenterOrMostExpensiveBuilding(Object* obj, void* vccl) static void viewCommandCenter( void ) { - Player* localPlayer = TheControlBar->getCurrentlyViewedPlayer(); - if (!localPlayer) + Player* localPlayer = rts::getObservedOrLocalPlayer(); + if (!localPlayer->isPlayerActive()) return; CommandCenterLocator ccl; @@ -928,8 +928,8 @@ void amIAHero(Object* obj, void* heroHolder) static Object *iNeedAHero( void ) { - Player* localPlayer = TheControlBar->getCurrentlyViewedPlayer(); - if (!localPlayer) + Player* localPlayer = rts::getObservedOrLocalPlayer(); + if (!localPlayer->isPlayerActive()) return NULL; HeroHolder heroHolder; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp index e6cfb5bf726..01e42c7e6e2 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp @@ -56,6 +56,7 @@ #include #include +#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/RandomValue.h" #include "Common/ThingFactory.h" @@ -223,7 +224,7 @@ void W3DWaypointBuffer::drawWaypoints(RenderInfoClass &rinfo) Int numPoints = 0; if( obj ) { - if ( obj->getControllingPlayer() != TheControlBar->getCurrentlyViewedPlayer()) + if ( obj->getControllingPlayer() != rts::getObservedOrLocalPlayer()) continue; ExitInterface *exitInterface = obj->getObjectExitInterface(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp index be5d3cb1fc7..e96a787c517 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -2718,7 +2718,7 @@ Bool Drawable::drawsAnyUIText( void ) return FALSE; const Object *obj = getObject(); - if ( !obj || obj->getControllingPlayer() != TheControlBar->getCurrentlyViewedPlayer()) + if ( !obj || obj->getControllingPlayer() != rts::getObservedOrLocalPlayer()) return FALSE; Player *owner = obj->getControllingPlayer(); @@ -2871,7 +2871,7 @@ void Drawable::drawAmmo( const IRegion2D *healthBarRegion ) if (!( TheGlobalData->m_showObjectHealth && (isSelected() || (TheInGameUI && (TheInGameUI->getMousedOverDrawableID() == getID()))) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer() + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() )) return; @@ -2929,7 +2929,7 @@ void Drawable::drawContained( const IRegion2D *healthBarRegion ) if (!( TheGlobalData->m_showObjectHealth && (isSelected() || (TheInGameUI && (TheInGameUI->getMousedOverDrawableID() == getID()))) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer() + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() )) return; @@ -3447,7 +3447,7 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion) UnsignedInt now = TheGameLogic->getFrame(); if( obj->testWeaponSetFlag( WEAPONSET_CARBOMB ) && - obj->getControllingPlayer() == TheControlBar->getCurrentlyViewedPlayer()) + obj->getControllingPlayer() == rts::getObservedOrLocalPlayer()) { if( !getIconInfo()->m_icon[ ICON_CARBOMB ] ) getIconInfo()->m_icon[ ICON_CARBOMB ] = newInstance(Anim2D)( s_animationTemplates[ ICON_CARBOMB ], TheAnim2DCollection ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp index 7e6391fef76..990f678c1c1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp @@ -28,6 +28,7 @@ #include "GameClient/ControlBar.h" #include "GameClient/Eva.h" +#include "Common/GameUtility.h" #include "Common/Player.h" #include "Common/PlayerList.h" #include "GameLogic/GameLogic.h" @@ -284,7 +285,7 @@ void Eva::update() return; } - m_localPlayer = TheControlBar->getCurrentlyViewedPlayer(); + m_localPlayer = rts::getObservedOrLocalPlayer(); UnsignedInt frame = TheGameLogic->getFrame(); // Don't update for the first few frames. This way, we don't have to deal with our initial power diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index ed8d6e0cc2f..439510054fb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5736,10 +5736,10 @@ void InGameUI::removeIdleWorker( Object *obj, Int playerNumber ) void InGameUI::selectNextIdleWorker( void ) { - Int index = TheControlBar->getCurrentlyViewedPlayer()->getPlayerIndex(); + Int index = rts::getObservedOrLocalPlayer()->getPlayerIndex(); if(m_idleWorkers[index].empty()) { - DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getLocalPlayer()->getPlayerDisplayName().str())); + DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); return; } Object *selectThisObject = NULL; @@ -5826,13 +5826,10 @@ ObjectPtrVector InGameUI::getUniqueIdleWorkers(const ObjectList& idleWorkers) Int InGameUI::getIdleWorkerCount( void ) { - if (Player* player = TheControlBar->getCurrentlyViewedPlayer()) - { - Int index = player->getPlayerIndex(); - return m_idleWorkers[index].size(); - } + Player* player = rts::getObservedOrLocalPlayer(); - return 0; + Int index = player->getPlayerIndex(); + return m_idleWorkers[index].size(); } void InGameUI::showIdleWorkerLayout( void ) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index 633474ef7f3..15df18fc367 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -944,8 +944,8 @@ void findCommandCenterOrMostExpensiveBuilding(Object* obj, void* vccl) static void viewCommandCenter( void ) { - Player* localPlayer = TheControlBar->getCurrentlyViewedPlayer(); - if (!localPlayer) + Player* localPlayer = rts::getObservedOrLocalPlayer(); + if (!localPlayer->isPlayerActive()) return; CommandCenterLocator ccl; @@ -986,8 +986,8 @@ void amIAHero(Object* obj, void* heroHolder) static Object *iNeedAHero( void ) { - Player* localPlayer = TheControlBar->getCurrentlyViewedPlayer(); - if (!localPlayer) + Player* localPlayer = rts::getObservedOrLocalPlayer(); + if (!localPlayer->isPlayerActive()) return NULL; HeroHolder heroHolder; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp index 3c531c5fc66..6c073b501d6 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp @@ -56,6 +56,7 @@ #include #include +#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/RandomValue.h" #include "Common/ThingFactory.h" @@ -230,7 +231,7 @@ void W3DWaypointBuffer::drawWaypoints(RenderInfoClass &rinfo) Int numPoints = 0; if( obj ) { - if ( obj->getControllingPlayer() != TheControlBar->getCurrentlyViewedPlayer()) + if ( obj->getControllingPlayer() != rts::getObservedOrLocalPlayer()) continue; From 0d13c7fe8bb221cccc07049e674d4e4244f2c5e4 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 18 Nov 2025 14:00:48 +1100 Subject: [PATCH 2/7] fix: Remove excess return caused by copy / paste funk --- Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 628c4be04e6..94375d286ef 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5566,7 +5566,7 @@ void InGameUI::selectNextIdleWorker( void ) Int index = rts::getObservedOrLocalPlayer()->getPlayerIndex(); if(m_idleWorkers[index].empty()) { - DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); return; + DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); return; } Object *selectThisObject = NULL; From 969064b422daa6dd4f374cadb37e7704789cbc1f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 18 Nov 2025 14:03:40 +1100 Subject: [PATCH 3/7] refactor: Simplify player acquisition logic --- Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp | 6 ++++-- GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 94375d286ef..54a9fb3956d 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5563,10 +5563,12 @@ void InGameUI::removeIdleWorker( Object *obj, Int playerNumber ) void InGameUI::selectNextIdleWorker( void ) { - Int index = rts::getObservedOrLocalPlayer()->getPlayerIndex(); + Player* player = rts::getObservedOrLocalPlayer(); + Int index = player->getPlayerIndex(); + if(m_idleWorkers[index].empty()) { - DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); + DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", player->getPlayerDisplayName().str())); return; } Object *selectThisObject = NULL; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 439510054fb..c7403418e48 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5736,10 +5736,12 @@ void InGameUI::removeIdleWorker( Object *obj, Int playerNumber ) void InGameUI::selectNextIdleWorker( void ) { - Int index = rts::getObservedOrLocalPlayer()->getPlayerIndex(); + Player* player = rts::getObservedOrLocalPlayer(); + Int index = player->getPlayerIndex(); + if(m_idleWorkers[index].empty()) { - DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", ThePlayerList->getNthPlayer(index)->getPlayerDisplayName().str())); + DEBUG_ASSERTCRASH(FALSE, ("InGameUI::selectNextIdleWorker We're trying to select a worker when our list is empty for player %ls", player->getPlayerDisplayName().str())); return; } Object *selectThisObject = NULL; From 9dfa94917aa05b0325547941211373981461e6ef Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 18 Nov 2025 19:53:45 +1100 Subject: [PATCH 4/7] tweak: Update more events --- .../GameClient/GUI/ControlBar/ControlBar.cpp | 17 ++++++++--------- .../GUICallbacks/ControlBarPopupDescription.cpp | 5 +++-- .../GameClient/GUI/ControlBar/ControlBar.cpp | 17 ++++++++--------- .../GUICallbacks/ControlBarPopupDescription.cpp | 5 +++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index b85f42dc612..df640b22362 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -37,6 +37,7 @@ #include "Common/ActionManager.h" #include "Common/GameType.h" +#include "Common/GameUtility.h" #include "Common/MultiplayerSettings.h" #include "Common/NameKeyGenerator.h" #include "Common/Override.h" @@ -1454,7 +1455,7 @@ void ControlBar::update( void ) setPortraitByObject(obj); const Coord3D* exitPosition = NULL; - if (obj && obj->getControllingPlayer() == getCurrentlyViewedPlayer() && obj->getObjectExitInterface()) + if (obj && obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() && obj->getObjectExitInterface()) exitPosition = obj->getObjectExitInterface()->getRallyPoint(); showRallyPoint(exitPosition); @@ -2732,14 +2733,12 @@ void ControlBar::showRallyPoint(const Coord3D* loc) marker->setOrientation(TheGlobalData->m_downwindAngle); // To blow down wind -- ML // set the marker colors to that of the local player - Player* player = TheControlBar->getCurrentlyViewedPlayer(); - if (player) - { - if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) - marker->setIndicatorColor(player->getPlayerNightColor()); - else - marker->setIndicatorColor(player->getPlayerColor()); - } + Player* player = rts::getObservedOrLocalPlayer(); + + if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) + marker->setIndicatorColor(player->getPlayerNightColor()); + else + marker->setIndicatorColor(player->getPlayerColor()); } // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp index 55fbfd98fff..232e9d21523 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp @@ -67,6 +67,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/BuildAssistant.h" #include "Common/Player.h" @@ -518,9 +519,9 @@ void ControlBar::populateBuildTooltipLayout( const CommandButton *commandButton, name = TheGameText->fetch("CONTROLBAR:Power"); descrip = TheGameText->fetch("CONTROLBAR:PowerDescription"); - Player* playerToDisplay = TheControlBar->getCurrentlyViewedPlayer(); + Player* playerToDisplay = rts::getObservedOrLocalPlayer(); - if( playerToDisplay && playerToDisplay->getEnergy() ) + if( playerToDisplay->getEnergy() ) { Energy *energy = playerToDisplay->getEnergy(); descrip.format(descrip, energy->getProduction(), energy->getConsumption()); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index c357ad30c36..2a0fd213a23 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -37,6 +37,7 @@ #include "Common/ActionManager.h" #include "Common/GameType.h" +#include "Common/GameUtility.h" #include "Common/MultiplayerSettings.h" #include "Common/NameKeyGenerator.h" #include "Common/Override.h" @@ -1477,7 +1478,7 @@ void ControlBar::update( void ) setPortraitByObject(obj); const Coord3D* exitPosition = NULL; - if (obj && obj->getControllingPlayer() == getCurrentlyViewedPlayer() && obj->getObjectExitInterface()) + if (obj && obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() && obj->getObjectExitInterface()) exitPosition = obj->getObjectExitInterface()->getRallyPoint(); showRallyPoint(exitPosition); @@ -2755,14 +2756,12 @@ void ControlBar::showRallyPoint(const Coord3D* loc) marker->setOrientation(TheGlobalData->m_downwindAngle); // To blow down wind -- ML // set the marker colors to that of the local player - Player* player = TheControlBar->getCurrentlyViewedPlayer(); - if (player) - { - if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) - marker->setIndicatorColor(player->getPlayerNightColor()); - else - marker->setIndicatorColor(player->getPlayerColor()); - } + Player* player = rts::getObservedOrLocalPlayer(); + + if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) + marker->setIndicatorColor(player->getPlayerNightColor()); + else + marker->setIndicatorColor(player->getPlayerColor()); } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp index 2803730c0ac..6f330852e26 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp @@ -67,6 +67,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/BuildAssistant.h" #include "Common/Player.h" @@ -567,9 +568,9 @@ void ControlBar::populateBuildTooltipLayout( const CommandButton *commandButton, name = TheGameText->fetch("CONTROLBAR:Power"); descrip = TheGameText->fetch("CONTROLBAR:PowerDescription"); - Player* playerToDisplay = TheControlBar->getCurrentlyViewedPlayer(); + Player* playerToDisplay = rts::getObservedOrLocalPlayer(); - if( playerToDisplay && playerToDisplay->getEnergy() ) + if( playerToDisplay->getEnergy() ) { Energy *energy = playerToDisplay->getEnergy(); descrip.format(descrip, energy->getProduction(), energy->getConsumption()); From 20dccf7bf66a6ad2f1e874237087021dd5007848 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 18 Nov 2025 19:58:23 +1100 Subject: [PATCH 5/7] refactor: Supersede viewed player side with the new utility logic --- Generals/Code/GameEngine/Include/GameClient/ControlBar.h | 2 -- Generals/Code/GameEngine/Source/GameClient/Eva.cpp | 2 +- .../Source/GameClient/GUI/ControlBar/ControlBar.cpp | 8 -------- .../Code/GameEngine/Include/GameClient/ControlBar.h | 2 -- GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp | 2 +- .../Source/GameClient/GUI/ControlBar/ControlBar.cpp | 8 -------- 6 files changed, 2 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/ControlBar.h b/Generals/Code/GameEngine/Include/GameClient/ControlBar.h index c8b686550b9..2a0cf0823dc 100644 --- a/Generals/Code/GameEngine/Include/GameClient/ControlBar.h +++ b/Generals/Code/GameEngine/Include/GameClient/ControlBar.h @@ -734,8 +734,6 @@ class ControlBar : public SubsystemInterface Player* getCurrentlyViewedPlayer(); /// Returns the relationship with the currently viewed player. May return NEUTRAL if no player is selected while observing. Relationship getCurrentlyViewedPlayerRelationship(const Team* team); - /// Returns the currently viewed player. Returns "Observer" if no player is selected while observing. - AsciiString getCurrentlyViewedPlayerSide(); // ControlBarResizer *getControlBarResizer( void ) {return m_controlBarResizer;} diff --git a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp index b7bf148f0aa..da880e3c54e 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp @@ -430,7 +430,7 @@ void Eva::processPlayingMessages(UnsignedInt currentFrame) } // We've got a winner! - AsciiString side = TheControlBar->getCurrentlyViewedPlayerSide(); + AsciiString side = rts::getObservedOrLocalPlayer()->getSide(); Int numSides = storedIt->m_evaInfo->m_evaSideSounds.size(); for (Int i = 0; i < numSides; ++i) { diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index df640b22362..43f3d467ba9 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -174,14 +174,6 @@ Relationship ControlBar::getCurrentlyViewedPlayerRelationship(const Team* team) return NEUTRAL; } -AsciiString ControlBar::getCurrentlyViewedPlayerSide() -{ - if (Player* player = getCurrentlyViewedPlayer()) - player->getSide(); - - return ThePlayerList->getLocalPlayer()->getSide(); -} - void ControlBar::populatePurchaseScience( Player* player ) { // TheInGameUI->deselectAllDrawables(); diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/ControlBar.h b/GeneralsMD/Code/GameEngine/Include/GameClient/ControlBar.h index e15b68975c0..3c4b3885002 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/ControlBar.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/ControlBar.h @@ -748,8 +748,6 @@ class ControlBar : public SubsystemInterface Player* getCurrentlyViewedPlayer(); /// Returns the relationship with the currently viewed player. May return NEUTRAL if no player is selected while observing. Relationship getCurrentlyViewedPlayerRelationship(const Team* team); - /// Returns the currently viewed player. Returns "Observer" if no player is selected while observing. - AsciiString getCurrentlyViewedPlayerSide(); // ControlBarResizer *getControlBarResizer( void ) {return m_controlBarResizer;} diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp index 990f678c1c1..bb5d863ed56 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Eva.cpp @@ -504,7 +504,7 @@ void Eva::processPlayingMessages(UnsignedInt currentFrame) } // We've got a winner! - AsciiString side = TheControlBar->getCurrentlyViewedPlayerSide(); + AsciiString side = rts::getObservedOrLocalPlayer()->getSide(); Int numSides = storedIt->m_evaInfo->m_evaSideSounds.size(); // clear it. If we can't find the side we want, don't play anything diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index 2a0fd213a23..a0e9f273f1e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -175,14 +175,6 @@ Relationship ControlBar::getCurrentlyViewedPlayerRelationship(const Team* team) return NEUTRAL; } -AsciiString ControlBar::getCurrentlyViewedPlayerSide() -{ - if (Player* player = getCurrentlyViewedPlayer()) - return player->getSide(); - - return ThePlayerList->getLocalPlayer()->getSide(); -} - void ControlBar::populatePurchaseScience( Player* player ) { // TheInGameUI->deselectAllDrawables(); From eb1877678a2447bb9ceeb464c1eb294cf04aad27 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 24 Nov 2025 19:11:22 +1100 Subject: [PATCH 6/7] chore: Remove blank lines --- Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp | 1 - GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 54a9fb3956d..4d0866732f1 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5656,7 +5656,6 @@ ObjectPtrVector InGameUI::getUniqueIdleWorkers(const ObjectList& idleWorkers) Int InGameUI::getIdleWorkerCount( void ) { Player* player = rts::getObservedOrLocalPlayer(); - Int index = player->getPlayerIndex(); return m_idleWorkers[index].size(); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index c7403418e48..0e6e39eea4f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5829,7 +5829,6 @@ ObjectPtrVector InGameUI::getUniqueIdleWorkers(const ObjectList& idleWorkers) Int InGameUI::getIdleWorkerCount( void ) { Player* player = rts::getObservedOrLocalPlayer(); - Int index = player->getPlayerIndex(); return m_idleWorkers[index].size(); } From 9f653572850c5a418361cf83949a1f10edf32204 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 24 Nov 2025 19:13:38 +1100 Subject: [PATCH 7/7] Revert "tweak: Update more events" This reverts commit 9dfa94917aa05b0325547941211373981461e6ef. --- .../GameClient/GUI/ControlBar/ControlBar.cpp | 17 +++++++++-------- .../GUICallbacks/ControlBarPopupDescription.cpp | 5 ++--- .../GameClient/GUI/ControlBar/ControlBar.cpp | 17 +++++++++-------- .../GUICallbacks/ControlBarPopupDescription.cpp | 5 ++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index 43f3d467ba9..2b79ac726bb 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -37,7 +37,6 @@ #include "Common/ActionManager.h" #include "Common/GameType.h" -#include "Common/GameUtility.h" #include "Common/MultiplayerSettings.h" #include "Common/NameKeyGenerator.h" #include "Common/Override.h" @@ -1447,7 +1446,7 @@ void ControlBar::update( void ) setPortraitByObject(obj); const Coord3D* exitPosition = NULL; - if (obj && obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() && obj->getObjectExitInterface()) + if (obj && obj->getControllingPlayer() == getCurrentlyViewedPlayer() && obj->getObjectExitInterface()) exitPosition = obj->getObjectExitInterface()->getRallyPoint(); showRallyPoint(exitPosition); @@ -2725,12 +2724,14 @@ void ControlBar::showRallyPoint(const Coord3D* loc) marker->setOrientation(TheGlobalData->m_downwindAngle); // To blow down wind -- ML // set the marker colors to that of the local player - Player* player = rts::getObservedOrLocalPlayer(); - - if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) - marker->setIndicatorColor(player->getPlayerNightColor()); - else - marker->setIndicatorColor(player->getPlayerColor()); + Player* player = TheControlBar->getCurrentlyViewedPlayer(); + if (player) + { + if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) + marker->setIndicatorColor(player->getPlayerNightColor()); + else + marker->setIndicatorColor(player->getPlayerColor()); + } } // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp index 232e9d21523..55fbfd98fff 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp @@ -67,7 +67,6 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine -#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/BuildAssistant.h" #include "Common/Player.h" @@ -519,9 +518,9 @@ void ControlBar::populateBuildTooltipLayout( const CommandButton *commandButton, name = TheGameText->fetch("CONTROLBAR:Power"); descrip = TheGameText->fetch("CONTROLBAR:PowerDescription"); - Player* playerToDisplay = rts::getObservedOrLocalPlayer(); + Player* playerToDisplay = TheControlBar->getCurrentlyViewedPlayer(); - if( playerToDisplay->getEnergy() ) + if( playerToDisplay && playerToDisplay->getEnergy() ) { Energy *energy = playerToDisplay->getEnergy(); descrip.format(descrip, energy->getProduction(), energy->getConsumption()); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index a0e9f273f1e..9f7d0e10531 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -37,7 +37,6 @@ #include "Common/ActionManager.h" #include "Common/GameType.h" -#include "Common/GameUtility.h" #include "Common/MultiplayerSettings.h" #include "Common/NameKeyGenerator.h" #include "Common/Override.h" @@ -1470,7 +1469,7 @@ void ControlBar::update( void ) setPortraitByObject(obj); const Coord3D* exitPosition = NULL; - if (obj && obj->getControllingPlayer() == rts::getObservedOrLocalPlayer() && obj->getObjectExitInterface()) + if (obj && obj->getControllingPlayer() == getCurrentlyViewedPlayer() && obj->getObjectExitInterface()) exitPosition = obj->getObjectExitInterface()->getRallyPoint(); showRallyPoint(exitPosition); @@ -2748,12 +2747,14 @@ void ControlBar::showRallyPoint(const Coord3D* loc) marker->setOrientation(TheGlobalData->m_downwindAngle); // To blow down wind -- ML // set the marker colors to that of the local player - Player* player = rts::getObservedOrLocalPlayer(); - - if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) - marker->setIndicatorColor(player->getPlayerNightColor()); - else - marker->setIndicatorColor(player->getPlayerColor()); + Player* player = TheControlBar->getCurrentlyViewedPlayer(); + if (player) + { + if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) + marker->setIndicatorColor(player->getPlayerNightColor()); + else + marker->setIndicatorColor(player->getPlayerColor()); + } } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp index 6f330852e26..2803730c0ac 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp @@ -67,7 +67,6 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine -#include "Common/GameUtility.h" #include "Common/GlobalData.h" #include "Common/BuildAssistant.h" #include "Common/Player.h" @@ -568,9 +567,9 @@ void ControlBar::populateBuildTooltipLayout( const CommandButton *commandButton, name = TheGameText->fetch("CONTROLBAR:Power"); descrip = TheGameText->fetch("CONTROLBAR:PowerDescription"); - Player* playerToDisplay = rts::getObservedOrLocalPlayer(); + Player* playerToDisplay = TheControlBar->getCurrentlyViewedPlayer(); - if( playerToDisplay->getEnergy() ) + if( playerToDisplay && playerToDisplay->getEnergy() ) { Energy *energy = playerToDisplay->getEnergy(); descrip.format(descrip, energy->getProduction(), energy->getConsumption());