diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index 82be232013..6a05b6a0a4 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -136,6 +136,43 @@ namespace OpenRA.Traits } } + static IEnumerable Neighbours(int2 c, bool allowDiagonal) + { + yield return c; + yield return new int2(c.X - 1, c.Y); + yield return new int2(c.X + 1, c.Y); + yield return new int2(c.X, c.Y - 1); + yield return new int2(c.X, c.Y + 1); + + if (allowDiagonal) + { + yield return new int2(c.X - 1, c.Y - 1); + yield return new int2(c.X + 1, c.Y - 1); + yield return new int2(c.X - 1, c.Y + 1); + yield return new int2(c.X + 1, c.Y + 1); + } + } + + public static IEnumerable ExpandFootprint(IEnumerable cells, bool allowDiagonal) + { + var result = new Dictionary(); + foreach (var c in cells.SelectMany(c => Neighbours(c, allowDiagonal))) + result[c] = true; + return result.Keys; + } + + public static IEnumerable AdjacentCells( Target target ) + { + var cells = target.IsActor + ? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray() + : new int2[] {}; + + if (cells.Length == 0) + cells = new [] { Util.CellContaining(target.CenterLocation) }; + + return Util.ExpandFootprint(cells, true); + } + static int2[] fvecs = { new int2( 0, -1331 ), diff --git a/OpenRA.Mods.RA/Activities/EnterTransport.cs b/OpenRA.Mods.RA/Activities/EnterTransport.cs index 7b4e324131..2b9300591d 100644 --- a/OpenRA.Mods.RA/Activities/EnterTransport.cs +++ b/OpenRA.Mods.RA/Activities/EnterTransport.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Activities // Todo: Queue a move order to the transport? need to be // careful about units that can't path to the transport - if ((transport.Location - self.Location).Length > 1) + if ((transport.Location - self.Location).LengthSquared > 2) return NextActivity; cargo.Load(transport, self); diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs index a073bc4294..7fcc7b87ba 100755 --- a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Mods.RA.Move; using OpenRA.Traits; @@ -20,28 +21,14 @@ namespace OpenRA.Mods.RA.Activities { readonly Target target; - public MoveAdjacentTo( Actor target ) - { - this.target = Target.FromActor(target); - } - - public MoveAdjacentTo( Target target ) - { - this.target = target; - } + public MoveAdjacentTo( Actor target ) { this.target = Target.FromActor(target); } + public MoveAdjacentTo( Target target ) { this.target = target; } public override Activity Tick( Actor self ) { if( IsCanceled || !target.IsValid) return NextActivity; var mobile = self.Trait(); - var cells = new Pair[] {}; - if (target.IsActor) - cells = target.Actor.OccupiesSpace.OccupiedCells().ToArray(); - - if (cells.Length == 0) - cells = new [] { - Pair.New(Util.CellContaining(target.CenterLocation), SubCell.FullCell) }; var ps1 = new PathSearch( self.World, mobile.Info, self.Owner ) { @@ -50,18 +37,17 @@ namespace OpenRA.Mods.RA.Activities inReverse = true }; - foreach( var cell in cells ) - { - ps1.AddInitialCell( cell.First ); - if( ( mobile.toCell - cell.First ).LengthSquared <= 2 ) + foreach( var cell in Util.AdjacentCells(target) ) + if (cell == self.Location) return NextActivity; - } + else + ps1.AddInitialCell( cell ); + ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell ); var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, Util.CellContaining(target.CenterLocation), true ); var ret = self.World.WorldActor.Trait().FindBidiPath( ps1, ps2 ); - if( ret.Count > 0 ) - ret.RemoveAt( 0 ); + return Util.SequenceActivities( mobile.MoveTo( () => ret ), this ); } } diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index c32e5f70ad..6818243b38 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -63,16 +63,23 @@ namespace OpenRA.Mods.RA.Activities return this; var actor = cargo.Unload(self); + var exitPx = Util.CenterOfCell(exitTile.Value); + var currentPx = Util.CenterOfCell(self.Location); self.World.AddFrameEndTask(w => { if (actor.Destroyed) return; var mobile = actor.Trait(); - mobile.SetPosition(actor, self.Location); + mobile.Facing = Util.GetFacing( exitPx - currentPx, mobile.Facing ); + mobile.SetPosition(actor, exitTile.Value); + mobile.AdjustPxPosition(actor, currentPx); + var speed = mobile.MovementSpeedForCell(actor, exitTile.Value); + var length = speed > 0 ? ((int)(exitPx - currentPx).Length * 3 / speed) : 0; w.Add(actor); actor.CancelActivity(); + actor.QueueActivity(new Drag(currentPx, exitPx, length)); actor.QueueActivity(mobile.MoveTo(exitTile.Value, 0)); actor.SetTargetLine(Target.FromCell(exitTile.Value), Color.Green, false); }); diff --git a/OpenRA.Mods.RA/HackyAI.cs b/OpenRA.Mods.RA/HackyAI.cs index 6f1250df00..ea0e079e30 100644 --- a/OpenRA.Mods.RA/HackyAI.cs +++ b/OpenRA.Mods.RA/HackyAI.cs @@ -149,24 +149,6 @@ namespace OpenRA.Mods.RA return null; } - IEnumerable Neighbours(int2 c) - { - /* only return 4-neighbors for now, maybe add 8s later. */ - yield return c; - yield return new int2(c.X - 1, c.Y); - yield return new int2(c.X + 1, c.Y); - yield return new int2(c.X, c.Y - 1); - yield return new int2(c.X, c.Y + 1); - } - - IEnumerable ExpandFootprint(IEnumerable cells) - { - var result = new Dictionary(); - foreach (var c in cells.SelectMany(c => Neighbours(c))) - result[c] = true; - return result.Keys; - } - bool NoBuildingsUnder(IEnumerable cells) { var bi = world.WorldActor.Trait(); @@ -181,8 +163,8 @@ namespace OpenRA.Mods.RA foreach (var t in world.FindTilesInCircle(baseCenter, k)) if (world.CanPlaceBuilding(item.Item, bi, t, null)) if (bi.IsCloseEnoughToBase(world, p, item.Item, t)) - if (NoBuildingsUnder(ExpandFootprint( - FootprintUtils.Tiles( item.Item, bi, t )))) + if (NoBuildingsUnder(Util.ExpandFootprint( + FootprintUtils.Tiles( item.Item, bi, t ), false))) return t; return null; // i don't know where to put it.