Skip to content

Commit 6ad992f

Browse files
authored
bugfix(controls): Fix double-press group selection logic not reselecting deselected groups (#1355)
1 parent 4a9bc10 commit 6ad992f

File tree

6 files changed

+54
-4
lines changed

6 files changed

+54
-4
lines changed

Generals/Code/GameEngine/Include/GameClient/InGameUI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ friend class Drawable; // for selection/deselection transactions
445445
virtual Drawable *getFirstSelectedDrawable( void ); ///< get the first selected drawable (if any)
446446
virtual DrawableID getSoloNexusSelectedDrawableID( void ) { return m_soloNexusSelectedDrawableID; } ///< Return the one drawable of the nexus if only 1 angry mob is selected
447447
virtual Bool isDrawableSelected( DrawableID idToCheck ) const; ///< Return true if the selected ID is in the drawable list
448+
virtual Bool areAllObjectsSelected(const std::vector<Object*>& objectsToCheck) const; ///< Return true if all of the selected objects are in the drawable list
448449
virtual Bool isAnySelectedKindOf( KindOfType kindOf ) const; ///< is any selected object a kind of
449450
virtual Bool isAllSelectedKindOf( KindOfType kindOf ) const; ///< are all selected objects a kind of
450451

Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,6 +3335,21 @@ Bool InGameUI::isDrawableSelected( DrawableID idToCheck ) const
33353335

33363336
} // end isDrawableSelected
33373337

3338+
//-------------------------------------------------------------------------------------------------
3339+
/** Return true if all of the given objects are selected */
3340+
//-------------------------------------------------------------------------------------------------
3341+
Bool InGameUI::areAllObjectsSelected(const std::vector<Object*>& objectsToCheck) const
3342+
{
3343+
for (std::vector<Object*>::const_iterator it = objectsToCheck.begin(); it != objectsToCheck.end(); ++it)
3344+
{
3345+
if (!(*it)->getDrawable()->isSelected())
3346+
return FALSE;
3347+
}
3348+
3349+
return TRUE;
3350+
3351+
} // end areAllObjectsSelected
3352+
33383353
// ------------------------------------------------------------------------------------------------
33393354
// ------------------------------------------------------------------------------------------------
33403355
Bool InGameUI::isAnySelectedKindOf( KindOfType kindOf ) const

Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
962962
if (! TheGlobalData->m_useAlternateMouse || TheInGameUI->getPendingPlaceSourceObjectID() != INVALID_ID)
963963
{
964964
deselectAll();
965+
m_lastGroupSelGroup = -1;
965966
}
966967
}
967968
}
@@ -1024,10 +1025,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
10241025
m_lastGroupSelTime = now;
10251026
}
10261027

1028+
Bool performSelection = TRUE;
1029+
10271030
// check for double-press to jump view
10281031
if ( now - m_lastGroupSelTime < 20 && group == m_lastGroupSelGroup )
10291032
{
10301033
DEBUG_LOG(("META: DOUBLETAP select team %d",group));
1034+
// TheSuperHackers @bugfix Stubbjax 26/05/2025 Perform selection on double-press
1035+
// if the group or part of it is somehow deselected between presses.
1036+
performSelection = FALSE;
10311037
Player *player = ThePlayerList->getLocalPlayer();
10321038
if (player)
10331039
{
@@ -1039,12 +1045,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
10391045
if (numObjs > 0)
10401046
{
10411047
// if theres someone in the group, center the camera on them.
1042-
TheTacticalView->lookAt( objlist[numObjs-1]->getDrawable()->getPosition() );
1048+
Drawable* drawable = objlist[numObjs - 1]->getDrawable();
1049+
TheTacticalView->lookAt( drawable->getPosition() );
1050+
performSelection = !TheInGameUI->areAllObjectsSelected( objlist );
10431051
}
10441052
}
10451053
}
10461054
}
1047-
else
1055+
1056+
if ( performSelection )
10481057
{
10491058
TheInGameUI->deselectAllDrawables( false ); //No need to post message because we're just creating a new group!
10501059

GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ friend class Drawable; // for selection/deselection transactions
460460
virtual Drawable *getFirstSelectedDrawable( void ); ///< get the first selected drawable (if any)
461461
virtual DrawableID getSoloNexusSelectedDrawableID( void ) { return m_soloNexusSelectedDrawableID; } ///< Return the one drawable of the nexus if only 1 angry mob is selected
462462
virtual Bool isDrawableSelected( DrawableID idToCheck ) const; ///< Return true if the selected ID is in the drawable list
463+
virtual Bool areAllObjectsSelected(const std::vector<Object*>& objectsToCheck) const; ///< Return true if all of the selected objects are in the drawable list
463464
virtual Bool isAnySelectedKindOf( KindOfType kindOf ) const; ///< is any selected object a kind of
464465
virtual Bool isAllSelectedKindOf( KindOfType kindOf ) const; ///< are all selected objects a kind of
465466

GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,21 @@ Bool InGameUI::isDrawableSelected( DrawableID idToCheck ) const
34253425

34263426
} // end isDrawableSelected
34273427

3428+
//-------------------------------------------------------------------------------------------------
3429+
/** Return true if all of the given objects are selected */
3430+
//-------------------------------------------------------------------------------------------------
3431+
Bool InGameUI::areAllObjectsSelected(const std::vector<Object*>& objectsToCheck) const
3432+
{
3433+
for (std::vector<Object*>::const_iterator it = objectsToCheck.begin(); it != objectsToCheck.end(); ++it)
3434+
{
3435+
if (!(*it)->getDrawable()->isSelected())
3436+
return FALSE;
3437+
}
3438+
3439+
return TRUE;
3440+
3441+
} // end areAllObjectsSelected
3442+
34283443
// ------------------------------------------------------------------------------------------------
34293444
// ------------------------------------------------------------------------------------------------
34303445
Bool InGameUI::isAnySelectedKindOf( KindOfType kindOf ) const

GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
954954
if( !TheInGameUI->getPreventLeftClickDeselectionInAlternateMouseModeForOneClick() )
955955
{
956956
deselectAll();
957+
m_lastGroupSelGroup = -1;
957958
}
958959
else
959960
{
@@ -1099,10 +1100,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
10991100
m_lastGroupSelTime = now;
11001101
}
11011102

1103+
Bool performSelection = TRUE;
1104+
11021105
// check for double-press to jump view
11031106
if ( now - m_lastGroupSelTime < 20 && group == m_lastGroupSelGroup )
11041107
{
11051108
DEBUG_LOG(("META: DOUBLETAP select team %d",group));
1109+
// TheSuperHackers @bugfix Stubbjax 26/05/2025 Perform selection on double-press
1110+
// if the group or part of it is somehow deselected between presses.
1111+
performSelection = FALSE;
11061112
Player *player = ThePlayerList->getLocalPlayer();
11071113
if (player)
11081114
{
@@ -1114,12 +1120,15 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
11141120
if (numObjs > 0)
11151121
{
11161122
// if theres someone in the group, center the camera on them.
1117-
TheTacticalView->lookAt( objlist[numObjs-1]->getDrawable()->getPosition() );
1123+
Drawable* drawable = objlist[numObjs - 1]->getDrawable();
1124+
TheTacticalView->lookAt( drawable->getPosition() );
1125+
performSelection = !TheInGameUI->areAllObjectsSelected( objlist );
11181126
}
11191127
}
11201128
}
11211129
}
1122-
else
1130+
1131+
if ( performSelection )
11231132
{
11241133
TheInGameUI->deselectAllDrawables( false ); //No need to post message because we're just creating a new group!
11251134

0 commit comments

Comments
 (0)