migrating most things to use the Target struct rather than Actor directly.
This commit is contained in:
@@ -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; } }
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
protected override void QueueAttack(Actor self, Order order)
|
||||
{
|
||||
target = order.TargetActor;
|
||||
target = Target.FromActor(order.TargetActor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user