diff --git a/src/include/unit.h b/src/include/unit.h index cf0c2abb2..5e4073a48 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -915,6 +915,8 @@ extern void UnSelectUnit(Unit* unit); extern int ToggleSelectUnit(Unit* unit); /// Select units from the same type (if selectable by rectangle) extern int SelectUnitsByType(Unit* base); + /// Toggle units from the same type (if selectable by rectangle) +extern int ToggleUnitsByType(Unit* base); /// Select the units belonging to a particular group extern int SelectGroup(int group_number); /// Select the unit from the same group as the one in parameter diff --git a/src/stratagus/selection.cpp b/src/stratagus/selection.cpp index fd4606850..56b1de240 100644 --- a/src/stratagus/selection.cpp +++ b/src/stratagus/selection.cpp @@ -10,12 +10,11 @@ // /**@name selection.c - The units' selection. */ // -// (c) Copyright 1999-2001 by Patrice Fortier +// (c) Copyright 1999-2002 by Patrice Fortier, Lutz Sammer // // FreeCraft is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the License, -// or (at your option) any later version. +// by the Free Software Foundation; only version 2 of the License. // // FreeCraft is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -110,26 +109,26 @@ global void ChangeSelectedUnits(Unit** units,int count) ** @return false if NumSelected == MaxSelectable or ** unit is already selected, true otherwise. */ -global int SelectUnit(Unit* unit) +global int SelectUnit(Unit * unit) { - if ( unit->Revealer ) { // Revealers cannot be selected + if (unit->Revealer) { // Revealers cannot be selected DebugLevel0Fn("Selecting revealer?\n"); return 0; } - if( NumSelected == MaxSelectable ) { - return 0; + if (NumSelected == MaxSelectable) { + return 0; } - if( unit->Selected ) { - return 0; + if (unit->Selected) { + return 0; } - Selected[NumSelected++]=unit; - unit->Selected=1; - if( NumSelected>1 ) { - Selected[0]->LastGroup=unit->LastGroup=GroupId; - }; + Selected[NumSelected++] = unit; + unit->Selected = 1; + if (NumSelected > 1) { + Selected[0]->LastGroup = unit->LastGroup = GroupId; + } CheckUnitToBeDrawn(unit); return 1; } @@ -276,6 +275,75 @@ global int SelectUnitsByType(Unit* base) return NumSelected; } +/** +** Toggle units from a particular type and belonging to the local player. +** +** The base is included in the selection and defines +** the type of the other units to be selected. +** +** @param base Toggle all units of same type. +** @return Number of units found, 0 means selection unchanged +** +** @todo +** FIXME: toggle not written +** +** FIXME: should always select the nearest 9 units to the base! +*/ +global int ToggleUnitsByType(Unit* base) +{ + Unit* unit; + Unit* table[UnitMax]; + const UnitType* type; + int r; + int i; + + type = base->Type; + + DebugLevel2Fn(" %s FIXME: toggle not written.\n", base->Type->Ident); + + // select all visible units. + // StephanR: should be (MapX,MapY,MapX+MapWidth-1,MapY+MapHeight-1) ??? + r = SelectUnits(MapX - 1, MapY - 1, MapX + MapWidth + 1, + MapY + MapHeight + 1, table); + + // if unit is a cadaver or hidden (not on map) + // no unit can be selected. + if (base->Removed || base->Orders[0].Action == UnitActionDie) { + return 0; + } + // if unit isn't belonging to the player, or is a static unit + // (like a building), only 1 unit can be selected at the same time. + if (base->Player != ThisPlayer || !type->SelectableByRectangle) { + return 0; + } + + if (!SelectUnit(base)) { // Add base to selection + return 0; + } + // + // Search for other visible units of the same type + // + // FIXME: peon/peasant with gold/wood & co are considered from + // different type... idem for tankers + for (i = 0; i < r; ++i) { + unit = table[i]; + if (unit->Player != ThisPlayer || unit->Type != type) { + continue; + } + if (UnitUnusable(unit)) { // guess SelectUnits doesn't check this + continue; + } + if (unit == base) { // no need to have the same unit twice + continue; + } + if (!SelectUnit(unit)) { // add unit to selection + return NumSelected; + } + } + + return NumSelected; +} + /** ** Change selected units to units from group #group_number ** Doesn't change the selection if the group has no unit. diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp index feea578c8..f50317e0a 100644 --- a/src/ui/mouse.cpp +++ b/src/ui/mouse.cpp @@ -10,12 +10,11 @@ // /**@name mouse.c - The mouse handling. */ // -// (c) Copyright 1998-2001 by Lutz Sammer +// (c) Copyright 1998-2002 by Lutz Sammer // // FreeCraft is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the License, -// or (at your option) any later version. +// by the Free Software Foundation; only version 2 of the License. // // FreeCraft is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1052,7 +1051,11 @@ local void DoSelectionButtons(unsigned num,unsigned button __attribute__((unused if( (KeyModifiers&ModifierControl) || (MouseButtons&(LeftButton<<MouseDoubleShift)) ) { - SelectUnitsByType(unit); + if( KeyModifiers&ModifierShift ) { + ToggleUnitsByType(unit); + } else { + SelectUnitsByType(unit); + } } else if( KeyModifiers&ModifierAlt ) { SelectGroupFromUnit(unit); } else if( KeyModifiers&ModifierShift ) { @@ -1418,7 +1421,11 @@ global void UIHandleButtonUp(unsigned button) // FIXME: Not nice coded, button number hardcoded! if( (KeyModifiers&ModifierControl) || (button&(1<<MouseDoubleShift))) { - num=SelectUnitsByType(unit); + if( KeyModifiers&ModifierShift ) { + num=ToggleUnitsByType(unit); + } else { + num=SelectUnitsByType(unit); + } } else if( (KeyModifiers&ModifierAlt) && unit->LastGroup ) { num=SelectGroupFromUnit(unit);