From 5c61c9d3a9d50ef758fbf264b542fcfad23d66bf Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 5 Jul 2010 18:25:10 +1200 Subject: [PATCH] migrating most things to use the Target struct rather than Actor directly. --- OpenRA.Game/Traits/TraitsInterfaces.cs | 9 +++++---- OpenRA.Mods.RA/Activities/Attack.cs | 16 +++++++++------- OpenRA.Mods.RA/Activities/Leap.cs | 15 +++++++++------ OpenRA.Mods.RA/AttackBase.cs | 18 ++++++++---------- OpenRA.Mods.RA/AttackFrontal.cs | 2 +- OpenRA.Mods.RA/AttackHeli.cs | 2 +- OpenRA.Mods.RA/AttackLeap.cs | 4 ++-- OpenRA.Mods.RA/AttackOmni.cs | 2 +- OpenRA.Mods.RA/AttackPlane.cs | 2 +- OpenRA.Mods.RA/AttackTesla.cs | 4 ++-- OpenRA.Mods.RA/AttackTurreted.cs | 4 ++-- OpenRA.Mods.RA/AutoHeal.cs | 9 +++++---- OpenRA.Mods.RA/AutoTarget.cs | 8 ++++---- OpenRA.Mods.RA/Combat.cs | 11 +++++++---- 14 files changed, 57 insertions(+), 49 deletions(-) diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index e39224926e..4832981243 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -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; } } diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index 3a15114457..7ea3d9e195 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -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(); - 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(); 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(); } } } diff --git a/OpenRA.Mods.RA/Activities/Leap.cs b/OpenRA.Mods.RA/Activities/Leap.cs index 25f0b8ff80..3f71ccfbdd 100644 --- a/OpenRA.Mods.RA/Activities/Leap.cs +++ b/OpenRA.Mods.RA/Activities/Leap.cs @@ -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().FirstOrDefault().SetPosition(self, target.Location); - target.InflictDamage(self, target.Health, null); // kill it + self.traits.WithInterface().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; } } } diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index 24cc5579eb..262845ce68 100755 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -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().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(); + var destUnit = target.IsActor ? target.Actor.traits.GetOrDefault() : 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))); } } diff --git a/OpenRA.Mods.RA/AttackFrontal.cs b/OpenRA.Mods.RA/AttackFrontal.cs index 9c9a4627fb..94ff6874f3 100644 --- a/OpenRA.Mods.RA/AttackFrontal.cs +++ b/OpenRA.Mods.RA/AttackFrontal.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA { base.Tick(self); - if (target == null) return; + if (!target.IsValid) return; var unit = self.traits.Get(); var facingToTarget = Util.GetFacing(target.CenterLocation - self.CenterLocation, unit.Facing); diff --git a/OpenRA.Mods.RA/AttackHeli.cs b/OpenRA.Mods.RA/AttackHeli.cs index aae1991a50..6fe592ec7a 100644 --- a/OpenRA.Mods.RA/AttackHeli.cs +++ b/OpenRA.Mods.RA/AttackHeli.cs @@ -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)); } } diff --git a/OpenRA.Mods.RA/AttackLeap.cs b/OpenRA.Mods.RA/AttackLeap.cs index c75ac2594a..d16cabcd9a 100644 --- a/OpenRA.Mods.RA/AttackLeap.cs +++ b/OpenRA.Mods.RA/AttackLeap.cs @@ -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)); diff --git a/OpenRA.Mods.RA/AttackOmni.cs b/OpenRA.Mods.RA/AttackOmni.cs index 27fe99af8a..09f81f2dcd 100644 --- a/OpenRA.Mods.RA/AttackOmni.cs +++ b/OpenRA.Mods.RA/AttackOmni.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA protected override void QueueAttack(Actor self, Order order) { - target = order.TargetActor; + target = Target.FromActor(order.TargetActor); } } } diff --git a/OpenRA.Mods.RA/AttackPlane.cs b/OpenRA.Mods.RA/AttackPlane.cs index 89e5e4c84e..21a84fa38a 100644 --- a/OpenRA.Mods.RA/AttackPlane.cs +++ b/OpenRA.Mods.RA/AttackPlane.cs @@ -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)); } } diff --git a/OpenRA.Mods.RA/AttackTesla.cs b/OpenRA.Mods.RA/AttackTesla.cs index 82e88000f8..d8448c60b6 100644 --- a/OpenRA.Mods.RA/AttackTesla.cs +++ b/OpenRA.Mods.RA/AttackTesla.cs @@ -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().PlayCharge( self ); return base.FireDelay( self, info ); } diff --git a/OpenRA.Mods.RA/AttackTurreted.cs b/OpenRA.Mods.RA/AttackTurreted.cs index 282bca28c4..e7d9b53a77 100644 --- a/OpenRA.Mods.RA/AttackTurreted.cs +++ b/OpenRA.Mods.RA/AttackTurreted.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA if( self.traits.Contains() && !buildComplete ) return false; - if (target == null) return false; + if (!target.IsValid) return false; var turreted = self.traits.Get(); 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); } diff --git a/OpenRA.Mods.RA/AutoHeal.cs b/OpenRA.Mods.RA/AutoHeal.cs index f8f30354c8..5ac26a9f3a 100644 --- a/OpenRA.Mods.RA/AutoHeal.cs +++ b/OpenRA.Mods.RA/AutoHeal.cs @@ -33,11 +33,12 @@ namespace OpenRA.Mods.RA var attack = self.traits.Get(); 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().HP) + if (attack.target.IsActor && attack.target.Actor.Health + == attack.target.Actor.Info.Traits.Get().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().HP) .OrderBy(a => (a.Location - self.Location).LengthSquared) .FirstOrDefault(); diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index d6deecfa56..8ef987e9bf 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -40,8 +40,8 @@ namespace OpenRA.Mods.RA var attack = self.traits.Get(); 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(); @@ -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() || !a.traits.Get().Cloaked) .OrderBy(a => (a.Location - self.Location).LengthSquared) .FirstOrDefault(); @@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA if (!e.Attacker.Info.Traits.Contains()) 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; diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 06834479c8..10ed1ef7a8 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -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(); 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(); + // todo: fix this properly. + if (!target.IsValid || !target.IsActor) return false; + + var ownedInfo = target.Actor.Info.Traits.GetOrDefault(); 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(); if (info.PrimaryWeapon != null &&