diff --git a/OpenRA.Game/Traits/Activities/Move.cs b/OpenRA.Game/Traits/Activities/Move.cs index 6fd761a956..01e6f1e4f7 100755 --- a/OpenRA.Game/Traits/Activities/Move.cs +++ b/OpenRA.Game/Traits/Activities/Move.cs @@ -15,7 +15,7 @@ using System.Linq; namespace OpenRA.Traits.Activities { - public class Move : CancelableActivity + class Move : CancelableActivity { int2? destination; int nearEnough; diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index 0fc3f342f0..da70dacd63 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -391,5 +391,12 @@ namespace OpenRA.Traits return true; } } + + public IActivity MoveTo( int2 cell ) { return new Move( cell ); } + public IActivity MoveTo( int2 cell, int range ) { return new Move( cell, range ); } + public IActivity MoveTo( int2 cell, Actor ignoredActor ) { return new Move( cell, ignoredActor ); } + public IActivity MoveTo( Actor target, int range ) { return new Move( target, range ); } + public IActivity MoveTo( Target target, int range ) { return new Move( target, range ); } + public IActivity MoveTo( Func> pathFunc ) { return new Move( pathFunc ); } } } diff --git a/OpenRA.Mods.Cnc/Missions/Gdi01Script.cs b/OpenRA.Mods.Cnc/Missions/Gdi01Script.cs index 99d5e1ce66..7bc663e9f2 100644 --- a/OpenRA.Mods.Cnc/Missions/Gdi01Script.cs +++ b/OpenRA.Mods.Cnc/Missions/Gdi01Script.cs @@ -96,10 +96,11 @@ namespace OpenRA.Mods.Cnc new OwnerInit( Players["BadGuy"] ), new FacingInit( 0 ), new LocationInit ( Map.Waypoints["nod0"] ), - }); - a.QueueActivity( new Move( Map.Waypoints["nod1"], 2 ) ); - a.QueueActivity( new Move( Map.Waypoints["nod2"], 2 ) ); - a.QueueActivity( new Move( Map.Waypoints["nod3"], 2 ) ); + }); + var mobile = a.Trait(); + a.QueueActivity( mobile.MoveTo( Map.Waypoints["nod1"], 2 ) ); + a.QueueActivity( mobile.MoveTo( Map.Waypoints["nod2"], 2 ) ); + a.QueueActivity( mobile.MoveTo( Map.Waypoints["nod3"], 2 ) ); // Todo: Queue hunt order } }); @@ -161,10 +162,12 @@ namespace OpenRA.Mods.Cnc } void SetGunboatPath() - { - Actors["Gunboat"].QueueActivity(new Move( Map.Waypoints["gunboatLeft"] )); - Actors["Gunboat"].QueueActivity(new Move( Map.Waypoints["gunboatRight"] )); - Actors["Gunboat"].QueueActivity(new CallFunc(() => SetGunboatPath())); + { + var self = Actors[ "Gunboat" ]; + var mobile = self.Trait(); + self.QueueActivity(mobile.MoveTo( Map.Waypoints["gunboatLeft"] )); + self.QueueActivity(mobile.MoveTo( Map.Waypoints["gunboatRight"] )); + self.QueueActivity(new CallFunc(() => SetGunboatPath())); } void ReinforceFromSea(World world, int2 startPos, int2 endPos, int2 unload, string[] items) @@ -178,8 +181,9 @@ namespace OpenRA.Mods.Cnc new LocationInit( startPos ), new OwnerInit( Players["GoodGuy"] ), new FacingInit( 0 ), - }); - + }); + + var mobile = a.Trait(); var cargo = a.Trait(); foreach (var i in items) cargo.Load(a, world.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary @@ -189,7 +193,7 @@ namespace OpenRA.Mods.Cnc })); a.CancelActivity(); - a.QueueActivity(new Move(endPos)); + a.QueueActivity(mobile.MoveTo(endPos)); a.QueueActivity(new CallFunc(() => { while (!cargo.IsEmpty(a)) @@ -200,12 +204,12 @@ namespace OpenRA.Mods.Cnc if (b.Destroyed) return; w2.Add(b); b.TraitsImplementing().FirstOrDefault().SetPosition(b, a.Location); - b.QueueActivity(new Move(unload, 2)); + b.QueueActivity(mobile.MoveTo(unload, 2)); }); } })); a.QueueActivity(new Wait(25)); - a.QueueActivity(new Move(startPos)); + a.QueueActivity(mobile.MoveTo(startPos)); a.QueueActivity(new RemoveSelf()); }); } diff --git a/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs b/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs index 3eace07818..a3f7c4e58a 100644 --- a/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs +++ b/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs @@ -27,6 +27,7 @@ namespace OpenRA.Mods.Cnc { int2 startDock = harv.Trait().PxPosition; int2 endDock = self.Trait().PxPosition + new int2(-15,8); + var mobile = self.Trait(); var harvester = harv.Trait(); harv.QueueActivity( new Turn(112) ); @@ -53,7 +54,7 @@ namespace OpenRA.Mods.Cnc harv.QueueActivity( new CallFunc( () => dockedHarv = null, false ) ); if (harvester.LastHarvestedCell != int2.Zero) { - harv.QueueActivity( new Move(harvester.LastHarvestedCell, 5) ); + harv.QueueActivity( mobile.MoveTo(harvester.LastHarvestedCell, 5) ); if (harv.Owner == self.World.LocalPlayer) self.World.AddFrameEndTask( w => { diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index b0076573bb..209169dfd8 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -41,10 +41,11 @@ namespace OpenRA.Mods.RA.Activities if (!Target.IsValid) return NextActivity; + var mobile = self.Trait(); var targetCell = Util.CellContaining(Target.CenterLocation); if ((targetCell - self.Location).LengthSquared >= Range * Range) - return Util.SequenceActivities( new Move( Target, Range ), this ); + return Util.SequenceActivities( mobile.MoveTo( Target, Range ), this ); var desiredFacing = Util.GetFacing((targetCell - self.Location).ToFloat2(), 0); var renderUnit = self.TraitOrDefault(); diff --git a/OpenRA.Mods.RA/Activities/DeliverOre.cs b/OpenRA.Mods.RA/Activities/DeliverOre.cs index f6ee49d942..3ed6e9ec78 100755 --- a/OpenRA.Mods.RA/Activities/DeliverOre.cs +++ b/OpenRA.Mods.RA/Activities/DeliverOre.cs @@ -27,6 +27,7 @@ namespace OpenRA.Mods.RA.Activities if( NextActivity != null ) return NextActivity; + var mobile = self.Trait(); var harv = self.Trait(); if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld) @@ -39,7 +40,7 @@ namespace OpenRA.Mods.RA.Activities if( self.Location != proc.Location + proc.Trait().DeliverOffset ) { - return Util.SequenceActivities( new Move(proc.Location + proc.Trait().DeliverOffset, 0), this ); + return Util.SequenceActivities( mobile.MoveTo(proc.Location + proc.Trait().DeliverOffset, 0), this ); } else if (!isDocking) { diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index d10de360cd..e65744eff8 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Linq; using OpenRA.Effects; using OpenRA.Traits; @@ -15,20 +16,21 @@ namespace OpenRA.Mods.RA.Activities { class Demolish : CancelableActivity { - Target target; + Actor target; - public Demolish( Actor target ) { this.target = Target.FromActor(target); } + public Demolish( Actor target ) { this.target = target; } public override IActivity Tick(Actor self) { - if( IsCanceled ) return NextActivity; - if (!target.IsValid) return NextActivity; - if ((target.Actor.Location - self.Location).Length > 1) + if (IsCanceled) return NextActivity; + if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; + if (target.Owner == self.Owner) return NextActivity; + + if( !target.Trait().OccupiedCells().Any( x => x == self.Location ) ) return NextActivity; - self.World.AddFrameEndTask(w => w.Add(new DelayedAction(25 * 2, - () => { if (target.IsValid) target.Actor.Kill(self); }))); + () => { if (target.IsInWorld) target.Kill(self); }))); return NextActivity; } } diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index e7e29210be..d965410c7c 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -28,10 +28,10 @@ namespace OpenRA.Mods.RA.Activities var mobile = self.Trait(); var nearest = target.Trait().NearestCellTo( mobile.toCell ); - if( ( nearest - mobile.toCell ).LengthSquared >= 2 ) + if( ( nearest - mobile.toCell ).LengthSquared > 2 ) return Util.SequenceActivities( new MoveAdjacentTo( target ), this ); - return Util.SequenceActivities( new Move( nearest, target ), NextActivity ); + return Util.SequenceActivities( mobile.MoveTo( nearest, target ), NextActivity ); } } } diff --git a/OpenRA.Mods.RA/Activities/Follow.cs b/OpenRA.Mods.RA/Activities/Follow.cs index 3b2790b178..596589ff75 100644 --- a/OpenRA.Mods.RA/Activities/Follow.cs +++ b/OpenRA.Mods.RA/Activities/Follow.cs @@ -33,9 +33,8 @@ namespace OpenRA.Mods.RA.Activities if( inRange ) return this; - var ret = new Move( Target, Range ); - ret.Queue( this ); - return ret; + var mobile = self.Trait(); + return Util.SequenceActivities( mobile.MoveTo( Target, Range ), this ); } } } diff --git a/OpenRA.Mods.RA/Activities/Harvest.cs b/OpenRA.Mods.RA/Activities/Harvest.cs index c772372d61..0e4428148e 100755 --- a/OpenRA.Mods.RA/Activities/Harvest.cs +++ b/OpenRA.Mods.RA/Activities/Harvest.cs @@ -60,10 +60,11 @@ namespace OpenRA.Mods.RA.Activities void FindMoreResource(Actor self) { + var mobile = self.Trait(); var res = self.World.WorldActor.Trait(); var harv = self.Info.Traits.Get(); var mobileInfo = self.Info.Traits.Get(); - self.QueueActivity(new Move( + self.QueueActivity(mobile.MoveTo( () => { return self.World.PathFinder.FindPath(PathSearch.Search(self.World, mobileInfo, true) diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs index e6bb24ae74..32eedf1053 100644 --- a/OpenRA.Mods.RA/Activities/LayMines.cs +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -23,6 +23,7 @@ namespace OpenRA.Mods.RA.Activities { if (IsCanceled) return NextActivity; + var mobile = self.Trait(); var limitedAmmo = self.TraitOrDefault(); if (!limitedAmmo.HasAmmo()) { @@ -54,7 +55,7 @@ namespace OpenRA.Mods.RA.Activities { var p = ml.minefield.Random(self.World.SharedRandom); if (ShouldLayMine(self, p)) - return Util.SequenceActivities( new Move(p, 0), this ); + return Util.SequenceActivities( mobile.MoveTo(p, 0), this ); } // todo: return somewhere likely to be safe (near fix) so we're not sitting out in the minefield. diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs index 9196797005..66bcc2f695 100755 --- a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.RA.Activities var ret = self.World.PathFinder.FindBidiPath( ps1, ps2 ); if( ret.Count > 0 ) ret.RemoveAt( 0 ); - return Util.SequenceActivities( new Move( () => ret ), this ); + return Util.SequenceActivities( mobile.MoveTo( () => ret ), this ); } } } diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index 01fd871ff2..49b91f8394 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -67,9 +67,11 @@ namespace OpenRA.Mods.RA.Activities { if (actor.Destroyed) return; w.Add(actor); - actor.TraitsImplementing().FirstOrDefault().SetPosition(actor, self.Location); + + var mobile = self.Trait(); + mobile.SetPosition(actor, self.Location); actor.CancelActivity(); - actor.QueueActivity(new Move(exitTile.Value, 0)); + actor.QueueActivity(mobile.MoveTo(exitTile.Value, 0)); if (actor.Owner == self.World.LocalPlayer) { var line = actor.TraitOrDefault(); diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index d2887b8942..87e1952c19 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -53,11 +53,12 @@ namespace OpenRA.Mods.RA line.SetTarget(self, Target.FromOrder(order), Color.Red); }); + var mobile = self.Trait(); self.CancelActivity(); self.QueueActivity(new Enter(order.TargetActor)); //self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); self.QueueActivity(new Demolish(order.TargetActor)); - self.QueueActivity(new Move(self.Location, 0)); + self.QueueActivity(mobile.MoveTo(self.Location, 0)); } } diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index 4e27072c6c..80b9d60524 100644 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -133,8 +133,9 @@ namespace OpenRA.Mods.RA line.SetTarget(self, Target.FromOrder(order), Color.Red); }); + var mobile = self.Trait(); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetLocation, 0)); + self.QueueActivity(mobile.MoveTo(order.TargetLocation, 0)); self.QueueActivity(new Harvest()); } else if (order.OrderString == "Deliver") diff --git a/OpenRA.Mods.RA/OreRefineryDockAction.cs b/OpenRA.Mods.RA/OreRefineryDockAction.cs index 579bc56d9e..6bf34214c5 100644 --- a/OpenRA.Mods.RA/OreRefineryDockAction.cs +++ b/OpenRA.Mods.RA/OreRefineryDockAction.cs @@ -41,7 +41,8 @@ namespace OpenRA.Mods.RA if (harvester.LastHarvestedCell != int2.Zero) { - harv.QueueActivity( new Move(harvester.LastHarvestedCell, 5) ); + var mobile = harv.Trait(); + harv.QueueActivity( mobile.MoveTo(harvester.LastHarvestedCell, 5) ); if (harv.Owner == self.World.LocalPlayer) self.World.AddFrameEndTask( w => { diff --git a/OpenRA.Mods.RA/Passenger.cs b/OpenRA.Mods.RA/Passenger.cs index cd1596ab16..c717a0c969 100644 --- a/OpenRA.Mods.RA/Passenger.cs +++ b/OpenRA.Mods.RA/Passenger.cs @@ -87,8 +87,9 @@ namespace OpenRA.Mods.RA line.SetTarget(self, Target.FromOrder(order), Color.Green); }); + var mobile = self.Trait(); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor.Location, 1)); + self.QueueActivity(mobile.MoveTo(order.TargetActor.Location, 1)); self.QueueActivity(new EnterTransport(self, order.TargetActor)); } } diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index 529bb28068..2894c486e4 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -72,8 +72,7 @@ namespace OpenRA.Mods.RA if (rp != null) { target = rp.rallyPoint; - // Todo: Move implies unit has Mobile - newUnit.QueueActivity(new Move(target, 1)); + newUnit.QueueActivity(mobile.MoveTo(target, 1)); } if (newUnit.Owner == self.World.LocalPlayer) diff --git a/OpenRA.Mods.RA/Repairable.cs b/OpenRA.Mods.RA/Repairable.cs index bfafb4ed18..d6c1f26d6c 100644 --- a/OpenRA.Mods.RA/Repairable.cs +++ b/OpenRA.Mods.RA/Repairable.cs @@ -72,6 +72,7 @@ namespace OpenRA.Mods.RA if( !CanRepairAt( order.TargetActor ) || !CanRepair() ) return; + var mobile = self.Trait(); var rp = order.TargetActor.TraitOrDefault(); if (self.Owner == self.World.LocalPlayer) @@ -85,13 +86,13 @@ namespace OpenRA.Mods.RA }); self.CancelActivity(); - self.QueueActivity(new Move(Util.CellContaining(order.TargetActor.CenterLocation), order.TargetActor)); + self.QueueActivity(mobile.MoveTo(Util.CellContaining(order.TargetActor.CenterLocation), order.TargetActor)); self.QueueActivity(new Rearm()); self.QueueActivity(new Repair(order.TargetActor)); if (rp != null) self.QueueActivity(new CallFunc( - () => self.QueueActivity(new Move(rp.rallyPoint, order.TargetActor)))); + () => self.QueueActivity(mobile.MoveTo(rp.rallyPoint, order.TargetActor)))); } } } diff --git a/OpenRA.Mods.RA/RepairableNear.cs b/OpenRA.Mods.RA/RepairableNear.cs index 55769aede8..cfbdd8885d 100644 --- a/OpenRA.Mods.RA/RepairableNear.cs +++ b/OpenRA.Mods.RA/RepairableNear.cs @@ -63,8 +63,9 @@ namespace OpenRA.Mods.RA { if (order.OrderString == "RepairNear" && CanRepairAt(order.TargetActor) && ShouldRepair()) { + var mobile = self.Trait(); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor, 1)); + self.QueueActivity(mobile.MoveTo(order.TargetActor, 1)); if (self.Owner == self.World.LocalPlayer) self.World.AddFrameEndTask( w => {