migrating most things to use the Target struct rather than Actor directly.

This commit is contained in:
Chris Forbes
2010-07-05 18:25:10 +12:00
parent 88b705c8ef
commit 5c61c9d3a9
14 changed files with 57 additions and 49 deletions

View File

@@ -161,12 +161,13 @@ namespace OpenRA.Traits
{ {
Actor actor; Actor actor;
float2 pos; float2 pos;
bool valid;
public static Target FromActor(Actor a) { return new Target { actor = a }; } public static Target FromActor(Actor a) { return new Target { actor = a, valid = true }; }
public static Target FromPos(float2 p) { return new Target { pos = p }; } public static Target FromPos(float2 p) { return new Target { pos = p, valid = true }; }
public bool IsValid { get { return actor == null || actor.IsInWorld; } } public bool IsValid { get { return valid && (actor == null || actor.IsInWorld); } }
public float2 Location { get { return actor != null ? actor.CenterLocation : pos; } } public float2 CenterLocation { get { return actor != null ? actor.CenterLocation : pos; } }
public Actor Actor { get { return actor; } } public Actor Actor { get { return actor; } }
public bool IsActor { get { return actor != null; } } public bool IsActor { get { return actor != null; } }

View File

@@ -17,10 +17,10 @@ namespace OpenRA.Mods.RA.Activities
/* non-turreted attack */ /* non-turreted attack */
public class Attack : IActivity public class Attack : IActivity
{ {
Actor Target; Target Target;
int Range; int Range;
public Attack(Actor target, int range) public Attack(Target target, int range)
{ {
Target = target; Target = target;
Range = range; Range = range;
@@ -32,13 +32,15 @@ namespace OpenRA.Mods.RA.Activities
{ {
var unit = self.traits.Get<Unit>(); var unit = self.traits.Get<Unit>();
if (Target == null || Target.IsDead) if (!Target.IsValid)
return NextActivity; return NextActivity;
if ((Target.Location - self.Location).LengthSquared >= Range * Range) var targetCell = Util.CellContaining(Target.CenterLocation);
return new Move( Target, Range ) { NextActivity = this };
var desiredFacing = Util.GetFacing((Target.Location - self.Location).ToFloat2(), 0); if ((targetCell - self.Location).LengthSquared >= Range * Range)
return new Move( targetCell, Range ) { NextActivity = this };
var desiredFacing = Util.GetFacing((targetCell - self.Location).ToFloat2(), 0);
var renderUnit = self.traits.GetOrDefault<RenderUnit>(); var renderUnit = self.traits.GetOrDefault<RenderUnit>();
var numDirs = (renderUnit != null) var numDirs = (renderUnit != null)
? renderUnit.anim.CurrentSequence.Facings : 8; ? renderUnit.anim.CurrentSequence.Facings : 8;
@@ -57,7 +59,7 @@ namespace OpenRA.Mods.RA.Activities
public void Cancel(Actor self) public void Cancel(Actor self)
{ {
Target = null; Target = new Target();
} }
} }
} }

View File

@@ -16,13 +16,13 @@ namespace OpenRA.Mods.RA.Activities
{ {
class Leap : IActivity class Leap : IActivity
{ {
Actor target; Target target;
float2 initialLocation; float2 initialLocation;
float t; float t;
const int delay = 6; const int delay = 6;
public Leap(Actor self, Actor target) public Leap(Actor self, Target target)
{ {
this.target = target; this.target = target;
initialLocation = self.CenterLocation; initialLocation = self.CenterLocation;
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Activities
public IActivity Tick(Actor self) public IActivity Tick(Actor self)
{ {
if (target == null || !target.IsInWorld) if (!target.IsValid)
return NextActivity; return NextActivity;
t += (1f / delay); t += (1f / delay);
@@ -44,14 +44,17 @@ namespace OpenRA.Mods.RA.Activities
if (t >= 1f) if (t >= 1f)
{ {
self.traits.WithInterface<IMove>().FirstOrDefault().SetPosition(self, target.Location); self.traits.WithInterface<IMove>().FirstOrDefault()
target.InflictDamage(self, target.Health, null); // kill it .SetPosition(self, Util.CellContaining(target.CenterLocation));
if (target.IsActor)
target.Actor.InflictDamage(self, target.Actor.Health, null); // kill it
return NextActivity; return NextActivity;
} }
return this; return this;
} }
public void Cancel(Actor self) { target = null; NextActivity = null; } public void Cancel(Actor self) { target = new Target(); NextActivity = null; }
} }
} }

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IProvideCursor public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IProvideCursor
{ {
[Sync] public Actor target; public Target target;
// time (in frames) until each weapon can fire again. // time (in frames) until each weapon can fire again.
[Sync] [Sync]
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA
protected virtual bool CanAttack(Actor self) protected virtual bool CanAttack(Actor self)
{ {
if (target == null) return false; if (!target.IsValid) return false;
if ((primaryFireDelay > 0) && (secondaryFireDelay > 0)) return false; if ((primaryFireDelay > 0) && (secondaryFireDelay > 0)) return false;
if (self.traits.WithInterface<IDisable>().Any(d => d.Disabled)) return false; if (self.traits.WithInterface<IDisable>().Any(d => d.Disabled)) return false;
@@ -85,8 +85,6 @@ namespace OpenRA.Mods.RA
primaryRecoil = Math.Max(0f, primaryRecoil - .2f); primaryRecoil = Math.Max(0f, primaryRecoil - .2f);
secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f); secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f);
if (target != null && target.IsDead) target = null; /* he's dead, jim. */
for (var i = 0; i < delayedActions.Count; i++) for (var i = 0; i < delayedActions.Count; i++)
{ {
var x = delayedActions[i]; var x = delayedActions[i];
@@ -137,7 +135,7 @@ namespace OpenRA.Mods.RA
return false; return false;
var weapon = Rules.Weapons[weaponName.ToLowerInvariant()]; var weapon = Rules.Weapons[weaponName.ToLowerInvariant()];
if (weapon.Range * weapon.Range < (target.Location - self.Location).LengthSquared) return false; if (weapon.Range * weapon.Range < (target.CenterLocation - self.Location).LengthSquared) return false;
if (!Combat.WeaponValidForTarget(weapon, target)) return false; if (!Combat.WeaponValidForTarget(weapon, target)) return false;
@@ -160,14 +158,14 @@ namespace OpenRA.Mods.RA
burst = weapon.Burst; burst = weapon.Burst;
} }
var destUnit = target.traits.GetOrDefault<Unit>(); var destUnit = target.IsActor ? target.Actor.traits.GetOrDefault<Unit>() : null;
var args = new ProjectileArgs var args = new ProjectileArgs
{ {
weapon = Rules.Weapons[weaponName.ToLowerInvariant()], weapon = Rules.Weapons[weaponName.ToLowerInvariant()],
firedBy = self, firedBy = self,
target = target, target = target.Actor,
src = self.CenterLocation.ToInt2() + Combat.GetTurretPosition(self, unit, fireOffset, 0f).ToInt2(), src = self.CenterLocation.ToInt2() + Combat.GetTurretPosition(self, unit, fireOffset, 0f).ToInt2(),
srcAltitude = unit != null ? unit.Altitude : 0, srcAltitude = unit != null ? unit.Altitude : 0,
@@ -224,7 +222,7 @@ namespace OpenRA.Mods.RA
if ((self.Owner.Stances[ underCursor.Owner ] != Stance.Enemy) && !forceFire) if ((self.Owner.Stances[ underCursor.Owner ] != Stance.Enemy) && !forceFire)
return null; return null;
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null; if (!Combat.HasAnyValidWeapons(self, Target.FromActor(underCursor))) return null;
return new Order(isHeal ? "Heal" : "Attack", self, underCursor); return new Order(isHeal ? "Heal" : "Attack", self, underCursor);
} }
@@ -240,7 +238,7 @@ namespace OpenRA.Mods.RA
self.World.AddFrameEndTask(w => w.Add(new FlashTarget(order.TargetActor))); self.World.AddFrameEndTask(w => w.Add(new FlashTarget(order.TargetActor)));
} }
else else
target = null; target = new Target();
} }
public string CursorForOrderString(string s, Actor a, int2 location) public string CursorForOrderString(string s, Actor a, int2 location)
@@ -258,7 +256,7 @@ namespace OpenRA.Mods.RA
/* todo: choose the appropriate weapon, when only one works against this target */ /* todo: choose the appropriate weapon, when only one works against this target */
var weapon = self.GetPrimaryWeapon() ?? self.GetSecondaryWeapon(); var weapon = self.GetPrimaryWeapon() ?? self.GetSecondaryWeapon();
self.QueueActivity(new Activities.Attack(order.TargetActor, self.QueueActivity(new Activities.Attack(Target.FromActor(order.TargetActor),
Math.Max(0, (int)weapon.Range))); Math.Max(0, (int)weapon.Range)));
} }
} }

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA
{ {
base.Tick(self); base.Tick(self);
if (target == null) return; if (!target.IsValid) return;
var unit = self.traits.Get<Unit>(); var unit = self.traits.Get<Unit>();
var facingToTarget = Util.GetFacing(target.CenterLocation - self.CenterLocation, unit.Facing); var facingToTarget = Util.GetFacing(target.CenterLocation - self.CenterLocation, unit.Facing);

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.RA
protected override void QueueAttack(Actor self, Order order) protected override void QueueAttack(Actor self, Order order)
{ {
target = order.TargetActor; target = Target.FromActor(order.TargetActor);
self.QueueActivity(new HeliAttack(order.TargetActor)); self.QueueActivity(new HeliAttack(order.TargetActor));
} }
} }

