diff --git a/OpenRa.Game/BuildingInfluenceMap.cs b/OpenRa.Game/BuildingInfluenceMap.cs new file mode 100644 index 0000000000..4804af4cfa --- /dev/null +++ b/OpenRa.Game/BuildingInfluenceMap.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game +{ + class BuildingInfluenceMap + { + Actor[,] influence = new Actor[128, 128]; + + public BuildingInfluenceMap(World world, Player player) + { + world.ActorAdded += + a => { if (a.traits.Contains() && a.Owner == player) AddInfluence(a); }; + world.ActorRemoved += + a => { if (a.traits.Contains() && a.Owner == player) RemoveInfluence(a); }; + } + + void AddInfluence(Actor a) + { + foreach (var t in Footprint.Tiles(a.unitInfo.Name, a.Location)) + if (IsValid(t)) + influence[t.X, t.Y] = a; + } + + void RemoveInfluence(Actor a) + { + foreach (var t in Footprint.Tiles(a.unitInfo.Name, a.Location)) + if (IsValid(t)) + influence[t.X, t.Y] = null; + } + + bool IsValid(int2 t) + { + return !(t.X < 0 || t.Y < 0 || t.X >= 128 || t.Y >= 128); + } + + public Actor this[int2 cell] { get { return IsValid(cell) ? influence[cell.X, cell.Y] : null; } } + } +} diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 7b0f86365e..f3ed92fe07 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -23,7 +23,8 @@ namespace OpenRa.Game public readonly Dictionary players = new Dictionary(); - public Player LocalPlayer { get { return players[localPlayerIndex]; } } + public Player LocalPlayer { get { return players[localPlayerIndex]; } } + public BuildingInfluenceMap LocalPlayerBuildings; public Game(string mapName, Renderer renderer, int2 clientSize) { @@ -46,7 +47,9 @@ namespace OpenRa.Game pathFinder = new PathFinder(map, terrain.tileSet); - network = new Network(); + network = new Network(); + + LocalPlayerBuildings = new BuildingInfluenceMap(world, LocalPlayer); controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL worldRenderer = new WorldRenderer(renderer, this); @@ -62,11 +65,13 @@ namespace OpenRa.Game public bool IsCellBuildable(int2 a) { + if (LocalPlayerBuildings[a] != null) return false; + a += map.Offset; return map.IsInMap(a.X, a.Y) && - TerrainCosts.Cost(UnitMovementType.Wheel, - terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; + TerrainCosts.Cost(UnitMovementType.Wheel, + terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; } public IEnumerable FindUnits(float2 a, float2 b) diff --git a/OpenRa.Game/GameRules/Footprint.cs b/OpenRa.Game/GameRules/Footprint.cs index 5d6435f4b4..0e3cde75c5 100644 --- a/OpenRa.Game/GameRules/Footprint.cs +++ b/OpenRa.Game/GameRules/Footprint.cs @@ -35,5 +35,23 @@ namespace OpenRa.Game.GameRules buildingFootprints = buildings .ToDictionary(a => a.Name, a => a.Pat); } + + public static IEnumerable Tiles(string name, int2 position) + { + var footprint = Rules.Footprint.GetFootprint(name); + var j = 0; + + foreach (var row in footprint) + { + var i = 0; + foreach (var c in row) + { + if (c != '_') + yield return position + new int2(i, j); + ++i; + } + ++j; + } + } } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 1580c46701..aee4d9b3b5 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -81,6 +81,7 @@ + diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs index b7cbf1ebe5..8cfe685eae 100644 --- a/OpenRa.Game/UiOverlay.cs +++ b/OpenRa.Game/UiOverlay.cs @@ -1,6 +1,7 @@ using System.Drawing; using OpenRa.Game.Graphics; using System; +using OpenRa.Game.GameRules; namespace OpenRa.Game { @@ -36,22 +37,8 @@ namespace OpenRa.Game if (!hasOverlay) return; - var footprint = Rules.Footprint.GetFootprint(name); - var j = 0; - foreach (var row in footprint) - { - var i = 0; - foreach (var c in row) - { - if (c != '_') - spriteRenderer.DrawSprite( - game.IsCellBuildable(position + new int2(i, j)) - ? buildOk : buildBlocked, - 24 * (position + new int2(i, j)), 0); - ++i; - } - ++j; - } + foreach (var t in Footprint.Tiles(name,position)) + spriteRenderer.DrawSprite(game.IsCellBuildable(t) ? buildOk : buildBlocked, 24 * t, 0); spriteRenderer.Flush(); } diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index 3fca98f2e3..31d5bd134e 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -13,11 +13,14 @@ namespace OpenRa.Game int lastTime = Environment.TickCount; const int timestep = 40; - public World(Game game) { this.game = game; } - - public void Add(Actor a) { actors.Add(a); } - public void Remove( Actor a ) { actors.Remove( a ); } - public void AddFrameEndTask( Action a ) { frameEndActions.Add( a ); } + public World(Game game) { this.game = game; } + + public void Add(Actor a) { actors.Add(a); ActorAdded(a); } + public void Remove(Actor a) { actors.Remove(a); ActorRemoved(a); } + public void AddFrameEndTask( Action a ) { frameEndActions.Add( a ); } + + public event Action ActorAdded = _ => { }; + public event Action ActorRemoved = _ => { }; public void Update() {