Added: Basic stances (Aggressive, Guard (Hold Ground), Hold Fire, None (dummy), Return Fire) Added: WorldCommandWidget (to be able to set said stances) Added: WorldCommandWidget to ra (cnc will follow, later on) Changed: Added support to AttackBase for firing with movement disabled + utility method ScanForTarget (used by stances) Added: AssignUnitStance (attach this to unit-producing actors, together with what stances can be picked as 'default')
110 lines
2.8 KiB
C#
110 lines
2.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using OpenRA.FileFormats;
|
|
using OpenRA.Graphics;
|
|
using OpenRA.Network;
|
|
using OpenRA.Orders;
|
|
using OpenRA.Widgets;
|
|
|
|
namespace OpenRA.Mods.RA.Widgets
|
|
{
|
|
public class WorldCommandWidget : Widget
|
|
{
|
|
public World World { get { return OrderManager.world; } }
|
|
|
|
public char AttackMoveKey = 'a';
|
|
public char GuardKey = 'g'; // (G)uard
|
|
// public char DefensiveKey = 'd'; // (D)efensive
|
|
public char AggressiveKey = 'a'; // (A)ggressive
|
|
public char ReturnFireKey = 'r'; // (R)eturn Fire
|
|
public char HoldFire = 'h'; // (h)old fire
|
|
public readonly OrderManager OrderManager;
|
|
|
|
[ObjectCreator.UseCtor]
|
|
public WorldCommandWidget([ObjectCreator.Param] OrderManager orderManager )
|
|
{
|
|
OrderManager = orderManager;
|
|
}
|
|
|
|
public override void DrawInner(WorldRenderer wr)
|
|
{
|
|
|
|
}
|
|
|
|
public override string GetCursor(int2 pos)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public override bool HandleKeyPressInner(KeyInput e)
|
|
{
|
|
if (World == null) return false;
|
|
if (World.LocalPlayer == null) return false;
|
|
|
|
return ProcessInput(e);
|
|
}
|
|
|
|
private bool ProcessInput(KeyInput e)
|
|
{
|
|
// command: AttackMove
|
|
if (e.KeyChar == AttackMoveKey && e.Modifiers == Modifiers.None)
|
|
{
|
|
return PerformAttackMove();
|
|
}
|
|
|
|
// command: GuardStance
|
|
if (e.KeyChar == GuardKey && (e.Modifiers.HasModifier(Modifiers.Alt)))
|
|
{
|
|
return EnableStance<UnitStanceGuard>();
|
|
}
|
|
|
|
// command: AggressiveStance
|
|
if (e.KeyChar == AggressiveKey && (e.Modifiers.HasModifier(Modifiers.Alt)))
|
|
{
|
|
return EnableStance<UnitStanceAggressive>();
|
|
}
|
|
|
|
// stance: Return Fire
|
|
// description: Fires only when fired upon, stops firing if no longer under attack
|
|
if (e.KeyChar == ReturnFireKey && (e.Modifiers.HasModifier(Modifiers.Alt)))
|
|
{
|
|
return EnableStance<UnitStanceReturnFire>();
|
|
}
|
|
|
|
// stance: Hold Fire
|
|
// description: Prevents attacking (ie no autotarget is being done)
|
|
if (e.KeyChar == HoldFire && (e.Modifiers.HasModifier(Modifiers.Alt)))
|
|
{
|
|
return EnableStance<UnitStanceHoldFire>();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool EnableStance<T>() where T : UnitStance
|
|
{
|
|
if (World.Selection.Actors.Count() == 0)
|
|
return false;
|
|
|
|
var traits =
|
|
World.Selection.Actors.Where(a => !a.Destroyed && a.Owner == World.LocalPlayer && a.TraitOrDefault<T>() != null && !UnitStance.IsActive<T>(a)).
|
|
Select(a => new Pair<Actor, T>(a, a.TraitOrDefault<T>()) );
|
|
|
|
World.AddFrameEndTask(w => traits.Do(p => p.Second.Activate(p.First)));
|
|
|
|
return traits.Any();
|
|
}
|
|
|
|
private bool PerformAttackMove()
|
|
{
|
|
if (World.Selection.Actors.Count() > 0)
|
|
{
|
|
World.OrderGenerator = new GenericSelectTarget(World.Selection.Actors, "AttackMove", "attackmove", MouseButton.Right);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
} |