|
8 | 8 |
|
9 | 9 | namespace C7.Map { |
10 | 10 |
|
| 11 | + public static class MapZIndex { |
| 12 | + public static readonly int Tiles = 10; |
| 13 | + public static readonly int Cities = 20; |
| 14 | + public static readonly int Cursor = 29; |
| 15 | + public static readonly int Units = 30; |
| 16 | + public static readonly int FogOfWar = 100; |
| 17 | + } |
| 18 | + |
11 | 19 | public partial class MapView : Node2D { |
12 | 20 | private string[,]terrain; |
13 | 21 | private TileMap terrainTilemap; |
@@ -155,10 +163,15 @@ private void initializeTileMap() { |
155 | 163 | if (layer != Layer.Invalid) { |
156 | 164 | tilemap.AddLayer(layer.Index()); |
157 | 165 | tilemap.SetLayerYSortEnabled(layer.Index(), true); |
| 166 | + if (layer != Layer.FogOfWar) { |
| 167 | + tilemap.SetLayerYSortEnabled(layer.Index(), true); |
| 168 | + } else { |
| 169 | + tilemap.SetLayerZIndex(layer.Index(), MapZIndex.FogOfWar); |
| 170 | + } |
158 | 171 | } |
159 | 172 | } |
160 | 173 |
|
161 | | - tilemap.ZIndex = 10; // need to figure out a good way to order z indices |
| 174 | + tilemap.ZIndex = MapZIndex.Tiles; |
162 | 175 | AddChild(tilemap); |
163 | 176 | AddChild(terrainTilemap); |
164 | 177 | // AddChild(terrainTilemapShadow); |
@@ -241,8 +254,9 @@ public MapView(Game game, GameData data) { |
241 | 254 | setTerrainTiles(); |
242 | 255 |
|
243 | 256 | // update each tile once to add all initial layers |
| 257 | + TileKnowledge tk = data.GetHumanPlayers().First()?.tileKnowledge; |
244 | 258 | foreach (Tile tile in gameMap.tiles) { |
245 | | - updateTile(tile); |
| 259 | + updateTile(tile, tk); |
246 | 260 | } |
247 | 261 | } |
248 | 262 |
|
@@ -496,13 +510,57 @@ private void updateBuildingLayer(Tile tile) { |
496 | 510 | } |
497 | 511 | } |
498 | 512 |
|
499 | | - public void updateTile(Tile tile) { |
| 513 | + // updateFogOfWarLayer returns true if the tile is visible or |
| 514 | + // semi-visible, indicating other layers should be updated. |
| 515 | + |
| 516 | + private static int fogOfWarIndex(Tile tile, TileKnowledge tk) { |
| 517 | + if (tk.isTileKnown(tile)) { |
| 518 | + return 0; |
| 519 | + } |
| 520 | + int sum = 0; |
| 521 | + // HACK: edge tiles have missing directions in neighbors map |
| 522 | + if (tile.neighbors.Values.Count != 8) { |
| 523 | + return sum; |
| 524 | + } |
| 525 | + if (tk.isTileKnown(tile.neighbors[TileDirection.NORTH]) || tk.isTileKnown(tile.neighbors[TileDirection.NORTHWEST]) || tk.isTileKnown(tile.neighbors[TileDirection.NORTHEAST])) { |
| 526 | + sum += 1 * 2; |
| 527 | + } |
| 528 | + if (tk.isTileKnown(tile.neighbors[TileDirection.WEST]) || tk.isTileKnown(tile.neighbors[TileDirection.NORTHWEST]) || tk.isTileKnown(tile.neighbors[TileDirection.SOUTHWEST])) { |
| 529 | + sum += 3 * 2; |
| 530 | + } |
| 531 | + if (tk.isTileKnown(tile.neighbors[TileDirection.EAST]) || tk.isTileKnown(tile.neighbors[TileDirection.NORTHEAST]) || tk.isTileKnown(tile.neighbors[TileDirection.SOUTHEAST])) { |
| 532 | + sum += 9 * 2; |
| 533 | + } |
| 534 | + if (tk.isTileKnown(tile.neighbors[TileDirection.SOUTH]) || tk.isTileKnown(tile.neighbors[TileDirection.SOUTHWEST]) || tk.isTileKnown(tile.neighbors[TileDirection.SOUTHEAST])) { |
| 535 | + sum += 27 * 2; |
| 536 | + } |
| 537 | + return sum; |
| 538 | + } |
| 539 | + |
| 540 | + private bool updateFogOfWarLayer(Tile tile, TileKnowledge tk) { |
| 541 | + if (tk.isTileKnown(tile)) { |
| 542 | + eraseCell(Layer.FogOfWar, tile); |
| 543 | + return true; |
| 544 | + } |
| 545 | + int index = fogOfWarIndex(tile, tk); |
| 546 | + setCell(Layer.FogOfWar, Atlas.FogOfWar, tile, new Vector2I(index % 9, index / 9)); |
| 547 | + return index > 0; // partially visible |
| 548 | + } |
| 549 | + |
| 550 | + public void updateTile(Tile tile, TileKnowledge tk) { |
500 | 551 | if (tile == Tile.NONE || tile is null) { |
501 | 552 | string msg = tile is null ? "null tile" : "Tile.NONE"; |
502 | 553 | log.Warning($"attempting to update {msg}"); |
503 | 554 | return; |
504 | 555 | } |
505 | 556 |
|
| 557 | + if (tk is not null) { |
| 558 | + bool visible = updateFogOfWarLayer(tile, tk); |
| 559 | + if (!visible) { |
| 560 | + return; |
| 561 | + } |
| 562 | + } |
| 563 | + |
506 | 564 | updateRoadLayer(tile, true); |
507 | 565 |
|
508 | 566 | if (tile.Resource != C7GameData.Resource.NONE) { |
@@ -533,5 +591,17 @@ private void updateGridLayer() { |
533 | 591 | tilemap.ClearLayer(Layer.Grid.Index()); |
534 | 592 | } |
535 | 593 | } |
| 594 | + |
| 595 | + public void discoverTile(Tile tile, TileKnowledge tk) { |
| 596 | + HashSet<Tile> update = new HashSet<Tile>(tile.neighbors.Values); |
| 597 | + foreach (Tile n in tile.neighbors.Values) { |
| 598 | + foreach (Tile nn in n.neighbors.Values) { |
| 599 | + update.Add(nn); |
| 600 | + } |
| 601 | + } |
| 602 | + foreach (Tile t in update) { |
| 603 | + updateTile(t, tk); |
| 604 | + } |
| 605 | + } |
536 | 606 | } |
537 | 607 | } |
0 commit comments