#region Copyright & License Information /* * Copyright 2007-2017 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you 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. For more * information, see COPYING. */ #endregion using System; using System.Drawing; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets { /// Contains all functions that are valid for players and observers/spectators. public class WorldCommandWidget : Widget { readonly World world; readonly WorldRenderer worldRenderer; readonly RadarPings radarPings; [ObjectCreator.UseCtor] public WorldCommandWidget(World world, WorldRenderer worldRenderer) { this.world = world; this.worldRenderer = worldRenderer; radarPings = world.WorldActor.TraitOrDefault(); } public override string GetCursor(int2 pos) { return null; } public override Rectangle GetEventBounds() { return Rectangle.Empty; } public override bool HandleKeyPress(KeyInput e) { if (world == null) return false; return ProcessInput(e); } bool ProcessInput(KeyInput e) { if (e.Event == KeyInputEvent.Down) { var key = Hotkey.FromKeyInput(e); var ks = Game.Settings.Keys; if (key == ks.CycleBaseKey) return CycleBases(); if (key == ks.CycleProductionBuildingsKey) return CycleProductionBuildings(); if (key == ks.ToLastEventKey) return ToLastEvent(); if (key == ks.ToSelectionKey) return ToSelection(); } return false; } bool CycleBases() { var player = world.RenderPlayer ?? world.LocalPlayer; var bases = world.ActorsHavingTrait() .Where(a => a.Owner == player) .ToList(); // If no BaseBuilding exist pick the first selectable Building. if (!bases.Any()) { var building = world.ActorsHavingTrait() .FirstOrDefault(a => a.Owner == player && a.Info.HasTraitInfo()); // No buildings left if (building == null) return true; world.Selection.Combine(world, new Actor[] { building }, false, true); return ToSelection(); } var next = bases .SkipWhile(b => !world.Selection.Contains(b)) .Skip(1) .FirstOrDefault(); if (next == null) next = bases.First(); world.Selection.Combine(world, new Actor[] { next }, false, true); return ToSelection(); } bool CycleProductionBuildings() { var player = world.RenderPlayer ?? world.LocalPlayer; var facilities = world.ActorsHavingTrait() .Where(a => a.Owner == player && !a.Info.HasTraitInfo()) .OrderBy(f => f.Info.TraitInfo().Produces.First()) .ToList(); if (!facilities.Any()) return true; var next = facilities .SkipWhile(b => !world.Selection.Contains(b)) .Skip(1) .FirstOrDefault(); if (next == null) next = facilities.First(); world.Selection.Combine(world, new Actor[] { next }, false, true); Game.Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null); return ToSelection(); } bool ToLastEvent() { if (radarPings == null || radarPings.LastPingPosition == null) return true; worldRenderer.Viewport.Center(radarPings.LastPingPosition.Value); return true; } bool ToSelection() { worldRenderer.Viewport.Center(world.Selection.Actors); return true; } } }