diff --git a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h index e73afdd6bf6..6d561254097 100644 --- a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h @@ -440,6 +440,7 @@ friend class Drawable; // for selection/deselection transactions virtual Drawable *getFirstSelectedDrawable( void ); ///< get the first selected drawable (if any) virtual DrawableID getSoloNexusSelectedDrawableID( void ) { return m_soloNexusSelectedDrawableID; } ///< Return the one drawable of the nexus if only 1 angry mob is selected virtual Bool isDrawableSelected( DrawableID idToCheck ) const; ///< Return true if the selected ID is in the drawable list + virtual Bool areAllObjectsSelected(const std::vector& objectsToCheck) const; ///< Return true if all of the selected objects are in the drawable list virtual Bool isAnySelectedKindOf( KindOfType kindOf ) const; ///< is any selected object a kind of virtual Bool isAllSelectedKindOf( KindOfType kindOf ) const; ///< are all selected objects a kind of diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 69bd81e08b0..0b388722c53 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -3335,6 +3335,21 @@ Bool InGameUI::isDrawableSelected( DrawableID idToCheck ) const } // end isDrawableSelected +//------------------------------------------------------------------------------------------------- +/** Return true if all of the given objects are selected */ +//------------------------------------------------------------------------------------------------- +Bool InGameUI::areAllObjectsSelected(const std::vector& objectsToCheck) const +{ + for (std::vector::const_iterator it = objectsToCheck.begin(); it != objectsToCheck.end(); ++it) + { + if (!(*it)->getDrawable()->isSelected()) + return FALSE; + } + + return TRUE; + +} // end areAllObjectsSelected + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ Bool InGameUI::isAnySelectedKindOf( KindOfType kindOf ) const diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index 9998b745227..2a0b7486449 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -962,6 +962,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if (! TheGlobalData->m_useAlternateMouse || TheInGameUI->getPendingPlaceSourceObjectID() != INVALID_ID) { deselectAll(); + m_lastGroupSelGroup = -1; } } } @@ -1024,10 +1025,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa m_lastGroupSelTime = now; } + Bool performSelection = TRUE; + // check for double-press to jump view if ( now - m_lastGroupSelTime < 20 && group == m_lastGroupSelGroup ) { DEBUG_LOG(("META: DOUBLETAP select team %d",group)); + // TheSuperHackers @bugfix Stubbjax 26/05/2025 Perform selection on double-press + // if the group or part of it is somehow deselected between presses. + performSelection = FALSE; Player *player = ThePlayerList->getLocalPlayer(); if (player) { @@ -1039,12 +1045,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if (numObjs > 0) { // if theres someone in the group, center the camera on them. - TheTacticalView->lookAt( objlist[numObjs-1]->getDrawable()->getPosition() ); + Drawable* drawable = objlist[numObjs - 1]->getDrawable(); + TheTacticalView->lookAt( drawable->getPosition() ); + performSelection = !TheInGameUI->areAllObjectsSelected( objlist ); } } } } - else + + if ( performSelection ) { TheInGameUI->deselectAllDrawables( false ); //No need to post message because we're just creating a new group! diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h b/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h index 2f3be01188f..45cff3a473e 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h @@ -455,6 +455,7 @@ friend class Drawable; // for selection/deselection transactions virtual Drawable *getFirstSelectedDrawable( void ); ///< get the first selected drawable (if any) virtual DrawableID getSoloNexusSelectedDrawableID( void ) { return m_soloNexusSelectedDrawableID; } ///< Return the one drawable of the nexus if only 1 angry mob is selected virtual Bool isDrawableSelected( DrawableID idToCheck ) const; ///< Return true if the selected ID is in the drawable list + virtual Bool areAllObjectsSelected(const std::vector& objectsToCheck) const; ///< Return true if all of the selected objects are in the drawable list virtual Bool isAnySelectedKindOf( KindOfType kindOf ) const; ///< is any selected object a kind of virtual Bool isAllSelectedKindOf( KindOfType kindOf ) const; ///< are all selected objects a kind of diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 6ba4f777d5f..d2e62e551d6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -3425,6 +3425,21 @@ Bool InGameUI::isDrawableSelected( DrawableID idToCheck ) const } // end isDrawableSelected +//------------------------------------------------------------------------------------------------- +/** Return true if all of the given objects are selected */ +//------------------------------------------------------------------------------------------------- +Bool InGameUI::areAllObjectsSelected(const std::vector& objectsToCheck) const +{ + for (std::vector::const_iterator it = objectsToCheck.begin(); it != objectsToCheck.end(); ++it) + { + if (!(*it)->getDrawable()->isSelected()) + return FALSE; + } + + return TRUE; + +} // end areAllObjectsSelected + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ Bool InGameUI::isAnySelectedKindOf( KindOfType kindOf ) const diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index e61b7684f18..e79a16a3f20 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -954,6 +954,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if( !TheInGameUI->getPreventLeftClickDeselectionInAlternateMouseModeForOneClick() ) { deselectAll(); + m_lastGroupSelGroup = -1; } else { @@ -1099,10 +1100,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa m_lastGroupSelTime = now; } + Bool performSelection = TRUE; + // check for double-press to jump view if ( now - m_lastGroupSelTime < 20 && group == m_lastGroupSelGroup ) { DEBUG_LOG(("META: DOUBLETAP select team %d",group)); + // TheSuperHackers @bugfix Stubbjax 26/05/2025 Perform selection on double-press + // if the group or part of it is somehow deselected between presses. + performSelection = FALSE; Player *player = ThePlayerList->getLocalPlayer(); if (player) { @@ -1114,12 +1120,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa if (numObjs > 0) { // if theres someone in the group, center the camera on them. - TheTacticalView->lookAt( objlist[numObjs-1]->getDrawable()->getPosition() ); + Drawable* drawable = objlist[numObjs - 1]->getDrawable(); + TheTacticalView->lookAt( drawable->getPosition() ); + performSelection = !TheInGameUI->areAllObjectsSelected( objlist ); } } } } - else + + if ( performSelection ) { TheInGameUI->deselectAllDrawables( false ); //No need to post message because we're just creating a new group!