From 4614f6febe0fca0c2acf11e68d4721957874a4e0 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 May 2020 00:20:48 +0100 Subject: [PATCH] Cache cell ramps to avoid repeated tileset lookups. --- OpenRA.Game/Graphics/Viewport.cs | 10 +------ OpenRA.Game/Map/Map.cs | 29 +++++++++++++++---- .../Traits/Buildings/BuildingUtils.cs | 10 ++----- .../Conditions/GrantConditionOnDeploy.cs | 12 ++------ .../Traits/World/JumpjetActorLayer.cs | 4 +-- .../Traits/World/LegacyBridgeLayer.cs | 8 +++-- .../Traits/World/ResourceLayer.cs | 10 +------ .../Traits/World/SubterraneanActorLayer.cs | 4 +-- .../Traits/World/TerrainGeometryOverlay.cs | 6 +--- 9 files changed, 37 insertions(+), 56 deletions(-) diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index ee6cd61b65..4affc0156c 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -254,7 +254,6 @@ namespace OpenRA.Graphics var world = worldRenderer.Viewport.ViewToWorldPx(view); var map = worldRenderer.World.Map; var candidates = CandidateMouseoverCells(world).ToList(); - var tileSet = worldRenderer.World.Map.Rules.TileSet; foreach (var uv in candidates) { @@ -263,14 +262,7 @@ namespace OpenRA.Graphics var s = worldRenderer.ScreenPxPosition(p); if (Math.Abs(s.X - world.X) <= tileSize.Width && Math.Abs(s.Y - world.Y) <= tileSize.Height) { - var ramp = 0; - if (map.Contains(uv)) - { - var ti = tileSet.GetTileInfo(map.Tiles[uv]); - if (ti != null) - ramp = ti.RampType; - } - + var ramp = map.Ramp.Contains(uv) ? map.Ramp[uv] : 0; var corners = map.Grid.CellCorners[ramp]; var pos = map.CenterOfCell(uv.ToCPos(map)); var screen = corners.Select(c => worldRenderer.ScreenPxPosition(pos + c)).ToArray(); diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index bc9912addb..3b66521130 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -230,6 +230,7 @@ namespace OpenRA public CellLayer Tiles { get; private set; } public CellLayer Resources { get; private set; } public CellLayer Height { get; private set; } + public CellLayer Ramp { get; private set; } public CellLayer CustomTerrain { get; private set; } public ProjectedCellRegion ProjectedCellBounds { get; private set; } @@ -301,10 +302,12 @@ namespace OpenRA Tiles = new CellLayer(Grid.Type, size); Resources = new CellLayer(Grid.Type, size); Height = new CellLayer(Grid.Type, size); + Ramp = new CellLayer(Grid.Type, size); if (Grid.MaximumTerrainHeight > 0) { Height.CellEntryChanged += UpdateProjection; Tiles.CellEntryChanged += UpdateProjection; + Tiles.CellEntryChanged += UpdateRamp; } Tiles.Clear(tileRef); @@ -336,6 +339,7 @@ namespace OpenRA Tiles = new CellLayer(Grid.Type, size); Resources = new CellLayer(Grid.Type, size); Height = new CellLayer(Grid.Type, size); + Ramp = new CellLayer(Grid.Type, size); using (var s = Package.GetStream("map.bin")) { @@ -384,6 +388,7 @@ namespace OpenRA if (Grid.MaximumTerrainHeight > 0) { + Tiles.CellEntryChanged += UpdateRamp; Tiles.CellEntryChanged += UpdateProjection; Height.CellEntryChanged += UpdateProjection; } @@ -422,9 +427,23 @@ namespace OpenRA foreach (var uv in AllCells.MapCoords) CustomTerrain[uv] = byte.MaxValue; + // Cache initial ramp state + var tileset = Rules.TileSet; + foreach (var uv in AllCells) + { + var tile = tileset.GetTileInfo(Tiles[uv]); + Ramp[uv] = tile != null ? tile.RampType : (byte)0; + } + AllEdgeCells = UpdateEdgeCells(); } + void UpdateRamp(CPos cell) + { + var tile = Rules.TileSet.GetTileInfo(Tiles[cell]); + Ramp[cell] = tile != null ? tile.RampType : (byte)0; + } + void InitializeCellProjection() { if (initializedCellProjection) @@ -531,12 +550,8 @@ namespace OpenRA return new[] { (PPos)uv }; // Odd-height ramps get bumped up a level to the next even height layer - if ((height & 1) == 1) - { - var ti = Rules.TileSet.GetTileInfo(Tiles[uv]); - if (ti != null && ti.RampType != 0) - height += 1; - } + if ((height & 1) == 1 && Ramp[uv] != 0) + height += 1; var candidates = new List(); @@ -913,11 +928,13 @@ namespace OpenRA var oldMapTiles = Tiles; var oldMapResources = Resources; var oldMapHeight = Height; + var oldMapRamp = Ramp; var newSize = new Size(width, height); Tiles = CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]); Resources = CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]); Height = CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]); + Ramp = CellLayer.Resize(oldMapRamp, newSize, oldMapHeight[MPos.Zero]); MapSize = new int2(newSize); var tl = new MPos(0, 0); diff --git a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs index b48ff39e3d..80479c33a6 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs @@ -39,14 +39,8 @@ namespace OpenRA.Mods.Common.Traits else if (!bi.AllowInvalidPlacement && world.ActorMap.GetActorsAt(cell).Any(a => a != toIgnore)) return false; - var tile = world.Map.Tiles[cell]; - var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile); - - // TODO: This is bandaiding over bogus tilesets. - if (tileInfo != null && tileInfo.RampType > 0) - return false; - - return bi.TerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type); + // Buildings can never be placed on ramps + return world.Map.Ramp[cell] == 0 && bi.TerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type); } public static bool CanPlaceBuilding(this World world, CPos cell, ActorInfo ai, BuildingInfo bi, Actor toIgnore) diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs index 0b3a237e9b..0e5b964e09 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs @@ -241,16 +241,8 @@ namespace OpenRA.Mods.Common.Traits if (Info.CanDeployOnRamps) return true; - var ramp = 0; - if (self.World.Map.Contains(location)) - { - var tile = self.World.Map.Tiles[location]; - var ti = self.World.Map.Rules.TileSet.GetTileInfo(tile); - if (ti != null) - ramp = ti.RampType; - } - - return ramp == 0; + var map = self.World.Map; + return !map.Ramp.Contains(location) || map.Ramp[location] == 0; } void INotifyDeployComplete.FinishedDeploy(Actor self) diff --git a/OpenRA.Mods.Common/Traits/World/JumpjetActorLayer.cs b/OpenRA.Mods.Common/Traits/World/JumpjetActorLayer.cs index 64fe1c2cce..45357b94d5 100644 --- a/OpenRA.Mods.Common/Traits/World/JumpjetActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/JumpjetActorLayer.cs @@ -83,9 +83,7 @@ namespace OpenRA.Mods.Common.Traits if (jli.JumpjetTransitionOnRamps) return true; - var tile = map.Tiles[cell]; - var ti = map.Rules.TileSet.GetTileInfo(tile); - return ti == null || ti.RampType == 0; + return map.Ramp[cell] == 0; } int ICustomMovementLayer.EntryMovementCost(ActorInfo a, LocomotorInfo li, CPos cell) diff --git a/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs b/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs index b32d3f99e0..890fad8f47 100644 --- a/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs @@ -65,8 +65,9 @@ namespace OpenRA.Mods.Common.Traits return; // Correlate the tile "image" aka subtile with its position to find the template origin - var tile = w.Map.Tiles[cell].Type; - var index = w.Map.Tiles[cell].Index; + var ti = w.Map.Tiles[cell]; + var tile = ti.Type; + var index = ti.Index; var template = w.Map.Rules.TileSet.Templates[tile]; var ni = cell.X - index % template.Size.X; var nj = cell.Y - index / template.Size.X; @@ -89,7 +90,8 @@ namespace OpenRA.Mods.Common.Traits var subtile = new CPos(ni + ind % template.Size.X, nj + ind / template.Size.X); // This isn't the bridge you're looking for - if (!mapTiles.Contains(subtile) || mapTiles[subtile].Type != tile || mapTiles[subtile].Index != ind) + var subti = mapTiles[subtile]; + if (!mapTiles.Contains(subtile) || subti.Type != tile || subti.Index != ind) continue; subTiles.Add(subtile, ind); diff --git a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs index 89156f0e6e..28398ed0ef 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs @@ -109,15 +109,7 @@ namespace OpenRA.Mods.Common.Traits if (!rt.Info.AllowUnderBuildings && buildingInfluence.GetBuildingAt(cell) != null) return false; - if (!rt.Info.AllowOnRamps) - { - var tile = world.Map.Tiles[cell]; - var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile); - if (tileInfo != null && tileInfo.RampType > 0) - return false; - } - - return true; + return rt.Info.AllowOnRamps || world.Map.Ramp[cell] == 0; } public bool CanSpawnResourceAt(ResourceType newResourceType, CPos cell) diff --git a/OpenRA.Mods.Common/Traits/World/SubterraneanActorLayer.cs b/OpenRA.Mods.Common/Traits/World/SubterraneanActorLayer.cs index c9c5314cc3..316c986c5b 100644 --- a/OpenRA.Mods.Common/Traits/World/SubterraneanActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/SubterraneanActorLayer.cs @@ -82,9 +82,7 @@ namespace OpenRA.Mods.Common.Traits if (sli.SubterraneanTransitionOnRamps) return true; - var tile = map.Tiles[cell]; - var ti = map.Rules.TileSet.GetTileInfo(tile); - return ti == null || ti.RampType == 0; + return map.Ramp[cell] == 0; } int ICustomMovementLayer.EntryMovementCost(ActorInfo a, LocomotorInfo li, CPos cell) diff --git a/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs b/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs index e286cfcccf..f539700eb9 100644 --- a/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs +++ b/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs @@ -63,11 +63,7 @@ namespace OpenRA.Mods.Common.Traits continue; var height = (int)map.Height[uv]; - var tile = map.Tiles[uv]; - var ti = tileSet.GetTileInfo(tile); - var ramp = ti != null ? ti.RampType : 0; - - var corners = map.Grid.CellCorners[ramp]; + var corners = map.Grid.CellCorners[map.Ramp[uv]]; var pos = map.CenterOfCell(uv.ToCPos(map)); var width = uv == mouseCell ? 3 : 1;