Merge pull request #10182 from obrakmann/fix9851-attackmove-click-madness

Fix AttackMove not working properly under certain conditions
This commit is contained in:
abcdefg30
2015-12-13 16:06:51 +01:00
5 changed files with 57 additions and 57 deletions

View File

@@ -13,19 +13,19 @@ using OpenRA.Graphics;
namespace OpenRA.Orders
{
public class GenericSelectTarget : IOrderGenerator
public class GenericSelectTarget : UnitOrderGenerator
{
readonly IEnumerable<Actor> subjects;
readonly string order;
readonly string cursor;
readonly MouseButton expectedButton;
protected readonly IEnumerable<Actor> Subjects;
protected readonly string OrderName;
protected readonly string Cursor;
protected readonly MouseButton ExpectedButton;
public GenericSelectTarget(IEnumerable<Actor> subjects, string order, string cursor, MouseButton button)
{
this.subjects = subjects;
this.order = order;
this.cursor = cursor;
expectedButton = button;
Subjects = subjects;
OrderName = order;
Cursor = cursor;
ExpectedButton = button;
}
public GenericSelectTarget(IEnumerable<Actor> subjects, string order, string cursor)
@@ -37,26 +37,23 @@ namespace OpenRA.Orders
public GenericSelectTarget(Actor subject, string order, string cursor, MouseButton button)
: this(new Actor[] { subject }, order, cursor, button) { }
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
public override IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
{
if (mi.Button != expectedButton)
if (mi.Button != ExpectedButton)
world.CancelInputMode();
return OrderInner(world, xy, mi);
}
IEnumerable<Order> OrderInner(World world, CPos xy, MouseInput mi)
protected virtual IEnumerable<Order> OrderInner(World world, CPos xy, MouseInput mi)
{
if (mi.Button == expectedButton && world.Map.Contains(xy))
if (mi.Button == ExpectedButton && world.Map.Contains(xy))
{
world.CancelInputMode();
foreach (var subject in subjects)
yield return new Order(order, subject, false) { TargetLocation = xy };
foreach (var subject in Subjects)
yield return new Order(OrderName, subject, false) { TargetLocation = xy };
}
}
public virtual void Tick(World world) { }
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; }
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world) { yield break; }
public string GetCursor(World world, CPos xy, MouseInput mi) { return world.Map.Contains(xy) ? cursor : "generic-blocked"; }
public override string GetCursor(World world, CPos xy, MouseInput mi) { return world.Map.Contains(xy) ? Cursor : "generic-blocked"; }
}
}

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Orders
{
class UnitOrderGenerator : IOrderGenerator
public class UnitOrderGenerator : IOrderGenerator
{
static Target TargetForInput(World world, CPos xy, MouseInput mi)
{
@@ -36,7 +36,7 @@ namespace OpenRA.Orders
return Target.FromCell(world, xy);
}
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
public virtual IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
{
var target = TargetForInput(world, xy, mi);
var actorsAt = world.ActorMap.GetActorsAt(xy).ToList();
@@ -58,11 +58,11 @@ namespace OpenRA.Orders
yield return CheckSameOrder(o.Order, o.Trait.IssueOrder(o.Actor, o.Order, o.Target, mi.Modifiers.HasModifier(Modifiers.Shift)));
}
public void Tick(World world) { }
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; }
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world) { yield break; }
public virtual void Tick(World world) { }
public virtual IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; }
public virtual IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world) { yield break; }
public string GetCursor(World world, CPos xy, MouseInput mi)
public virtual string GetCursor(World world, CPos xy, MouseInput mi)
{
var useSelect = false;
var target = TargetForInput(world, xy, mi);

View File

@@ -120,12 +120,25 @@ namespace OpenRA.Widgets
}
}
}
else if (dragStart.HasValue)
else
{
// Select actors in the dragbox
var newSelection = SelectActorsInBoxWithDeadzone(World, dragStart.Value, xy);
World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
/* The block below does three things:
// 1. Allows actor selection using a selection box regardless of input mode.
// 2. Allows actor deselection with a single click in the default input mode (UnitOrderGenerator).
// 3. Prevents units from getting deselected when exiting input modes (eg. AttackMove or Guard).
//
// We cannot check for UnitOrderGenerator here since it's the default order generator that gets activated in
// World.CancelInputMode. If we did check it, actor de-selection would not be possible by just clicking somewhere,
// only by dragging an empty selection box.
*/
if (dragStart.HasValue && (!(World.OrderGenerator is GenericSelectTarget) || hasBox))
{
var newSelection = SelectActorsInBoxWithDeadzone(World, dragStart.Value, xy);
World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
}
}
World.CancelInputMode();
}
dragStart = dragEnd = null;