From fd0f97d20bc50b78e3a06bb05bb9d130d36fab84 Mon Sep 17 00:00:00 2001 From: Bart Roossien Date: Fri, 9 May 2025 21:29:33 +0200 Subject: [PATCH] [GEN] Backport feature to select all aircraft with hotkey (#834) --- .../GameEngine/Include/Common/MessageStream.h | 1 + .../GameEngine/Include/GameClient/InGameUI.h | 17 +- .../Source/Common/MessageStream.cpp | 1 + .../GameEngine/Source/GameClient/InGameUI.cpp | 345 ++++++++++-------- .../GameClient/MessageStream/CommandXlat.cpp | 53 ++- .../GameClient/MessageStream/MetaEvent.cpp | 1 + .../MessageStream/SelectionXlat.cpp | 4 +- 7 files changed, 260 insertions(+), 162 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/MessageStream.h b/Generals/Code/GameEngine/Include/Common/MessageStream.h index 6592d771f1c..e85e51835d4 100644 --- a/Generals/Code/GameEngine/Include/Common/MessageStream.h +++ b/Generals/Code/GameEngine/Include/Common/MessageStream.h @@ -225,6 +225,7 @@ class GameMessage : public MemoryPoolObject MSG_META_VIEW_LAST_RADAR_EVENT, ///< center view on last radar event MSG_META_SELECT_HERO, ///< selects player's hero character, if exists... MSG_META_SELECT_ALL, ///< selects all units across screen + MSG_META_SELECT_ALL_AIRCRAFT, ///< selects all air units just like select all MSG_META_SCATTER, ///< selected units scatter MSG_META_STOP, ///< selected units stop MSG_META_DEPLOY, ///< selected units 'deploy' diff --git a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h index a087d962e48..db6aefd2c48 100644 --- a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h @@ -36,7 +36,9 @@ #include "Common/GameCommon.h" #include "Common/GameType.h" #include "Common/MessageStream.h" // for GameMessageTranslator +#include "Common/KindOf.h" #include "Common/SpecialPowerType.h" +#include "Common/Snapshot.h" #include "Common/STLTypedefs.h" #include "Common/SubsystemInterface.h" #include "Common/UnicodeString.h" @@ -44,7 +46,6 @@ #include "GameClient/Mouse.h" #include "GameClient/RadiusDecal.h" #include "GameClient/View.h" -#include "Common/Snapshot.h" // FORWARD DECLARATIONS /////////////////////////////////////////////////////////////////////////// class Drawable; @@ -482,10 +483,16 @@ friend class Drawable; // for selection/deselection transactions Bool canSelectedObjectsOverrideSpecialPowerDestination( const Coord3D *loc, SelectionRules rule, SpecialPowerType spType = SPECIAL_INVALID ) const; // Selection Methods - virtual Int selectMatchingUnits(); ///< selects matching units - virtual Int selectAcrossScreen(); ///< selects matching units across screen - virtual Int selectAcrossMap(); ///< selects matching units across map - virtual Int selectAcrossRegion( IRegion2D *region ); // -1 = no locally-owned selection, 0+ = # of units selected + virtual Int selectUnitsMatchingCurrentSelection(); ///< selects matching units + virtual Int selectMatchingAcrossScreen(); ///< selects matching units across screen + virtual Int selectMatchingAcrossMap(); ///< selects matching units across map + virtual Int selectMatchingAcrossRegion( IRegion2D *region ); // -1 = no locally-owned selection, 0+ = # of units selected + + virtual Int selectAllUnitsByType(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear); + virtual Int selectAllUnitsByTypeAcrossScreen(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear); + virtual Int selectAllUnitsByTypeAcrossMap(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear); + virtual Int selectAllUnitsByTypeAcrossRegion( IRegion2D *region, KindOfMaskType mustBeSet, KindOfMaskType mustBeClear ); + virtual void buildRegion( const ICoord2D *anchor, const ICoord2D *dest, IRegion2D *region ); ///< builds a region around the specified coordinates virtual Bool getDisplayedMaxWarning( void ) { return m_displayedMaxWarning; } diff --git a/Generals/Code/GameEngine/Source/Common/MessageStream.cpp b/Generals/Code/GameEngine/Source/Common/MessageStream.cpp index 28e226172ba..9920b1e8443 100644 --- a/Generals/Code/GameEngine/Source/Common/MessageStream.cpp +++ b/Generals/Code/GameEngine/Source/Common/MessageStream.cpp @@ -327,6 +327,7 @@ AsciiString GameMessage::getCommandTypeAsAsciiString(GameMessage::Type t) CHECK_IF(MSG_META_VIEW_LAST_RADAR_EVENT) CHECK_IF(MSG_META_SELECT_HERO) CHECK_IF(MSG_META_SELECT_ALL) + CHECK_IF(MSG_META_SELECT_ALL_AIRCRAFT) CHECK_IF(MSG_META_SCATTER) CHECK_IF(MSG_META_STOP) CHECK_IF(MSG_META_DEPLOY) diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 61fa15b2053..4dd505b86a5 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -104,14 +104,63 @@ InGameUI *TheInGameUI = NULL; GameWindow *m_replayWindow = NULL; // ------------------------------------------------------------------------------------------------ -struct TypeSelectionData +struct KindOfSelectionData { - GameMessage *m_message; - const ThingTemplate *m_template; + KindOfMaskType m_mustbeSet; + KindOfMaskType m_mustbeClear; + + DrawableList newlySelectedDrawables; }; +// ------------------------------------------------------------------------------------------------ +static Bool kindOfUnitSelection( Drawable *test, void *userData ) +{ + KindOfSelectionData *data = (KindOfSelectionData *) userData; + + if( test ) + { + const Object *object = test->getObject(); + // Only things with objects can be selected, and the code below isn't + // safe unless you've verified that there is a valid object. + if (!object) + return FALSE; + + Bool isKindOfMatch = object->isKindOfMulti(data->m_mustbeSet, data->m_mustbeClear); + + // only select objects if not already selected + if( object && isKindOfMatch + && object->isLocallyControlled() + && !object->isContained() + && !object->getDrawable()->isSelected() + && !object->isEffectivelyDead() + && object->isMassSelectable() + && !object->isOffMap() + ) + { + // enforce optional unit cap + if (TheInGameUI->getMaxSelectCount() > 0 && TheInGameUI->getSelectCount() >= TheInGameUI->getMaxSelectCount()) + { + if ( !TheInGameUI->getDisplayedMaxWarning() ) + { + TheInGameUI->setDisplayedMaxWarning( TRUE ); + UnicodeString msg; + msg.format(TheGameText->fetch("GUI:MaxSelectionSize").str(), TheInGameUI->getMaxSelectCount()); + TheInGameUI->message(msg); + } + } + else + { + TheInGameUI->selectDrawable( test ); + TheInGameUI->setDisplayedMaxWarning( FALSE ); + data->newlySelectedDrawables.push_back(test); + return TRUE; + } + } + } + return FALSE; +} // ------------------------------------------------------------------------------------------------ -struct SelectionData +struct MatchingUnitSelectionData { const ThingTemplate *templateToSelect; DrawableList newlySelectedDrawables; @@ -120,7 +169,7 @@ struct SelectionData // ------------------------------------------------------------------------------------------------ static Bool similarUnitSelection( Drawable *test, void *userData ) { - SelectionData *data = (SelectionData *) userData; + MatchingUnitSelectionData *data = (MatchingUnitSelectionData *) userData; const ThingTemplate *selectedType = data->templateToSelect; if( test ) @@ -143,6 +192,7 @@ static Bool similarUnitSelection( Drawable *test, void *userData ) && !object->isContained() && !( object->getDrawable()->isSelected() ) && object->isMassSelectable() // And only if they can be multiply selected. (otherwise the drawable will be, but the object will not be) + && !object->isOffMap() ) { // enforce optional unit cap @@ -4408,10 +4458,64 @@ Bool InGameUI::canSelectedObjectsEffectivelyUseWeapon( const CommandButton *comm return false; } +// ------------------------------------------------------------------------------------------------ +Int InGameUI::selectAllUnitsByTypeAcrossRegion( IRegion2D *region, KindOfMaskType mustBeSet, KindOfMaskType mustBeClear ) +{ + KindOfSelectionData data; + Int newSelectionCount = 0; + Int oldSelectionCount = getAllSelectedDrawables()->size(); + + data.m_mustbeSet = mustBeSet; + data.m_mustbeClear = mustBeClear; + + if (region) + { + TheTacticalView->iterateDrawablesInRegion(region, kindOfUnitSelection, (void *)&data); + newSelectionCount += data.newlySelectedDrawables.size(); + } + else + { + // loop over the map + Drawable *temp = TheGameClient->firstDrawable(); + while( temp ) + { + if( kindOfUnitSelection( temp, (void *)&data) ) + { + newSelectionCount ++; + } + + temp = temp->getNextDrawable(); + } + } + setDisplayedMaxWarning( FALSE ); + + if (newSelectionCount > 0) + { + // create selected message + GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP ); + + teamMsg->appendBooleanArgument( (oldSelectionCount == 0) ? TRUE : FALSE ); + + const Drawable *draw; + + //Loop through each drawable add append it's objectID to the event. + for( DrawableListCIt it = data.newlySelectedDrawables.begin(); it != data.newlySelectedDrawables.end(); ++it ) + { + draw = *it; + if( draw && draw->getObject() ) + { + teamMsg->appendObjectIDArgument( draw->getObject()->getID() ); + } + } + } + + return newSelectionCount; +} + // ------------------------------------------------------------------------------------------------ /** Selects maching units on the screen */ // ------------------------------------------------------------------------------------------------ -Int InGameUI::selectAcrossRegion( IRegion2D *region ) +Int InGameUI::selectMatchingAcrossRegion( IRegion2D *region ) { const DrawableList *selected = getAllSelectedDrawables(); @@ -4447,7 +4551,7 @@ Int InGameUI::selectAcrossRegion( IRegion2D *region ) const ThingTemplate *templateName; // now use the list to select across screen - SelectionData data; + MatchingUnitSelectionData data; Int newSelectionCount = 0; for( iter = drawableList.begin(); iter != drawableList.end(); ++iter ) @@ -4494,10 +4598,42 @@ Int InGameUI::selectAcrossRegion( IRegion2D *region ) } +// ------------------------------------------------------------------------------------------------ +Int InGameUI::selectAllUnitsByTypeAcrossScreen(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear) +{ + /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 + + IRegion2D region; + ICoord2D origin; + ICoord2D size; + + TheTacticalView->getOrigin( &origin.x, &origin.y ); + size.x = TheTacticalView->getWidth(); + size.y = TheTacticalView->getHeight(); + + buildRegion( &origin, &size, ®ion ); + + Int numSelected = selectAllUnitsByTypeAcrossRegion(®ion, mustBeSet, mustBeClear); + if (numSelected == -1) + { + UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); + TheInGameUI->message( message ); + } + else if (numSelected == 0) + { + } + else + { + UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossScreen" ); + TheInGameUI->message( message ); + } + return numSelected; +} + // ------------------------------------------------------------------------------------------------ /** Selects maching units on the screen */ // ------------------------------------------------------------------------------------------------ -Int InGameUI::selectAcrossScreen( void ) +Int InGameUI::selectMatchingAcrossScreen( void ) { /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 @@ -4511,7 +4647,7 @@ Int InGameUI::selectAcrossScreen( void ) buildRegion( &origin, &size, ®ion ); - Int numSelected = selectAcrossRegion(®ion); + Int numSelected = selectMatchingAcrossRegion(®ion); if (numSelected == -1) { UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); @@ -4528,13 +4664,40 @@ Int InGameUI::selectAcrossScreen( void ) return numSelected; } +//------------------------------------------------------------------------------------------------- +Int InGameUI::selectAllUnitsByTypeAcrossMap(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear) +{ + /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 + Int numSelected = selectAllUnitsByTypeAcrossRegion(NULL, mustBeSet, mustBeClear); + if (numSelected == -1) + { + UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); + TheInGameUI->message( message ); + } + else if (numSelected == 0) + { + Drawable *draw = TheInGameUI->getFirstSelectedDrawable(); + if( !draw || !draw->getObject() || !draw->getObject()->isKindOf( KINDOF_STRUCTURE ) ) + { + UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossMap" ); + TheInGameUI->message( message ); + } + } + else + { + UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossMap" ); + TheInGameUI->message( message ); + } + return numSelected; +} + //------------------------------------------------------------------------------------------------- /** Selects matching units across map */ //------------------------------------------------------------------------------------------------- -Int InGameUI::selectAcrossMap() +Int InGameUI::selectMatchingAcrossMap() { /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 - Int numSelected = selectAcrossRegion(NULL); + Int numSelected = selectMatchingAcrossRegion(NULL); if (numSelected == -1) { UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); @@ -4557,21 +4720,39 @@ Int InGameUI::selectAcrossMap() return numSelected; } +//------------------------------------------------------------------------------------------------- +Int InGameUI::selectAllUnitsByType(KindOfMaskType mustBeSet, KindOfMaskType mustBeClear) +{ + /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 + Int numSelected = selectAllUnitsByTypeAcrossScreen(mustBeSet, mustBeClear); + if (numSelected == -1) + { + return numSelected; + } + + if (numSelected == 0) + { + Int numSelectedAcrossMap = selectAllUnitsByTypeAcrossMap(mustBeSet, mustBeClear); + return numSelectedAcrossMap; + } + return numSelected; +} + //------------------------------------------------------------------------------------------------- /** Selects matching units, either on screen or across map. When called by pressing 'T', their is not a way to tell if the game is supposed to select across the screen, or across the map. For mouse clicks, i.e. Alt + click or double click, we can directly call - selectAcrossScreen or selectAcrossMap */ + selectMatchingAcrossScreen or selectMatchingAcrossMap */ //------------------------------------------------------------------------------------------------- -Int InGameUI::selectMatchingUnits() +Int InGameUI::selectUnitsMatchingCurrentSelection() { /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 - Int numSelected = selectAcrossScreen(); + Int numSelected = selectMatchingAcrossScreen(); if (numSelected == -1) return numSelected; if (numSelected == 0) { - Int numSelectedAcrossMap = selectAcrossMap(); + Int numSelectedAcrossMap = selectMatchingAcrossMap(); //if (numSelectedAcrossMap < 1) //{ //UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); @@ -4581,140 +4762,6 @@ Int InGameUI::selectMatchingUnits() } return numSelected; - /* - /// When implementing this, obey TheInGameUI->getMaxSelectCount() if it is > 0 - - // check to see if you select units across screen or across map - - IRegion2D region; - ICoord2D origin; - ICoord2D size; - - TheTacticalView->getOrigin( &origin.x, &origin.y ); - size.x = TheTacticalView->getWidth(); - size.y = TheTacticalView->getHeight(); - - // setup the region and to the iterate function - - buildRegion( &origin, &size, ®ion ); - - const DrawableList *selected = getAllSelectedDrawables(); - - Drawable *draw; - - std::set drawableList; - - // get a set of the selected types of object - for( DrawableListCIt it = selected->begin(); it != selected->end(); ++it ) - { - // get this drawable - draw = *it; - if( draw && draw->getObject() && draw->getObject()->isLocallyControlled() ) - { - - - //drawableList.insert( draw->getObject()->getTemplate()->getName() ); - drawableList.insert( draw->getTemplate() ); - } - } - - std::set::const_iterator iter; - - const ThingTemplate *templateName; - TypeSelectionData data; - data.m_message = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP ); - - // go though the drawableList and get the units of that type - for( iter = drawableList.begin(); iter != drawableList.end(); ++iter ) - { - // get this drawable - data.m_template = *iter; - //iterate through the drawable region - // all drawables in the region will call the typeSelection method - m_selectedAcrossScreen = TheTacticalView->iterateDrawablesInRegion( ®ion, InGameUI::typeSelection, (void *) &data); - setDisplayedMaxWarning( FALSE ); - } - - if( m_selectedAcrossScreen ) - { - UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossScreen" ); - TheInGameUI->message( message ); - setSelectedAcrossScreen( false ); - } - else - { - // add to existing group - GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP ); - - // adding to previous group so pass false - teamMsg->appendBooleanArgument( FALSE ); - - selected = getAllSelectedDrawables(); - // loop through all the selected drawables - Drawable *draw; - - //see if player has any units selected, if not, give message - Bool check = FALSE; - for( DrawableListCIt it1 = selected->begin(); it1 != selected->end(); ++it1 ) - { - draw = *it1; - if( draw && draw->getObject()->isLocallyControlled() ) - { - check = TRUE; - } - } - if( check == FALSE ) - { - UnicodeString message = TheGameText->fetch( "GUI:NothingSelected" ); - TheInGameUI->message( message ); - setSelectedAcrossScreen( false ); - deselectAllDrawables(); - return; - } - - //else select across the map - - for( iter = drawableList.begin(); iter != drawableList.end(); ++iter ) - { - // get this drawable - templateName = *iter; - Drawable *temp = TheGameClient->firstDrawable(); - while( temp ) - { - const Object *object = temp->getObject(); - - if( object && object->isLocallyControlled() - && !object->isContained() && temp->getTemplate()->isEquivalentTo( templateName ) ) - { - - // enforce optional unit cap - if ( getMaxSelectCount() > 0 && TheInGameUI->getSelectCount() >= getMaxSelectCount()) - { - if ( !getDisplayedMaxWarning() ) - { - setDisplayedMaxWarning( TRUE ); - UnicodeString msg; - msg.format(TheGameText->fetch("GUI:MaxSelectionSize").str(), TheInGameUI->getMaxSelectCount()); - message(msg); - } - } - else - { - selectDrawable( temp ); - teamMsg->appendObjectIDArgument( temp->getObject()->getID() ); - setDisplayedMaxWarning( FALSE ); - } - } - temp = temp->getNextDrawable(); - } - } - - UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossMap" ); - TheInGameUI->message( message ); - setSelectedAcrossScreen( FALSE ); - - } - */ } //----------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index a6faef03557..f109b132d2c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -2213,7 +2213,7 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage case GameMessage::MSG_META_SELECT_MATCHING_UNITS: { - TheInGameUI->selectMatchingUnits(); + TheInGameUI->selectUnitsMatchingCurrentSelection(); disp = DESTROY_MESSAGE; break; @@ -2739,7 +2739,51 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------------------- case GameMessage::MSG_META_SELECT_ALL: - { + case GameMessage::MSG_META_SELECT_ALL_AIRCRAFT: + { + KindOfMaskType requiredKindofs; + KindOfMaskType disqualifyingKindofs; + disqualifyingKindofs.set(KINDOF_DOZER); + disqualifyingKindofs.set(KINDOF_HARVESTER); + disqualifyingKindofs.set(KINDOF_IGNORES_SELECT_ALL); + Bool selectAircraft = FALSE; + + if( t == GameMessage::MSG_META_SELECT_ALL_AIRCRAFT ) + { + requiredKindofs.set(KINDOF_AIRCRAFT); + selectAircraft = TRUE; + } + + //Kris: Patch 1.03. We need to deselect all the units if any of the units we have selected + //are incompatible with the select all type we are triggering. This is a fix for the SCUDSTORM + //exploit. + const DrawableList *drawList = TheInGameUI->getAllSelectedDrawables(); + Drawable *draw; + for( DrawableListCIt it = drawList->begin(); it != drawList->end(); ++it ) + { + draw = *it; + if( selectAircraft && (draw->isAnyKindOf( disqualifyingKindofs ) || !draw->isKindOf( KINDOF_AIRCRAFT )) ) + { + TheInGameUI->deselectAllDrawables(); + break; + } + else if( !selectAircraft && (draw->isAnyKindOf( disqualifyingKindofs ) || draw->isKindOf( KINDOF_STRUCTURE )) ) + { + TheInGameUI->deselectAllDrawables(); + break; + } + } + + TheInGameUI->selectAllUnitsByType(requiredKindofs, disqualifyingKindofs); + + disp = DESTROY_MESSAGE; + break; + + + + + +/* TheInGameUI->deselectAllDrawables(); GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP ); @@ -2785,10 +2829,6 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage TheInGameUI->setDisplayedMaxWarning( FALSE ); } } - /*else - { - TheInGameUI->deselectDrawable(draw); - }*/ draw = draw->getNextDrawable(); } @@ -2800,6 +2840,7 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage disp = DESTROY_MESSAGE; break; +*/ } // end select all diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp index fbb450c4bd2..200d4f8e668 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp @@ -132,6 +132,7 @@ static const LookupListRec GameMessageMetaTypeNames[] = { "SELECT_PREV_WORKER", GameMessage::MSG_META_SELECT_PREV_WORKER }, { "SELECT_HERO", GameMessage::MSG_META_SELECT_HERO }, { "SELECT_ALL", GameMessage::MSG_META_SELECT_ALL }, + { "SELECT_ALL_AIRCRAFT", GameMessage::MSG_META_SELECT_ALL_AIRCRAFT }, { "VIEW_COMMAND_CENTER", GameMessage::MSG_META_VIEW_COMMAND_CENTER }, { "VIEW_LAST_RADAR_EVENT", GameMessage::MSG_META_VIEW_LAST_RADAR_EVENT }, { "SCATTER", GameMessage::MSG_META_SCATTER }, diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index e3c2c9a81a8..252e72112cf 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -511,9 +511,9 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa // Yay. Either select across the screen or the world depending on selectAcrossMap if (selectAcrossMap) - TheInGameUI->selectAcrossMap(); + TheInGameUI->selectMatchingAcrossMap(); else - TheInGameUI->selectAcrossScreen(); + TheInGameUI->selectMatchingAcrossScreen(); // emit "picked" message GameMessage *pickMsg = TheMessageStream->appendMessage( GameMessage::MSG_AREA_SELECTION );