ITileMatcher <TTile, Nothing> CreateDecoMatcher(ITileRegistry <TTile> tiles) { var gd = GameData; var map = gd.Map.DecorationLayer; var wallMap = gd.Map.WallLayer; bool IsNeitherWallOrPassageFn(int x, int y) { var tile = wallMap[x, y]; return(!gd.Rules.Walls.Stone.Equals(tile) && !gd.Rules.Walls.Passage.Equals(tile)); } var wallsAsCardinals = new CardinalTileRegistry <TTile>(tiles); var wallTypeSelector = new DistinctTileMatcher <IDecorationType, TTile, Nothing>((x, y) => map[x, y]); foreach (var decorationType in gd.Rules.DecorationTypes.Skip(1)) { var target = decorationType; wallTypeSelector.Add(decorationType, new CardinalTileSelector <TTile, Nothing>(IsNeitherWallOrPassageFn, CreateMatcher(map, target), RenderingConfig.MatcherNavigator, wallsAsCardinals, target.Name)); } return(wallTypeSelector); }
TileMatchControl CreateSettlementLayer() { var map = GameData.Terrain; string Classify(int x, int y) { var s = map[x, y].City; if (s != 0) { var settlement = GameData.Settlements[s]; var owner = GameData.Players[settlement.Owner]; var culture = owner.Culture.ToString().ToLowerInvariant(); var walled = settlement.Walled ? "wall" : "city"; return($"city.{culture}_{walled}"); } return(""); } var matcher = new DistinctTileMatcher <string, TTile, Nothing>(Classify); matcher.Add("city.asian_wall", CreateSettlementMatch("city.asian_wall")); matcher.Add("city.asian_city", CreateSettlementMatch("city.asian_city")); matcher.Add("city.tropical_wall", CreateSettlementMatch("city.tropical_wall")); matcher.Add("city.tropical_city", CreateSettlementMatch("city.tropical_city")); matcher.Add("city.celtic_wall", CreateSettlementMatch("city.celtic_wall")); matcher.Add("city.celtic_city", CreateSettlementMatch("city.celtic_city")); matcher.Add("city.classical_wall", CreateSettlementMatch("city.classical_wall")); matcher.Add("city.classical_city", CreateSettlementMatch("city.classical_city")); matcher.Add("city.babylonian_wall", CreateSettlementMatch("city.babylonian_wall")); matcher.Add("city.babylonian_city", CreateSettlementMatch("city.babylonian_city")); return(new TileMatchControl(matcher, RotationCacheControl)); }
TileMatchControl CreateResourceLayer() { var resourceTypes = GameData.Rules.TerrainResourceTypes; var map = GameData.Terrain; int Query(int x, int y) { return(map[x, y].Resources); } bool AlwaysTrue(int x, int y) { return(true); } var m = new DistinctTileMatcher <int, TTile, Nothing>(Query); for (var idx = 0; idx < resourceTypes.Count; idx++) { var resource = resourceTypes[idx]; if (resource.GraphicTag != null) { m.Add(idx, new BasicTileSelector <TTile, Nothing>(AlwaysTrue, RenderingConfig.MatcherNavigator, Tiles, resource.GraphicTag)); } } // alternative ... Tuple <TTile, Nothing> LookupTileFromResourceId(int idx) { var resource = resourceTypes[idx]; if (Tiles.FindFirstTile(resource, out var retval)) { return(Tuple.Create(retval, Nothing.Instance)); } return(null); } var cachedLookup = new LookupTable <Tuple <TTile, Nothing> >(resourceTypes.Count, LookupTileFromResourceId); Tuple <TTile, Nothing> QueryCachedData(int x, int y) { var data = map[x, y].Resources; return(cachedLookup.Lookup(data)); } var dm = new DirectMappingTileMatcher <Tuple <TTile, Nothing>, TTile, Nothing>( QueryCachedData, LookupTable.UnwrapTuple); return(new TileMatchControl(dm, RotationCacheControl)); }
ITileMatcher <TTile, Nothing> BuildLayer(int layerIdx) { var matcher = new DistinctTileMatcher <byte, TTile, Nothing>((x, y) => GameData.Terrain[x, y].TerrainIdx); foreach (var t in GameData.Rules.TerrainTypes) { var tag = TileSet.FindFirstTerrain(t); if (tag != null) { if (!tag.MatchRule.TryGetValue(layerIdx, out RenderLayerDefinition rd)) { continue; } var idx = (byte)GameData.Rules.TerrainTypes.IndexOf(t); ITileMatcher <TTile, Nothing> tileMatcher; switch (rd.MatchType) { case TerrainMatchType.None: tileMatcher = NoOpTileMatcher <TTile, Nothing> .Instance; break; case TerrainMatchType.Basic: tileMatcher = GenerateBasicLayer(idx, rd); break; case TerrainMatchType.Cardinal: tileMatcher = GenerateCardinalLayer(layerIdx, idx, rd); break; case TerrainMatchType.Corner: tileMatcher = GenerateCornerLayer(layerIdx, idx, rd); break; case TerrainMatchType.CornerPair: tileMatcher = GenerateCornerPairLayer(layerIdx, idx, rd); break; case TerrainMatchType.CellGroup: tileMatcher = GenerateCellGroupLayer(layerIdx, rd); break; default: throw new InvalidOperationException(); } matcher.Add(idx, tileMatcher); } } return(matcher); }
ITileMatcher <TTile, Nothing> CreateWallMatcher(ITileRegistry <TTile> tiles) { var gd = GameData; var map = gd.Map.WallLayer; bool IsWallOrPassageFn(int x, int y) { var tile = map[x, y]; return(gd.Rules.Walls.Stone.Equals(tile) || gd.Rules.Walls.Passage.Equals(tile)); } var wallsAsCardinals = new CardinalTileRegistry <TTile>(tiles); var wallTypeSelector = new DistinctTileMatcher <IWallType, TTile, Nothing>((x, y) => map[x, y]); wallTypeSelector.Add(gd.Rules.Walls.Stone, new CardinalTileSelector <TTile, Nothing>(IsWallOrPassageFn, CreateMatcher(map, gd.Rules.Walls.Stone), RenderingConfig.MatcherNavigator, wallsAsCardinals, gd.Rules.Walls.Stone.Name)); return(wallTypeSelector); }