/** ** Change selected units to units from group group_number ** Doesn't change the selection if the group has no unit. ** ** @param group_number number of the group to be selected. ** ** @return number of units in the group. */ int SelectGroup(int group_number, GroupSelectionMode mode) { const std::vector<CUnit *> &units = GetUnitsOfGroup(group_number); if (units.empty()) { return 0; } if (mode == SELECT_ALL || !IsGroupTainted(group_number)) { ChangeSelectedUnits(const_cast<CUnit **>(&units[0]), units.size()); return Selected.size(); } std::vector<CUnit *> table; for (size_t i = 0; i != units.size(); ++i) { const CUnitType *type = units[i]->Type; if (type && type->CanSelect(mode)) { table.push_back(units[i]); } } if (table.empty() == false) { ChangeSelectedUnits(&table[0], table.size()); return Selected.size(); } return 0; }
/** ** Change selected units to units from group group_number ** Doesn't change the selection if the group has no unit. ** ** @param group_number number of the group to be selected. ** ** @return number of units in the group. */ int SelectGroup(int group_number, GroupSelectionMode mode) { int nunits = GetNumberUnitsOfGroup(group_number, SELECT_ALL); if (nunits) { if (mode == SELECT_ALL || !IsGroupTainted(group_number)) { ChangeSelectedUnits(GetUnitsOfGroup(group_number), nunits); return NumSelected; } else { std::vector<CUnit *> table; CUnit **group = GetUnitsOfGroup(group_number); for (int i = 0; i < nunits; ++i) { const CUnitType *type = group[i]->Type; if (type && type->CanSelect(mode)) { table.push_back(group[i]); } } if (table.empty() == false) { ChangeSelectedUnits(&table[0], static_cast<int>(table.size())); return NumSelected; } } } return 0; }
/** ** Select own air units in a rectangle. ** ** @param corner_topleft, start of selection rectangle ** @param corner_bottomright end of selection rectangle ** ** @return the number of units found. */ int SelectAirUnitsInRectangle(const PixelPos &corner_topleft, const PixelPos &corner_bottomright) { const Vec2i t0 = Map.MapPixelPosToTilePos(corner_topleft); const Vec2i t1 = Map.MapPixelPosToTilePos(corner_bottomright); const Vec2i range(2, 2); std::vector<CUnit *> table; Select(t0 - range, t1 + range, table); SelectSpritesInsideRectangle(corner_topleft, corner_bottomright, table); unsigned int n = 0; for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; if (!CanSelectMultipleUnits(*unit.Player) || !unit.Type->SelectableByRectangle) { continue; } if (unit.IsUnusable()) { // guess SelectUnits doesn't check this continue; } if (unit.Type->UnitType != UnitTypeFly) { continue; } if (unit.TeamSelected) { // Somebody else onteam has this unit continue; } table[n++] = &unit; if (n == MaxSelectable) { break; } } if (n) { ChangeSelectedUnits(&table[0], n); } return n; }
/** ** Select own ground units in a rectangle. ** ** @param corner_topleft, start of selection rectangle ** @param corner_bottomright end of selection rectangle ** ** @return the number of units found. */ int SelectGroundUnitsInRectangle(const PixelPos &corner_topleft, const PixelPos &corner_bottomright) { const Vec2i t0 = Map.MapPixelPosToTilePos(corner_topleft, UI.CurrentMapLayer->ID); const Vec2i t1 = Map.MapPixelPosToTilePos(corner_bottomright, UI.CurrentMapLayer->ID); const Vec2i range(2, 2); std::vector<CUnit *> table; //Wyrmgus start // Select(t0 - range, t1 + range, table); Select(t0 - range, t1 + range, table, UI.CurrentMapLayer->ID); //Wyrmgus end SelectSpritesInsideRectangle(corner_topleft, corner_bottomright, table); unsigned int n = 0; for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; if (!CanSelectMultipleUnits(*unit.Player) || !unit.Type->BoolFlag[SELECTABLEBYRECTANGLE_INDEX].value) { continue; } if (unit.IsUnusable()) { // guess SelectUnits doesn't check this continue; } if (unit.Type->UnitType == UnitTypeFly) { continue; } if (unit.TeamSelected) { // Somebody else onteam has this unit continue; } //Wyrmgus start if (unit.Type->BoolFlag[BUILDING_INDEX].value) { //this selection mode is not for buildings continue; } //Wyrmgus end table[n++] = &unit; if (n == MaxSelectable) { break; } } if (n) { ChangeSelectedUnits(&table[0], n); } return n; }
/** ** Select entire army. ** ** ** @return the number of units found. */ int SelectArmy() { const Vec2i minPos(0, 0); const Vec2i maxPos(UI.CurrentMapLayer->GetWidth() - 1, UI.CurrentMapLayer->GetHeight() - 1); std::vector<CUnit *> table; //Wyrmgus start // Select(minPos, maxPos, table); Select(minPos, maxPos, table, UI.CurrentMapLayer->ID); //Wyrmgus end unsigned int n = 0; for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; if (!CanSelectMultipleUnits(*unit.Player) || !unit.Type->BoolFlag[SELECTABLEBYRECTANGLE_INDEX].value) { continue; } if (unit.IsUnusable()) { // guess SelectUnits doesn't check this continue; } if (unit.Type->UnitType == UnitTypeNaval || unit.Type->UnitType == UnitTypeFly) { continue; } if (unit.TeamSelected) { // Somebody else on team has this unit continue; } if (unit.Type->BoolFlag[BUILDING_INDEX].value) { //this selection mode is not for buildings continue; } if (unit.Type->BoolFlag[HARVESTER_INDEX].value) { //this selection mode is not for workers continue; } table[n++] = &unit; if (n == MaxSelectable) { break; } } if (n) { ChangeSelectedUnits(&table[0], n); } return n; }
/** ** Select units in a rectangle. ** Proceed in order in none found: ** @li select local player mobile units ** @li select one local player static unit (random) ** @li select one neutral unit (critter, mine...) ** @li select one enemy unit (random) ** ** @param corner_topleft, start of selection rectangle ** @param corner_bottomright end of selection rectangle ** ** @return the number of units found. */ int SelectUnitsInRectangle(const PixelPos &corner_topleft, const PixelPos &corner_bottomright) { const Vec2i t0 = Map.MapPixelPosToTilePos(corner_topleft); const Vec2i t1 = Map.MapPixelPosToTilePos(corner_bottomright); const Vec2i range(2, 2); std::vector<CUnit *> table; Select(t0 - range, t1 + range, table); SelectSpritesInsideRectangle(corner_topleft, corner_bottomright, table); // 1) search for the player units selectable with rectangle if (SelectOrganicUnitsInTable(table)) { const int size = static_cast<int>(table.size()); ChangeSelectedUnits(&table[0], size); return size; } // 2) If no unit found, try a player's unit not selectable by rectangle for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; if (!CanSelectMultipleUnits(*unit.Player)) { continue; } // FIXME: Can we get this? if (!unit.Removed && unit.IsAlive()) { SelectSingleUnit(unit); return 1; } } // 3) If no unit found, try a resource or a neutral critter for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; // Unit visible FIXME: write function UnitSelectable if (!unit.IsVisibleInViewport(*UI.SelectedViewport)) { continue; } const CUnitType &type = *unit.Type; // Buildings are visible but not selectable if (type.Building && !unit.IsVisibleOnMap(*ThisPlayer)) { continue; } if ((type.GivesResource && !unit.Removed)) { // no built resources. SelectSingleUnit(unit); return 1; } } // 4) If no unit found, select an enemy unit (first found) for (size_t i = 0; i != table.size(); ++i) { CUnit &unit = *table[i]; // Unit visible FIXME: write function UnitSelectable if (!unit.IsVisibleInViewport(*UI.SelectedViewport)) { continue; } // Buildings are visible but not selectable if (unit.Type->Building && !unit.IsVisibleOnMap(*ThisPlayer)) { continue; } if (unit.IsAliveOnMap()) { SelectSingleUnit(unit); return 1; } } return 0; }
/** ** Select a single unit, unselecting the previous ones ** ** @param unit Pointer to unit to be selected. */ void SelectSingleUnit(CUnit &unit) { CUnit *unitPtr = &unit; ChangeSelectedUnits(&unitPtr, 1); }