View File

@@ -26,11 +26,11 @@ namespace OpenRA.Mods.RA
{ {
base.Tick(self); base.Tick(self);
if (target == null || !target.IsInWorld) return; if (!target.IsValid) return;
if (self.GetCurrentActivity() is Leap) return; if (self.GetCurrentActivity() is Leap) return;
var weapon = self.GetPrimaryWeapon(); var weapon = self.GetPrimaryWeapon();
if (weapon.Range * weapon.Range < (target.Location - self.Location).LengthSquared) return; if (weapon.Range * weapon.Range < (target.CenterLocation - self.Location).LengthSquared) return;
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new Leap(self, target)); self.QueueActivity(new Leap(self, target));

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
protected override void QueueAttack(Actor self, Order order) protected override void QueueAttack(Actor self, Order order)
{ {
target = order.TargetActor; target = Target.FromActor(order.TargetActor);
} }
} }
} }

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.RA
protected override void QueueAttack(Actor self, Order order) protected override void QueueAttack(Actor self, Order order)
{ {
target = order.TargetActor; target = Target.FromActor(order.TargetActor);
self.QueueActivity(new FlyAttack(order.TargetActor)); self.QueueActivity(new FlyAttack(order.TargetActor));
} }
} }

View File

@@ -56,9 +56,9 @@ namespace OpenRA.Mods.RA
timeToRecharge = self.GetPrimaryWeapon().ROF; timeToRecharge = self.GetPrimaryWeapon().ROF;
--charges; --charges;
if( target != sameTarget ) if( target.Actor != sameTarget )
{ {
sameTarget = target; sameTarget = target.Actor;
self.traits.Get<RenderBuildingCharge>().PlayCharge( self ); self.traits.Get<RenderBuildingCharge>().PlayCharge( self );
return base.FireDelay( self, info ); return base.FireDelay( self, info );
} }

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA
if( self.traits.Contains<Building>() && !buildComplete ) if( self.traits.Contains<Building>() && !buildComplete )
return false; return false;
if (target == null) return false; if (!target.IsValid) return false;
var turreted = self.traits.Get<Turreted>(); var turreted = self.traits.Get<Turreted>();
turreted.desiredFacing = Util.GetFacing( target.CenterLocation - self.CenterLocation, turreted.turretFacing ); turreted.desiredFacing = Util.GetFacing( target.CenterLocation - self.CenterLocation, turreted.turretFacing );
if( turreted.desiredFacing != turreted.turretFacing ) if( turreted.desiredFacing != turreted.turretFacing )
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA
self.QueueActivity( new Follow( order.TargetActor, self.QueueActivity( new Follow( order.TargetActor,
Math.Max( 0, (int)weapon.Range - RangeTolerance ) ) ); Math.Max( 0, (int)weapon.Range - RangeTolerance ) ) );
target = order.TargetActor; target = Target.FromActor(order.TargetActor);
} }

