diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index d42ccd8cc9..2d9a9e0b26 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -16,37 +16,35 @@ namespace OpenRA.Mods.RA.Activities { class Demolish : Activity { - Actor target; + Target target; int delay; - public Demolish( Actor target, int delay ) + public Demolish(Actor target, int delay) { - this.target = target; + this.target = Target.FromActor(target); this.delay = delay; } public override Activity Tick(Actor self) { - if (IsCanceled) return NextActivity; - if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - - if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) + if (IsCanceled || !target.IsValid) return NextActivity; self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () => { // Can't demolish an already dead actor - if (target.IsDead()) + if (!target.IsValid) return; // Invulnerable actors can't be demolished - var modifier = (float)target.TraitsImplementing() + var modifier = (float)target.Actor.TraitsImplementing() .Concat(self.Owner.PlayerActor.TraitsImplementing()) .Select(t => t.GetDamageModifier(self, null)).Product(); - if (target.IsInWorld && modifier > 0) - target.Kill(self); + if (modifier > 0) + target.Actor.Kill(self); }))); + return NextActivity; } } diff --git a/OpenRA.Mods.RA/Activities/DonateSupplies.cs b/OpenRA.Mods.RA/Activities/DonateSupplies.cs index ea9d1e54f4..7a805cc826 100644 --- a/OpenRA.Mods.RA/Activities/DonateSupplies.cs +++ b/OpenRA.Mods.RA/Activities/DonateSupplies.cs @@ -16,26 +16,26 @@ namespace OpenRA.Mods.RA.Activities { class DonateSupplies : Activity { - Actor target; + Target target; int payload; public DonateSupplies(Actor target, int payload) { - this.target = target; + this.target = Target.FromActor(target); this.payload = payload; } public override Activity Tick(Actor self) { - if (IsCanceled) return NextActivity; - if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if (!target.OccupiesSpace.OccupiedCells().Any(x => x.First == self.Location)) + if (IsCanceled || !target.IsValid) return NextActivity; - target.Owner.PlayerActor.Trait().GiveCash(payload); + var targetPlayer = target.Actor.Owner; + targetPlayer.PlayerActor.Trait().GiveCash(payload); self.Destroy(); - if (self.World.LocalPlayer == null || self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally) - self.World.AddFrameEndTask(w => w.Add(new CashTick(payload, 30, 2, target.CenterLocation, target.Owner.ColorRamp.GetColor(0)))); + + if (self.Owner.IsAlliedWith(self.World.RenderPlayer)) + self.World.AddFrameEndTask(w => w.Add(new CashTick(payload, 30, 2, target.CenterLocation, targetPlayer.ColorRamp.GetColor(0)))); return this; } diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index 75c6c27d3b..652e970c63 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Linq; using OpenRA.Mods.RA.Move; using OpenRA.Traits; @@ -15,20 +16,38 @@ namespace OpenRA.Mods.RA.Activities { public class Enter : Activity { - readonly Actor target; - public Enter( Actor target ) { this.target = target; } + readonly Target target; + readonly Activity inner; - public override Activity Tick( Actor self ) + public Enter(Actor target, Activity inner) { - if( IsCanceled || target.Destroyed || !target.IsInWorld ) + this.target = Target.FromActor(target); + this.inner = inner; + } + + public override Activity Tick(Actor self) + { + if (IsCanceled || !target.IsValid) return NextActivity; - var mobile = self.Trait(); - var nearest = target.OccupiesSpace.NearestCellTo( mobile.toCell ); - if( ( nearest - mobile.toCell ).LengthSquared > 2 ) - return Util.SequenceActivities( new MoveAdjacentTo( Target.FromActor(target) ), this ); + if (!Util.AdjacentCells(target).Any(c => c == self.Location)) + return Util.SequenceActivities(new MoveAdjacentTo(target), this); - return Util.SequenceActivities( mobile.MoveTo( nearest, target ), NextActivity ); + // Move to the middle of the target, ignoring impassable tiles + var mobile = self.Trait(); + var to = target.CenterLocation; + var from = self.CenterLocation; + var speed = mobile.MovementSpeedForCell(self, self.Location); + var length = speed > 0 ? (int)((to - from).Length * 3 / speed) : 0; + + return Util.SequenceActivities( + new Turn(Util.GetFacing(to - from, mobile.Facing)), + new Drag(from, to, length), + inner, + new Turn(Util.GetFacing(from - to, mobile.Facing)), + new Drag(to, from, length), + NextActivity + ); } } } diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index b5d82cd3cc..fc9c9cdbdd 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -16,31 +16,23 @@ namespace OpenRA.Mods.RA.Activities { class Infiltrate : Activity { - Actor target; - public Infiltrate(Actor target) { this.target = target; } + Target target; + public Infiltrate(Actor target) { this.target = Target.FromActor(target); } public override Activity Tick(Actor self) { - if (IsCanceled) return NextActivity; - if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if (target.Owner == self.Owner) return NextActivity; - - if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) + if (IsCanceled || !target.IsValid || target.Actor.Owner == self.Owner) return NextActivity; - foreach (var t in target.TraitsImplementing()) - t.OnInfiltrate(target, self); + foreach (var t in target.Actor.TraitsImplementing()) + t.OnInfiltrate(target.Actor, self); if (self.HasTrait()) - self.World.AddFrameEndTask(w => - { - if (self.Destroyed) return; - w.Remove(self); - }); + self.World.AddFrameEndTask(w => { if (!self.Destroyed) w.Remove(self); }); else self.Destroy(); - if (target.HasTrait()) + if (target.Actor.HasTrait()) Sound.PlayToPlayer(self.Owner, "bldginf1.aud"); return this; diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs index 1c07b6d2de..3615d40485 100755 --- a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -17,33 +17,34 @@ namespace OpenRA.Mods.RA.Activities { readonly Target target; - public MoveAdjacentTo( Target target ) { this.target = target; } + public MoveAdjacentTo(Target target) { this.target = target; } - public override Activity Tick( Actor self ) + public override Activity Tick(Actor self) { - if( IsCanceled || !target.IsValid) return NextActivity; + if (IsCanceled || !target.IsValid) + return NextActivity; var mobile = self.Trait(); - - var ps1 = new PathSearch( self.World, mobile.Info, self ) + var ps1 = new PathSearch(self.World, mobile.Info, self) { checkForBlocked = true, heuristic = location => 0, inReverse = true }; - foreach( var cell in Util.AdjacentCells(target) ) + foreach (var cell in Util.AdjacentCells(target)) + { if (cell == self.Location) return NextActivity; else - ps1.AddInitialCell( cell ); + ps1.AddInitialCell(cell); + } - ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell ); + ps1.heuristic = PathSearch.DefaultEstimator(mobile.toCell); + var ps2 = PathSearch.FromPoint(self.World, mobile.Info, self, mobile.toCell, target.CenterLocation.ToCPos(), true); + var ret = self.World.WorldActor.Trait().FindBidiPath(ps1, ps2); - var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self, mobile.toCell, target.CenterLocation.ToCPos(), true ); - var ret = self.World.WorldActor.Trait().FindBidiPath( ps1, ps2 ); - - return Util.SequenceActivities( mobile.MoveTo( () => ret ), this ); + return Util.SequenceActivities(mobile.MoveTo(() => ret), this); } } } diff --git a/OpenRA.Mods.RA/Activities/RepairBuilding.cs b/OpenRA.Mods.RA/Activities/RepairBuilding.cs index 54ffdcad37..8e5e4f4bc6 100644 --- a/OpenRA.Mods.RA/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.RA/Activities/RepairBuilding.cs @@ -15,22 +15,20 @@ namespace OpenRA.Mods.RA.Activities { class RepairBuilding : Activity { - Actor target; + Target target; - public RepairBuilding(Actor target) { this.target = target; } + public RepairBuilding(Actor target) { this.target = Target.FromActor(target); } public override Activity Tick(Actor self) { - if (IsCanceled) return NextActivity; - if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) + if (IsCanceled || !target.IsValid) return NextActivity; - var health = target.Trait(); + var health = target.Actor.Trait(); if (health.DamageState == DamageState.Undamaged) return NextActivity; - target.InflictDamage(self, -health.MaxHP, null); + target.Actor.InflictDamage(self, -health.MaxHP, null); self.Destroy(); return this; diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index 24c2e29483..cd46a527eb 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -52,11 +52,8 @@ namespace OpenRA.Mods.RA { self.SetTargetLine(Target.FromOrder(order), Color.Red); - var mobile = self.Trait(); self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor)); - self.QueueActivity(new Demolish(order.TargetActor, Info.C4Delay)); - self.QueueActivity(mobile.MoveTo(self.Location, 0)); + self.QueueActivity(new Enter(order.TargetActor, new Demolish(order.TargetActor, Info.C4Delay))); } } diff --git a/OpenRA.Mods.RA/EngineerRepair.cs b/OpenRA.Mods.RA/EngineerRepair.cs index 92d4a055e8..1653a52605 100644 --- a/OpenRA.Mods.RA/EngineerRepair.cs +++ b/OpenRA.Mods.RA/EngineerRepair.cs @@ -26,9 +26,9 @@ namespace OpenRA.Mods.RA get { yield return new EngineerRepairOrderTargeter(); } } - public Order IssueOrder( Actor self, IOrderTargeter order, Target target, bool queued ) + public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) { - if( order.OrderID == "EngineerRepair" ) + if (order.OrderID == "EngineerRepair") return new Order(order.OrderID, self, queued) { TargetActor = target.Actor }; return null; @@ -36,41 +36,43 @@ namespace OpenRA.Mods.RA public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "EngineerRepair" - && order.TargetActor.GetDamageState() > DamageState.Undamaged) ? "Attack" : null; + return (order.OrderString == "EngineerRepair" && + order.TargetActor.GetDamageState() > DamageState.Undamaged) ? "Attack" : null; } public void ResolveOrder(Actor self, Order order) { - if (order.OrderString == "EngineerRepair" - && order.TargetActor.GetDamageState() > DamageState.Undamaged) + if (order.OrderString == "EngineerRepair" && + order.TargetActor.GetDamageState() > DamageState.Undamaged) { self.SetTargetLine(Target.FromOrder(order), Color.Yellow); self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor)); - self.QueueActivity(new RepairBuilding(order.TargetActor)); + self.QueueActivity(new Enter(order.TargetActor, new RepairBuilding(order.TargetActor))); } } class EngineerRepairOrderTargeter : UnitTraitOrderTargeter { public EngineerRepairOrderTargeter() - : base( "EngineerRepair", 6, "goldwrench", false, true ) { } + : base("EngineerRepair", 6, "goldwrench", false, true) { } public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor) { - if( !base.CanTargetActor( self, target, forceAttack, forceQueued, ref cursor ) ) return false; + if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor)) + return false; + if (!target.HasTrait()) return false; - if (self.Owner.Stances[ target.Owner ] != Stance.Ally) + if (self.Owner.Stances[target.Owner] != Stance.Ally) return false; IsQueued = forceQueued; - if( target.GetDamageState() == DamageState.Undamaged ) + if (target.GetDamageState() == DamageState.Undamaged) cursor = "goldwrench-blocked"; + return true; } } diff --git a/OpenRA.Mods.RA/Infiltrates.cs b/OpenRA.Mods.RA/Infiltrates.cs index abd59a6b75..94aa3398a3 100644 --- a/OpenRA.Mods.RA/Infiltrates.cs +++ b/OpenRA.Mods.RA/Infiltrates.cs @@ -67,8 +67,7 @@ namespace OpenRA.Mods.RA self.SetTargetLine(Target.FromOrder(order), Color.Red); self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor)); - self.QueueActivity(new Infiltrate(order.TargetActor)); + self.QueueActivity(new Enter(order.TargetActor, new Infiltrate(order.TargetActor))); } } diff --git a/OpenRA.Mods.RA/SupplyTruck.cs b/OpenRA.Mods.RA/SupplyTruck.cs index b14084f622..438740573c 100644 --- a/OpenRA.Mods.RA/SupplyTruck.cs +++ b/OpenRA.Mods.RA/SupplyTruck.cs @@ -59,8 +59,7 @@ namespace OpenRA.Mods.RA { self.SetTargetLine(Target.FromOrder(order), Color.Yellow); self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor)); - self.QueueActivity(new DonateSupplies(order.TargetActor, Info.Payload)); + self.QueueActivity(new Enter(order.TargetActor, new DonateSupplies(order.TargetActor, Info.Payload))); } }