#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. * * OpenRA 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 3 of the License, or * (at your option) any later version. * * OpenRA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenRA. If not, see . */ #endregion using System.Collections.Generic; using System.Linq; using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA { public class Selection { List actors = new List(); public void Combine(World world, IEnumerable newSelection, bool isCombine, bool isClick) { var oldSelection = actors.AsEnumerable(); if (isClick) { var adjNewSelection = newSelection.Take(1); /* todo: select BEST, not FIRST */ actors = (isCombine ? oldSelection.SymmetricDifference(adjNewSelection) : adjNewSelection).ToList(); } else actors = (isCombine ? oldSelection.Union(newSelection) : newSelection).ToList(); var voicedUnit = actors.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.HasVoice()); Sound.PlayVoice("Select", voicedUnit); foreach (var ns in world.WorldActor.traits.WithInterface()) ns.SelectionChanged(); } public IEnumerable Actors { get { return actors; } } public void Clear() { actors = new List(); } public void Tick(World world) { actors.RemoveAll(a => !a.IsInWorld); } Cache> controlGroups = new Cache>(_ => new List()); public void DoControlGroup(World world, int group, Modifiers mods) { if (mods.HasModifier(Modifiers.Ctrl)) { if (actors.Count == 0) return; controlGroups[group].Clear(); for (var i = 0; i < 10; i++) /* all control groups */ controlGroups[i].RemoveAll(a => actors.Contains(a)); controlGroups[group].AddRange(actors); return; } if (mods.HasModifier(Modifiers.Alt)) { Game.viewport.Center(controlGroups[group]); return; } Combine(world, controlGroups[group], mods.HasModifier(Modifiers.Shift), false); } public int? GetControlGroupForActor(Actor a) { return controlGroups.Where(g => g.Value.Contains(a)) .Select(g => (int?)g.Key) .FirstOrDefault(); } } }