View File

@@ -33,11 +33,12 @@ namespace OpenRA.Mods.RA
var attack = self.traits.Get<AttackBase>(); var attack = self.traits.Get<AttackBase>();
var range = Combat.GetMaximumRange(self); var range = Combat.GetMaximumRange(self);
if (attack.target == null) if (!attack.target.IsValid)
return true; // he's dead. return true; // he's dead.
if ((attack.target.Location - self.Location).LengthSquared > range * range + 2) if ((attack.target.CenterLocation - self.Location).LengthSquared > range * range + 2)
return true; // wandered off faster than we could follow return true; // wandered off faster than we could follow
if (attack.target.Health == attack.target.Info.Traits.Get<OwnedActorInfo>().HP) if (attack.target.IsActor && attack.target.Actor.Health
== attack.target.Actor.Info.Traits.Get<OwnedActorInfo>().HP)
return true; // fully healed return true; // fully healed
return false; return false;
@@ -57,7 +58,7 @@ namespace OpenRA.Mods.RA
return inRange return inRange
.Where(a => a != self && self.Owner.Stances[ a.Owner ] == Stance.Ally) .Where(a => a != self && self.Owner.Stances[ a.Owner ] == Stance.Ally)
.Where(a => Combat.HasAnyValidWeapons(self, a)) .Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a)))
.Where(a => a.Health < a.Info.Traits.Get<OwnedActorInfo>().HP) .Where(a => a.Health < a.Info.Traits.Get<OwnedActorInfo>().HP)
.OrderBy(a => (a.Location - self.Location).LengthSquared) .OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault(); .FirstOrDefault();

