#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.Orders; using OpenRA.Mods.Common.Traits; using OpenRA.Orders; using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets { /// Contains all functions that are unit-specific. public class UnitCommandWidget : Widget { readonly World world; [ObjectCreator.UseCtor] public UnitCommandWidget(World world, WorldRenderer worldRenderer) { this.world = world; } 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; // Put all functions that are valid for observers/spectators inside WorldCommandWidget. if (world.LocalPlayer == null || world.LocalPlayer.Spectating) return false; if (world.IsGameOver || !world.Selection.Actors.Any()) 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.AttackMoveKey) return PerformAttackMove(); if (key == ks.StopKey) return PerformStop(); if (key == ks.ScatterKey) return PerformScatter(); if (key == ks.DeployKey) return PerformDeploy(); var stanceKeyIdx = new Hotkey[] { ks.StanceHoldFireKey, ks.StanceReturnFireKey, ks.StanceDefendKey, ks.StanceAttackAnythingKey }.IndexOf(key); if (stanceKeyIdx > -1) return SetUnitStance((UnitStance)stanceKeyIdx); if (key == ks.GuardKey) return PerformGuard(); } return false; } // TODO: take ALL this garbage and route it through the OrderTargeter stuff. bool PerformAttackMove() { var actors = world.Selection.Actors .Where(a => a.Owner == world.LocalPlayer) .ToArray(); if (actors.Any(a => a.Info.HasTraitInfo() && a.Info.HasTraitInfo())) world.OrderGenerator = new GenericSelectTarget(actors, "AttackMove", "attackmove", Game.Settings.Game.MouseButtonPreference.Action); return true; } void PerformKeyboardOrderOnSelection(Func f) { var orders = world.Selection.Actors .Where(a => a.Owner == world.LocalPlayer && !a.Disposed) .Select(f) .ToArray(); foreach (var o in orders) world.IssueOrder(o); world.PlayVoiceForOrders(orders); } bool PerformStop() { PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false)); return true; } bool PerformScatter() { PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false)); return true; } bool PerformDeploy() { // HACK: multiple orders here PerformKeyboardOrderOnSelection(a => new Order("ReturnToBase", a, false)); PerformKeyboardOrderOnSelection(a => new Order("DeployTransform", a, false)); PerformKeyboardOrderOnSelection(a => new Order("Unload", a, false)); PerformKeyboardOrderOnSelection(a => new Order("Detonate", a, false)); PerformKeyboardOrderOnSelection(a => new Order("GrantConditionOnDeploy", a, false)); return true; } bool SetUnitStance(UnitStance unitStance) { PerformKeyboardOrderOnSelection(a => { var at = a.TraitOrDefault(); if (at != null) at.PredictedStance = unitStance; return new Order("SetUnitStance", a, false) { ExtraData = (uint)unitStance }; }); Game.AddChatLine(Color.White, "Battlefield Control", "Unit stance set to: {0}".F(unitStance)); return true; } bool PerformGuard() { var actors = world.Selection.Actors .Where(a => !a.Disposed && a.Owner == world.LocalPlayer); if (actors.Any(a => a.Info.HasTraitInfo() && a.Info.HasTraitInfo())) world.OrderGenerator = new GuardOrderGenerator(actors, "Guard", "guard", Game.Settings.Game.MouseButtonPreference.Action); return true; } } }