diff --git a/OpenRA.Game/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Game/Orders/PlaceBuildingOrderGenerator.cs index 1cd1e6db1f..98359589a0 100644 --- a/OpenRA.Game/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Game/Orders/PlaceBuildingOrderGenerator.cs @@ -21,7 +21,6 @@ using System.Collections.Generic; using OpenRA.GameRules; using OpenRA.Traits; -using System.Linq; namespace OpenRA.Orders { @@ -63,37 +62,8 @@ namespace OpenRA.Orders // Linebuild for walls. // Assumes a 1x1 footprint; weird things will happen for other footprints if (Rules.Info[ Building ].Traits.Contains()) - { - int range = Rules.Info[ Building ].Traits.Get().Range; - - // Start at place location, search outwards - // TODO: First make it work, then make it nice - int[] dirs = {0,0,0,0}; - for (int d = 0; d < 4; d++) - { - for (int i = 1; i < range; i++) - { - if (dirs[d] != 0) - continue; - - int2 cell = world.OffsetCell(topLeft,i,d); - - if (world.IsCellBuildable(cell, BuildingInfo.WaterBound ? UnitMovementType.Float : UnitMovementType.Wheel,null)) - continue; // Cell is empty; continue search - - // Cell contains an actor. Is it the type we want? - if (world.Queries.WithTrait().Any(a => (a.Actor.Info.Name == Building && a.Actor.Location.X == cell.X && a.Actor.Location.Y == cell.Y))) - dirs[d] = i; // Cell contains actor of correct type - else - dirs[d] = -1; // Cell is blocked by another actor type - } - - // Place intermediate-line sections - if (dirs[d] > 0) - for (int i = 1; i < dirs[d]; i++) - yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, world.OffsetCell(topLeft,i,d), Building); - } - } + foreach( var t in LineBuildUtils.GetLineBuildCells( world, topLeft, Building, BuildingInfo )) + yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, t, Building); } } diff --git a/OpenRA.Game/UiOverlay.cs b/OpenRA.Game/UiOverlay.cs index 4a36b6d170..5e8865b42a 100644 --- a/OpenRA.Game/UiOverlay.cs +++ b/OpenRA.Game/UiOverlay.cs @@ -18,6 +18,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.GameRules; @@ -77,43 +78,49 @@ namespace OpenRA // Linebuild for walls. // Assumes a 1x1 footprint; weird things will happen for other footprints if (Rules.Info[ name ].Traits.Contains()) - { - int range = Rules.Info[ name ].Traits.Get().Range; - - // Start at place location, search outwards - // TODO: First make it work, then make it nice - int[] dirs = {0,0,0,0}; - for (int d = 0; d < 4; d++) - { - for (int i = 1; i < range; i++) - { - if (dirs[d] != 0) - continue; - - int2 cell = world.OffsetCell(topLeft,i,d); - - if (world.IsCellBuildable(cell, bi.WaterBound ? UnitMovementType.Float : UnitMovementType.Wheel,null)) - continue; // Cell is empty; continue search - - // Cell contains an actor. Is it the type we want? - if (Game.world.Queries.WithTrait().Any(a => (a.Actor.Info.Name == name && a.Actor.Location.X == cell.X && a.Actor.Location.Y == cell.Y))) - dirs[d] = i; // Cell contains actor of correct type - else - dirs[d] = -1; // Cell is blocked by another actor type - } - - // Place intermediate-line sections - if (dirs[d] > 0) - { - for (int i = 1; i < dirs[d]; i++) - { - int2 cell = world.OffsetCell(topLeft,i,d); - spriteRenderer.DrawSprite( world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, cell) ? buildOk : buildBlocked, Game.CellSize * cell, "terrain" ); - } - } - } - } + foreach( var t in LineBuildUtils.GetLineBuildCells(world, topLeft, name, bi ) ) + spriteRenderer.DrawSprite(world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, t) + ? buildOk : buildBlocked, Game.CellSize * t, "terrain"); + spriteRenderer.Flush(); } } + + static class LineBuildUtils + { + public static IEnumerable GetLineBuildCells(World world, int2 location, string name, BuildingInfo bi) + { + int range = Rules.Info[name].Traits.Get().Range; + var topLeft = location; // 1x1 assumption! + + // Start at place location, search outwards + // TODO: First make it work, then make it nice + var vecs = new[] { new int2(1, 0), new int2(0, 1), new int2(-1, 0), new int2(0, -1) }; + int[] dirs = { 0, 0, 0, 0 }; + for (int d = 0; d < 4; d++) + { + for (int i = 1; i < range; i++) + { + if (dirs[d] != 0) + continue; + + int2 cell = world.OffsetCell(topLeft, i, d); + + if (world.IsCellBuildable(cell, bi.WaterBound ? UnitMovementType.Float : UnitMovementType.Wheel, null)) + continue; // Cell is empty; continue search + + // Cell contains an actor. Is it the type we want? + if (Game.world.Queries.WithTrait().Any(a => (a.Actor.Info.Name == name && a.Actor.Location.X == cell.X && a.Actor.Location.Y == cell.Y))) + dirs[d] = i; // Cell contains actor of correct type + else + dirs[d] = -1; // Cell is blocked by another actor type + } + + // Place intermediate-line sections + if (dirs[d] > 0) + for (int i = 1; i < dirs[d]; i++) + yield return topLeft + i * vecs[d]; + } + } + } }