diff --git a/OpenRA.Game/PathFinder.cs b/OpenRA.Game/PathFinder.cs index b7ca1758a4..718c023bd1 100644 --- a/OpenRA.Game/PathFinder.cs +++ b/OpenRA.Game/PathFinder.cs @@ -40,7 +40,7 @@ namespace OpenRA public List FindUnitPath(int2 from, int2 target, Actor self) { - using (new PerfSample("find_unit_path")) + using (new PerfSample("Pathfinder")) { var cached = CachedPaths.FirstOrDefault(p => p.from == from && p.to == target && p.actor == self); if (cached != null) @@ -69,7 +69,7 @@ namespace OpenRA public List FindUnitPathToRange( int2 src, int2 target, int range, Actor self ) { - using( new PerfSample( "find_unit_path_multiple_src" ) ) + using( new PerfSample( "Pathfinder" ) ) { var mobileInfo = self.Info.Traits.Get(); var tilesInRange = world.FindTilesInCircle(target, range) @@ -93,7 +93,7 @@ namespace OpenRA public List FindPath( PathSearch search ) { - //using (new PerfSample("find_path_inner")) + using (new PerfSample("Pathfinder")) { while (!search.queue.Empty) { @@ -127,26 +127,29 @@ namespace OpenRA - List FindBidiPath( /* searches from both ends toward each other */ + public List FindBidiPath( /* searches from both ends toward each other */ PathSearch fromSrc, PathSearch fromDest) { - while (!fromSrc.queue.Empty && !fromDest.queue.Empty) + using (new PerfSample("Pathfinder")) { - /* make some progress on the first search */ - var p = fromSrc.Expand( world ); + while (!fromSrc.queue.Empty && !fromDest.queue.Empty) + { + /* make some progress on the first search */ + var p = fromSrc.Expand( world ); - if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity) - return MakeBidiPath(fromSrc, fromDest, p); + if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity) + return MakeBidiPath(fromSrc, fromDest, p); - /* make some progress on the second search */ - var q = fromDest.Expand( world ); + /* make some progress on the second search */ + var q = fromDest.Expand( world ); - if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity) - return MakeBidiPath(fromSrc, fromDest, q); + if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity) + return MakeBidiPath(fromSrc, fromDest, q); + } + + return new List(); } - - return new List(); } static List MakeBidiPath(PathSearch a, PathSearch b, int2 p) diff --git a/OpenRA.Game/PathSearch.cs b/OpenRA.Game/PathSearch.cs index 9a2ae8410a..2d4b73e3df 100755 --- a/OpenRA.Game/PathSearch.cs +++ b/OpenRA.Game/PathSearch.cs @@ -72,7 +72,7 @@ namespace OpenRA public PathSearch FromPoint(int2 from) { - AddInitialCell( world, from ); + AddInitialCell( from ); return this; } @@ -155,7 +155,7 @@ namespace OpenRA new int2( 1, 1 ), }; - public void AddInitialCell( World world, int2 location ) + public void AddInitialCell( int2 location ) { if (!world.Map.IsInMap(location.X, location.Y)) return; @@ -177,7 +177,7 @@ namespace OpenRA heuristic = DefaultEstimator( target ), checkForBlocked = checkForBlocked }; - search.AddInitialCell( world, from ); + search.AddInitialCell( from ); return search; } @@ -189,8 +189,8 @@ namespace OpenRA checkForBlocked = checkForBlocked }; - foreach (var sl in froms) - search.AddInitialCell(world, sl); + foreach( var sl in froms ) + search.AddInitialCell( sl ); return search; } diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs new file mode 100755 index 0000000000..e7e29210be --- /dev/null +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -0,0 +1,37 @@ +#region Copyright & License Information +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Traits; +using OpenRA.Traits.Activities; + +namespace OpenRA.Mods.RA.Activities +{ + public class Enter : CancelableActivity + { + readonly Actor target; + public Enter( Actor target ) { this.target = target; } + + public override IActivity Tick( Actor self ) + { + if( IsCanceled || target.Destroyed || !target.IsInWorld ) + return NextActivity; + + var mobile = self.Trait(); + var nearest = target.Trait().NearestCellTo( mobile.toCell ); + if( ( nearest - mobile.toCell ).LengthSquared >= 2 ) + return Util.SequenceActivities( new MoveAdjacentTo( target ), this ); + + return Util.SequenceActivities( new Move( nearest, target ), NextActivity ); + } + } +} diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs index 813aff2454..e6bb24ae74 100644 --- a/OpenRA.Mods.RA/Activities/LayMines.cs +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -35,7 +35,8 @@ namespace OpenRA.Mods.RA.Activities return new Wait(20); return Util.SequenceActivities( - new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget), + new Enter(rearmTarget), + //new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget), new Rearm(), new Repair(rearmTarget), this ); diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs new file mode 100755 index 0000000000..9196797005 --- /dev/null +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -0,0 +1,54 @@ +#region Copyright & License Information +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Traits; +using OpenRA.Traits.Activities; + +namespace OpenRA.Mods.RA.Activities +{ + public class MoveAdjacentTo : CancelableActivity + { + readonly Actor target; + + public MoveAdjacentTo( Actor target ) + { + this.target = target; + } + + public override IActivity Tick( Actor self ) + { + if( IsCanceled || target.Destroyed || !target.IsInWorld) return NextActivity; + + var mobile = self.Trait(); + var ps1 = new PathSearch( self.World, mobile.Info ) + { + checkForBlocked = true, + heuristic = location => 0, + inReverse = true + }; + foreach( var cell in target.Trait().OccupiedCells() ) + { + ps1.AddInitialCell( cell ); + if( ( mobile.toCell - cell ).LengthSquared <= 2 ) + return NextActivity; + } + ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell ); + + var ps2 = PathSearch.FromPoint( self.World, mobile.Info, mobile.toCell, target.Location, true ); + var ret = self.World.PathFinder.FindBidiPath( ps1, ps2 ); + if( ret.Count > 0 ) + ret.RemoveAt( 0 ); + return Util.SequenceActivities( new Move( () => ret ), this ); + } + } +} diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index 7c8e91d0fb..d2887b8942 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -54,7 +54,8 @@ namespace OpenRA.Mods.RA }); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); + 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)); } diff --git a/OpenRA.Mods.RA/EngineerCapture.cs b/OpenRA.Mods.RA/EngineerCapture.cs index 2e9b0d9a8b..657f8e19df 100644 --- a/OpenRA.Mods.RA/EngineerCapture.cs +++ b/OpenRA.Mods.RA/EngineerCapture.cs @@ -58,7 +58,8 @@ namespace OpenRA.Mods.RA }); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); + self.QueueActivity(new Enter(order.TargetActor)); + //self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); self.QueueActivity(new CaptureBuilding(order.TargetActor)); } } diff --git a/OpenRA.Mods.RA/EngineerRepair.cs b/OpenRA.Mods.RA/EngineerRepair.cs index 9bc3c955f8..51422159da 100644 --- a/OpenRA.Mods.RA/EngineerRepair.cs +++ b/OpenRA.Mods.RA/EngineerRepair.cs @@ -57,7 +57,8 @@ namespace OpenRA.Mods.RA }); self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); + self.QueueActivity(new Enter(order.TargetActor)); + //self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor)); self.QueueActivity(new RepairBuilding(order.TargetActor)); } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 64bb95340e..c4281dff74 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -57,6 +57,7 @@ + @@ -70,6 +71,7 @@ + diff --git a/OpenRA.Mods.RA/Spy.cs b/OpenRA.Mods.RA/Spy.cs index f873c4a142..9c6a5e6af6 100644 --- a/OpenRA.Mods.RA/Spy.cs +++ b/OpenRA.Mods.RA/Spy.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA if (order.OrderString == "SpyInfiltrate") { self.CancelActivity(); - self.QueueActivity(new Move(order.TargetActor, 1)); + self.QueueActivity(new MoveAdjacentTo(order.TargetActor)); if (self.Owner == self.World.LocalPlayer) self.World.AddFrameEndTask( w => {