diff --git a/Core/GameEngine/Include/GameClient/ControlBar.h b/Core/GameEngine/Include/GameClient/ControlBar.h index 446277a13be..658f997b6b1 100644 --- a/Core/GameEngine/Include/GameClient/ControlBar.h +++ b/Core/GameEngine/Include/GameClient/ControlBar.h @@ -702,6 +702,7 @@ class ControlBar : public SubsystemInterface Bool hasAnyShortcutSelection() const; Bool canShowSpecialPowerShortcut() const; + Bool isApparentControllingPlayerNeutral(const Object* obj) const; void showSpecialPowerShortcut(); void hideSpecialPowerShortcut(); void animateSpecialPowerShortcut( Bool isOn ); @@ -975,6 +976,7 @@ class ControlBar : public SubsystemInterface Color m_buildUpClockColor; Bool m_isObserverCommandBar; ///< If this is true, the command bar behaves greatly different + Bool m_isReadOnly; ///< If this is true, the command bar will not allow any commands to be issued Player *m_observerLookAtPlayer; ///< The current player we're looking at, Null if we're not looking at anyone. Player *m_observedPlayer; ///< The current player we're observing, Null if we're not observing anyone. diff --git a/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index 697ee47a0a4..7ef6b958cee 100644 --- a/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -884,6 +884,7 @@ ControlBar::ControlBar() m_commandSets = nullptr; m_controlBarSchemeManager = nullptr; m_isObserverCommandBar = FALSE; + m_isReadOnly = FALSE; m_observerLookAtPlayer = nullptr; m_observedPlayer = nullptr; m_buildToolTipLayout = nullptr; @@ -1321,6 +1322,7 @@ void ControlBar::reset() m_displayedOCLTimerSeconds = 0; m_isObserverCommandBar = FALSE; // reset us to use a normal command bar + m_isReadOnly = FALSE; m_observerLookAtPlayer = nullptr; m_observedPlayer = nullptr; @@ -1479,6 +1481,26 @@ void ControlBar::update() exitPosition = obj->getObjectExitInterface()->getRallyPoint(); showRallyPoint(exitPosition); + + ContainModuleInterface* observerContain = obj ? obj->getContain() : nullptr; + Bool showObserverInventory = (observerContain != nullptr && observerContain->getContainMax() > 0); + + if (showObserverInventory && m_observerLookAtPlayer == nullptr) + { + if (!isApparentControllingPlayerNeutral(obj)) { + return; + } + + if (m_currContext != CB_CONTEXT_STRUCTURE_INVENTORY || m_currentSelectedDrawable != drawToEvaluateFor) + switchToContext(CB_CONTEXT_STRUCTURE_INVENTORY, drawToEvaluateFor); + else + updateContextStructureInventory(); + } + else if (m_currContext != CB_CONTEXT_OBSERVER_LIST) + { + switchToContext(CB_CONTEXT_OBSERVER_LIST, nullptr); + } + return; } @@ -1805,24 +1827,12 @@ void ControlBar::evaluateContextUI() ContainModuleInterface *contain = obj->getContain(); if( contain && contain->getContainMax() > 0 ) { - - const Player *otherPlayer = contain->getApparentControllingPlayer(ThePlayerList->getLocalPlayer()); - if (!otherPlayer) - otherPlayer = obj->getControllingPlayer(); - Player *player = ThePlayerList->getLocalPlayer(); - - if( !player || !otherPlayer ) - { - //Sanity. - return; - } - Relationship relation = player->getRelationship( otherPlayer->getDefaultTeam() ); - + Bool apparentControllingPlayerNeutral = isApparentControllingPlayerNeutral(obj); //Note: All following checks already account for the fact that this object //isn't ours. //The only case we can actually see a non-controlled controlbar is a neutral garrisonable structure. - if( !contain->isGarrisonable() || relation != NEUTRAL ) + if( !contain->isGarrisonable() || !apparentControllingPlayerNeutral) { //Can't peek inside enemy/allied containers period! return; @@ -2789,6 +2799,7 @@ void ControlBar::setControlBarSchemeByPlayer(Player *p) if( !p->isPlayerActive() ) { m_isObserverCommandBar = TRUE; + m_isReadOnly = TRUE; switchToContext( CB_CONTEXT_OBSERVER_LIST, nullptr ); DEBUG_LOG(("We're loading the Observer Command Bar")); @@ -2803,6 +2814,7 @@ void ControlBar::setControlBarSchemeByPlayer(Player *p) { switchToContext( CB_CONTEXT_NONE, nullptr ); m_isObserverCommandBar = FALSE; + m_isReadOnly = FALSE; if (buttonPlaceBeacon) buttonPlaceBeacon->winHide( @@ -2834,6 +2846,7 @@ void ControlBar::setControlBarSchemeByPlayerTemplate( const PlayerTemplate *pt) if(pt == ThePlayerTemplateStore->findPlayerTemplate(TheNameKeyGenerator->nameToKey("FactionObserver"))) { m_isObserverCommandBar = TRUE; + m_isReadOnly = TRUE; switchToContext( CB_CONTEXT_OBSERVER_LIST, nullptr ); DEBUG_LOG(("We're loading the Observer Command Bar")); @@ -2848,6 +2861,7 @@ void ControlBar::setControlBarSchemeByPlayerTemplate( const PlayerTemplate *pt) { switchToContext( CB_CONTEXT_NONE, nullptr ); m_isObserverCommandBar = FALSE; + m_isReadOnly = FALSE; if (buttonPlaceBeacon) buttonPlaceBeacon->winHide( @@ -3582,6 +3596,25 @@ Bool ControlBar::canShowSpecialPowerShortcut() const return false; } +//------------------------------------------------------------------------------------------------- +Bool ControlBar::isApparentControllingPlayerNeutral(const Object* obj) const +{ + ContainModuleInterface* contain = obj->getContain(); + const Player* otherPlayer = contain->getApparentControllingPlayer(ThePlayerList->getLocalPlayer()); + if (!otherPlayer) + otherPlayer = obj->getControllingPlayer(); + const Player* player = ThePlayerList->getLocalPlayer(); + + if (!player || !otherPlayer) + { + //Sanity. + return FALSE; + } + + Relationship relation = player->getRelationship(otherPlayer->getDefaultTeam()); + return relation == NEUTRAL; +} + //------------------------------------------------------------------------------------------------- void ControlBar::updateSpecialPowerShortcut() { diff --git a/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarStructureInventory.cpp b/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarStructureInventory.cpp index 0bde39bc6f4..ebbbf7d7702 100644 --- a/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarStructureInventory.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarStructureInventory.cpp @@ -83,7 +83,7 @@ void ControlBar::populateButtonProc( Object *obj, void *userData ) GadgetButtonDrawOverlayImage( info->inventoryButtons[ info->buttonIndex ], image ); // Enable the button - info->inventoryButtons[ info->buttonIndex ]->winEnable( TRUE ); + info->inventoryButtons[ info->buttonIndex ]->winEnable( !info->self->m_isReadOnly ); // move to the next button index info->buttonIndex++; @@ -170,7 +170,7 @@ void ControlBar::populateStructureInventory( Object *building ) m_commandWindows[ STOP_ID ]->winHide( FALSE ); // if there is at least one item in there enable the evacuate and stop buttons - if( contain->getContainCount() != 0 ) + if(!m_isReadOnly && contain->getContainCount() != 0 ) { m_commandWindows[ EVACUATE_ID ]->winEnable( TRUE ); m_commandWindows[ STOP_ID ]->winEnable( TRUE );