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;
float2 pos;
bool valid;
public static Target FromActor(Actor a) { return new Target { actor = a }; }
public static Target FromPos(float2 p) { return new Target { pos = p }; }
public static Target FromActor(Actor a) { return new Target { actor = a, valid = true }; }
public static Target FromPos(float2 p) { return new Target { pos = p, valid = true }; }
public bool IsValid { get { return actor == null || actor.IsInWorld; } }
public float2 Location { get { return actor != null ? actor.CenterLocation : pos; } }
public bool IsValid { get { return valid && (actor == null || actor.IsInWorld); } }
public float2 CenterLocation { get { return actor != null ? actor.CenterLocation : pos; } }
public Actor Actor { get { return actor; } }
public bool IsActor { get { return actor != null; } }

View File

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

View File

@@ -16,13 +16,13 @@ namespace OpenRA.Mods.RA.Activities
{
class Leap : IActivity
{
Actor target;
Target target;
float2 initialLocation;
float t;
const int delay = 6;
public Leap(Actor self, Actor target)
public Leap(Actor self, Target target)
{
this.target = target;
initialLocation = self.CenterLocation;
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA.Activities
public IActivity Tick(Actor self)
{
if (target == null || !target.IsInWorld)
if (!target.IsValid)
return NextActivity;
t += (1f / delay);
@@ -44,14 +44,17 @@ namespace OpenRA.Mods.RA.Activities
if (t >= 1f)
{
self.traits.WithInterface<IMove>().FirstOrDefault().SetPosition(self, target.Location);
target.InflictDamage(self, target.Health, null); // kill it
self.traits.WithInterface<IMove>().FirstOrDefault()
.SetPosition(self, Util.CellContaining(target.CenterLocation));
if (target.IsActor)
target.Actor.InflictDamage(self, target.Actor.Health, null); // kill it
return NextActivity;
}
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
{
[Sync] public Actor target;
public Target target;
// time (in frames) until each weapon can fire again.
[Sync]
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA
protected virtual bool CanAttack(Actor self)
{
if (target == null) return false;
if (!target.IsValid) return false;
if ((primaryFireDelay > 0) && (secondaryFireDelay > 0)) 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);
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++)
{
var x = delayedActions[i];
@@ -137,7 +135,7 @@ namespace OpenRA.Mods.RA
return false;
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;
@@ -160,14 +158,14 @@ namespace OpenRA.Mods.RA
burst = weapon.Burst;
}
var destUnit = target.traits.GetOrDefault<Unit>();
var destUnit = target.IsActor ? target.Actor.traits.GetOrDefault<Unit>() : null;
var args = new ProjectileArgs
{
weapon = Rules.Weapons[weaponName.ToLowerInvariant()],
firedBy = self,
target = target,
target = target.Actor,
src = self.CenterLocation.ToInt2() + Combat.GetTurretPosition(self, unit, fireOffset, 0f).ToInt2(),
srcAltitude = unit != null ? unit.Altitude : 0,
@@ -224,7 +222,7 @@ namespace OpenRA.Mods.RA
if ((self.Owner.Stances[ underCursor.Owner ] != Stance.Enemy) && !forceFire)
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);
}
@@ -240,7 +238,7 @@ namespace OpenRA.Mods.RA
self.World.AddFrameEndTask(w => w.Add(new FlashTarget(order.TargetActor)));
}
else
target = null;
target = new Target();
}
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 */
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)));
}
}

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA
{
base.Tick(self);
if (target == null) return;
if (!target.IsValid) return;
var unit = self.traits.Get<Unit>();
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)
{
target = order.TargetActor;
target = Target.FromActor(order.TargetActor);
self.QueueActivity(new HeliAttack(order.TargetActor));
}
}

View File

@@ -26,11 +26,11 @@ namespace OpenRA.Mods.RA
{
base.Tick(self);
if (target == null || !target.IsInWorld) return;
if (!target.IsValid) return;
if (self.GetCurrentActivity() is Leap) return;
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.QueueActivity(new Leap(self, target));

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
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)
{
target = order.TargetActor;
target = Target.FromActor(order.TargetActor);
self.QueueActivity(new FlyAttack(order.TargetActor));
}
}

View File

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

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA
if( self.traits.Contains<Building>() && !buildComplete )
return false;
if (target == null) return false;
if (!target.IsValid) return false;
var turreted = self.traits.Get<Turreted>();
turreted.desiredFacing = Util.GetFacing( target.CenterLocation - self.CenterLocation, turreted.turretFacing );
if( turreted.desiredFacing != turreted.turretFacing )
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA
self.QueueActivity( new Follow( order.TargetActor,
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 range = Combat.GetMaximumRange(self);
if (attack.target == null)
if (!attack.target.IsValid)
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
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 false;
@@ -57,7 +58,7 @@ namespace OpenRA.Mods.RA
return inRange
.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)
.OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault();

View File

@@ -40,8 +40,8 @@ namespace OpenRA.Mods.RA
var attack = self.traits.Get<AttackBase>();
var range = Combat.GetMaximumRange(self);
if (attack.target == null ||
(attack.target.Location - self.Location).LengthSquared > range * range)
if (!attack.target.IsValid ||
(Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
AttackTarget(self, ChooseTarget(self, range));
var info = self.Info.Traits.Get<AutoTargetInfo>();
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA
return inRange
.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)
.OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault();
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA
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?
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.
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)
{
// 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 radius = selectable != null ? selectable.Radius : 0;
@@ -159,9 +159,12 @@ namespace OpenRA.Mods.RA
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))
return false;
@@ -175,7 +178,7 @@ namespace OpenRA.Mods.RA
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>();
if (info.PrimaryWeapon != null &&