Introduce Target.Type property.
This commit is contained in:
@@ -151,12 +151,10 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
public bool IsValidAgainst(Target target, World world)
|
public bool IsValidAgainst(Target target, World world)
|
||||||
{
|
{
|
||||||
if (!target.IsValid)
|
if (target.Type == TargetType.Actor)
|
||||||
return false;
|
|
||||||
|
|
||||||
if (target.IsActor)
|
|
||||||
return IsValidAgainst(target.Actor);
|
return IsValidAgainst(target.Actor);
|
||||||
else
|
|
||||||
|
if (target.Type == TargetType.Terrain)
|
||||||
{
|
{
|
||||||
var cell = target.CenterPosition.ToCPos();
|
var cell = target.CenterPosition.ToCPos();
|
||||||
if (ValidTargets.Contains("Ground") && world.GetTerrainType(cell) != "Water")
|
if (ValidTargets.Contains("Ground") && world.GetTerrainType(cell) != "Water")
|
||||||
@@ -167,6 +165,8 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,8 +109,10 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
self.World.AddFrameEndTask(w =>
|
self.World.AddFrameEndTask(w =>
|
||||||
{
|
{
|
||||||
if (self.Destroyed) return;
|
if (self.Destroyed)
|
||||||
if (target.IsActor && display)
|
return;
|
||||||
|
|
||||||
|
if (target.Type == TargetType.Actor && display)
|
||||||
w.Add(new FlashTarget(target.Actor));
|
w.Add(new FlashTarget(target.Actor));
|
||||||
|
|
||||||
var line = self.TraitOrDefault<DrawLineToTarget>();
|
var line = self.TraitOrDefault<DrawLineToTarget>();
|
||||||
|
|||||||
@@ -14,18 +14,19 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
|
public enum TargetType { Invalid, Actor, Terrain }
|
||||||
public struct Target
|
public struct Target
|
||||||
{
|
{
|
||||||
public static readonly Target[] NoTargets = {};
|
public static readonly Target[] None = {};
|
||||||
public static readonly Target None = new Target();
|
public static readonly Target Invalid = new Target { type = TargetType.Invalid };
|
||||||
|
|
||||||
|
TargetType type;
|
||||||
Actor actor;
|
Actor actor;
|
||||||
WPos pos;
|
WPos pos;
|
||||||
bool valid;
|
|
||||||
int generation;
|
int generation;
|
||||||
|
|
||||||
public static Target FromPos(WPos p) { return new Target { pos = p, valid = true }; }
|
public static Target FromPos(WPos p) { return new Target { pos = p, type = TargetType.Terrain }; }
|
||||||
public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, valid = true }; }
|
public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, type = TargetType.Terrain }; }
|
||||||
public static Target FromOrder(Order o)
|
public static Target FromOrder(Order o)
|
||||||
{
|
{
|
||||||
return o.TargetActor != null
|
return o.TargetActor != null
|
||||||
@@ -38,23 +39,39 @@ namespace OpenRA.Traits
|
|||||||
return new Target
|
return new Target
|
||||||
{
|
{
|
||||||
actor = a,
|
actor = a,
|
||||||
valid = (a != null),
|
type = a != null ? TargetType.Actor : TargetType.Invalid,
|
||||||
generation = a.Generation,
|
generation = a.Generation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Generation == generation)); } }
|
public bool IsValid { get { return Type != TargetType.Invalid; } }
|
||||||
public Actor Actor { get { return IsActor ? actor : null; } }
|
public Actor Actor { get { return actor; } }
|
||||||
|
|
||||||
// TODO: This should return true even if the actor is destroyed
|
public TargetType Type
|
||||||
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (type == TargetType.Actor)
|
||||||
|
{
|
||||||
|
// Actor is no longer in the world
|
||||||
|
if (!actor.IsInWorld || actor.IsDead())
|
||||||
|
return TargetType.Invalid;
|
||||||
|
|
||||||
|
// Actor generation has changed (teleported or captured)
|
||||||
|
if (actor.Generation != generation)
|
||||||
|
return TargetType.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Representative position - see Positions for the full set of targetable positions.
|
// Representative position - see Positions for the full set of targetable positions.
|
||||||
public WPos CenterPosition
|
public WPos CenterPosition
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!IsValid)
|
if (Type == TargetType.Invalid)
|
||||||
throw new InvalidOperationException("Attempting to query the position of an invalid Target");
|
throw new InvalidOperationException("Attempting to query the position of an invalid Target");
|
||||||
|
|
||||||
return actor != null ? actor.CenterPosition : pos;
|
return actor != null ? actor.CenterPosition : pos;
|
||||||
@@ -67,7 +84,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!IsValid)
|
if (Type == TargetType.Invalid)
|
||||||
return NoPositions;
|
return NoPositions;
|
||||||
|
|
||||||
if (actor == null)
|
if (actor == null)
|
||||||
@@ -83,7 +100,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool IsInRange(WPos origin, WRange range)
|
public bool IsInRange(WPos origin, WRange range)
|
||||||
{
|
{
|
||||||
if (!IsValid)
|
if (Type == TargetType.Invalid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Target ranges are calculated in 2D, so ignore height differences
|
// Target ranges are calculated in 2D, so ignore height differences
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public static IEnumerable<CPos> AdjacentCells(Target target)
|
public static IEnumerable<CPos> AdjacentCells(Target target)
|
||||||
{
|
{
|
||||||
var cells = target.IsActor
|
var cells = target.Type == TargetType.Actor
|
||||||
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
|
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
|
||||||
: new CPos[] { };
|
: new CPos[] { };
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
public Attack(Target target, WRange range, bool allowMovement)
|
public Attack(Target target, WRange range, bool allowMovement)
|
||||||
{
|
{
|
||||||
Target = target;
|
Target = target;
|
||||||
if (target.IsActor)
|
if (target.Type == TargetType.Actor)
|
||||||
targetable = target.Actor.TraitOrDefault<ITargetable>();
|
targetable = target.Actor.TraitOrDefault<ITargetable>();
|
||||||
|
|
||||||
Range = range;
|
Range = range;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (!target.IsValid)
|
if (target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var capturable = target.Actor.Trait<Capturable>();
|
var capturable = target.Actor.Trait<Capturable>();
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () =>
|
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () =>
|
||||||
{
|
{
|
||||||
// Can't demolish an already dead actor
|
// Can't demolish an already dead actor
|
||||||
if (!target.IsValid)
|
if (target.Type != TargetType.Actor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Invulnerable actors can't be demolished
|
// Invulnerable actors can't be demolished
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid || !target.IsActor)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var targetActor = target.Actor;
|
var targetActor = target.Actor;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
if (!Util.AdjacentCells(target).Any(c => c == self.Location))
|
if (!Util.AdjacentCells(target).Any(c => c == self.Location))
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
protected override Activity InnerTick(Actor self, AttackBase attack)
|
protected override Activity InnerTick(Actor self, AttackBase attack)
|
||||||
{
|
{
|
||||||
if (Target.IsActor && Target.Actor.GetDamageState() == DamageState.Undamaged)
|
if (Target.Type == TargetType.Actor && Target.Actor.GetDamageState() == DamageState.Undamaged)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
return base.InnerTick(self, attack);
|
return base.InnerTick(self, attack);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid || target.Actor.Owner == self.Owner)
|
if (IsCanceled || target.Type != TargetType.Actor || target.Actor.Owner == self.Owner)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
foreach (var t in target.Actor.TraitsImplementing<IAcceptInfiltrator>())
|
foreach (var t in target.Actor.TraitsImplementing<IAcceptInfiltrator>())
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
|
||||||
if (!target.IsValid)
|
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var b = target.Actor.TraitOrDefault<Building>();
|
var b = target.Actor.TraitOrDefault<Building>();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var hut = target.Actor.Trait<BridgeHut>();
|
var hut = target.Actor.Trait<BridgeHut>();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled || !target.IsValid)
|
if (IsCanceled || target.Type != TargetType.Actor)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var health = target.Actor.Trait<Health>();
|
var health = target.Actor.Trait<Health>();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (self.IsDisabled())
|
if (self.IsDisabled())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (target.IsActor && target.Actor.HasTrait<ITargetable>() &&
|
if (target.Type == TargetType.Actor && target.Actor.HasTrait<ITargetable>() &&
|
||||||
!target.Actor.Trait<ITargetable>().TargetableBy(target.Actor,self))
|
!target.Actor.Trait<ITargetable>().TargetableBy(target.Actor,self))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
if (order is AttackOrderTargeter)
|
if (order is AttackOrderTargeter)
|
||||||
{
|
{
|
||||||
if (target.IsActor)
|
if (target.Type == TargetType.Actor)
|
||||||
return new Order("Attack", self, queued) { TargetActor = target.Actor };
|
return new Order("Attack", self, queued) { TargetActor = target.Actor };
|
||||||
else
|
else
|
||||||
return new Order("Attack", self, queued) { TargetLocation = target.CenterPosition.ToCPos() };
|
return new Order("Attack", self, queued) { TargetLocation = target.CenterPosition.ToCPos() };
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public override void DoAttack(Actor self, Target target)
|
public override void DoAttack(Actor self, Target target)
|
||||||
{
|
{
|
||||||
if (!CanAttack(self, target) || !target.IsActor)
|
if (target.Type != TargetType.Actor || !CanAttack(self, target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var a = ChooseArmamentForTarget(target);
|
var a = ChooseArmamentForTarget(target);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA
|
|||||||
base.ResolveOrder(self, order);
|
base.ResolveOrder(self, order);
|
||||||
|
|
||||||
if (order.OrderString == "Stop")
|
if (order.OrderString == "Stop")
|
||||||
target = Target.None;
|
target = Target.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void BuildingComplete(Actor self) { buildComplete = true; }
|
public virtual void BuildingComplete(Actor self) { buildComplete = true; }
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
return Enumerable.Reverse(path).Select(c => Target.FromCell(c));
|
return Enumerable.Reverse(path).Select(c => Target.FromCell(c));
|
||||||
if (destination != null)
|
if (destination != null)
|
||||||
return new Target[] { Target.FromCell(destination.Value) };
|
return new Target[] { Target.FromCell(destination.Value) };
|
||||||
return Target.NoTargets;
|
return Target.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MovePart : Activity
|
abstract class MovePart : Activity
|
||||||
|
|||||||
Reference in New Issue
Block a user