This can be used to avoid several lookups for these traits, as well as allow Actor to provide specialised methods to deal with target types efficiently. This also reduces some code duplication.
89 lines
3.1 KiB
C#
89 lines
3.1 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2015 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. For more information,
|
|
* see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Orders
|
|
{
|
|
public abstract class UnitOrderTargeter : IOrderTargeter
|
|
{
|
|
readonly string cursor;
|
|
readonly bool targetEnemyUnits, targetAllyUnits;
|
|
|
|
public UnitOrderTargeter(string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)
|
|
{
|
|
this.OrderID = order;
|
|
this.OrderPriority = priority;
|
|
this.cursor = cursor;
|
|
this.targetEnemyUnits = targetEnemyUnits;
|
|
this.targetAllyUnits = targetAllyUnits;
|
|
}
|
|
|
|
public string OrderID { get; private set; }
|
|
public int OrderPriority { get; private set; }
|
|
public bool? ForceAttack = null;
|
|
public bool OverrideSelection { get { return true; } }
|
|
|
|
public abstract bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor);
|
|
public abstract bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor);
|
|
|
|
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
|
{
|
|
var type = target.Type;
|
|
if (type != TargetType.Actor && type != TargetType.FrozenActor)
|
|
return false;
|
|
|
|
cursor = this.cursor;
|
|
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
|
|
|
|
if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack)
|
|
return false;
|
|
|
|
var owner = type == TargetType.FrozenActor ? target.FrozenActor.Owner : target.Actor.Owner;
|
|
var playerRelationship = self.Owner.Stances[owner];
|
|
|
|
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits)
|
|
return false;
|
|
|
|
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits)
|
|
return false;
|
|
|
|
return type == TargetType.FrozenActor ?
|
|
CanTargetFrozenActor(self, target.FrozenActor, modifiers, ref cursor) :
|
|
CanTargetActor(self, target.Actor, modifiers, ref cursor);
|
|
}
|
|
|
|
public virtual bool IsQueued { get; protected set; }
|
|
}
|
|
|
|
public class TargetTypeOrderTargeter : UnitOrderTargeter
|
|
{
|
|
readonly HashSet<string> targetTypes;
|
|
|
|
public TargetTypeOrderTargeter(HashSet<string> targetTypes, string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)
|
|
: base(order, priority, cursor, targetEnemyUnits, targetAllyUnits)
|
|
{
|
|
this.targetTypes = targetTypes;
|
|
}
|
|
|
|
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
|
{
|
|
return targetTypes.Overlaps(target.GetEnabledTargetTypes());
|
|
}
|
|
|
|
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
|
{
|
|
return target.TargetTypes.Overlaps(targetTypes);
|
|
}
|
|
}
|
|
}
|