View File

@@ -40,8 +40,8 @@ namespace OpenRA.Mods.RA
var attack = self.traits.Get<AttackBase>(); var attack = self.traits.Get<AttackBase>();
var range = Combat.GetMaximumRange(self); var range = Combat.GetMaximumRange(self);
if (attack.target == null || if (!attack.target.IsValid ||
(attack.target.Location - self.Location).LengthSquared > range * range) (Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
AttackTarget(self, ChooseTarget(self, range)); AttackTarget(self, ChooseTarget(self, range));
var info = self.Info.Traits.Get<AutoTargetInfo>(); var info = self.Info.Traits.Get<AutoTargetInfo>();
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA
return inRange return inRange
.Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy) .Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy)
.Where(a => Combat.HasAnyValidWeapons(self, a)) .Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a)))
.Where(a => !a.traits.Contains<Cloak>() || !a.traits.Get<Cloak>().Cloaked) .Where(a => !a.traits.Contains<Cloak>() || !a.traits.Get<Cloak>().Cloaked)
.OrderBy(a => (a.Location - self.Location).LengthSquared) .OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault(); .FirstOrDefault();
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA
if (!e.Attacker.Info.Traits.Contains<OwnedActorInfo>()) return; if (!e.Attacker.Info.Traits.Contains<OwnedActorInfo>()) return;
// not a lot we can do about things we can't hurt... although maybe we should automatically run away? // not a lot we can do about things we can't hurt... although maybe we should automatically run away?
if (!Combat.HasAnyValidWeapons(self, e.Attacker)) return; if (!Combat.HasAnyValidWeapons(self, Target.FromActor(e.Attacker))) return;
// don't retaliate against own units force-firing on us. it's usually not what the player wanted. // don't retaliate against own units force-firing on us. it's usually not what the player wanted.
if (self.Owner.Stances[e.Attacker.Owner] == Stance.Ally) return; if (self.Owner.Stances[e.Attacker.Owner] == Stance.Ally) return;

View File

@@ -147,7 +147,7 @@ namespace OpenRA.Mods.RA
static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier) static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier)
{ {
// don't hit air units with splash from ground explosions, etc // don't hit air units with splash from ground explosions, etc
if (!WeaponValidForTarget(args.weapon, target)) return 0f; if (!WeaponValidForTarget(args.weapon, Target.FromActor(target))) return 0f;
var selectable = target.Info.Traits.GetOrDefault<SelectableInfo>(); var selectable = target.Info.Traits.GetOrDefault<SelectableInfo>();
var radius = selectable != null ? selectable.Radius : 0; var radius = selectable != null ? selectable.Radius : 0;
@@ -159,9 +159,12 @@ namespace OpenRA.Mods.RA
return (float)(rawDamage * multiplier); return (float)(rawDamage * multiplier);
} }
public static bool WeaponValidForTarget(WeaponInfo weapon, Actor target) public static bool WeaponValidForTarget(WeaponInfo weapon, Target target)
{ {
var ownedInfo = target.Info.Traits.GetOrDefault<OwnedActorInfo>(); // todo: fix this properly.
if (!target.IsValid || !target.IsActor) return false;
var ownedInfo = target.Actor.Info.Traits.GetOrDefault<OwnedActorInfo>();
if (!weapon.ValidTargets.Contains(ownedInfo.TargetType)) if (!weapon.ValidTargets.Contains(ownedInfo.TargetType))
return false; return false;
@@ -175,7 +178,7 @@ namespace OpenRA.Mods.RA
return true; return true;
} }
public static bool HasAnyValidWeapons(Actor self, Actor target) public static bool HasAnyValidWeapons(Actor self, Target target)
{ {
var info = self.Info.Traits.Get<AttackBaseInfo>(); var info = self.Info.Traits.Get<AttackBaseInfo>();
if (info.PrimaryWeapon != null && if (info.PrimaryWeapon != null &&