Пример #1
0
        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);
        }
Пример #2
0
        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));
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }