Пример #1
0
        public static bool DefinesUnsafeCustomRules(ModData modData, IReadOnlyFileSystem fileSystem, MiniYaml mapRules, MiniYaml mapWeapons, MiniYaml mapVoices, MiniYaml mapNotifications, MiniYaml mapSequences)
        {
            if (AnyCustomYaml(mapWeapons) || AnyCustomYaml(mapVoices) || AnyCustomYaml(mapNotifications) || AnyCustomYaml(mapSequences))
            {
                return(true);
            }

            if (mapRules != null)
            {
                if (AnyFlaggedTraits(modData, mapRules.Nodes))
                {
                    return(true);
                }

                if (mapRules.Value != null)
                {
                    var mapFiles = FieldLoader.GetValue <string[]>("value", mapRules.Value);
                    foreach (var f in mapFiles)
                    {
                        if (AnyFlaggedTraits(modData, MiniYaml.FromStream(fileSystem.Open(f), f)))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fileSystem"></param>
        /// <param name="files"></param>
        /// <param name="mapRules"></param>
        /// <returns></returns>
        public static List <MiniYamlNode> Load(IReadOnlyFileSystem fileSystem, IEnumerable <string> files, MiniYaml mapRules)
        {
            if (mapRules != null && mapRules.Value != null)
            {
                var mapFiles = FieldLoader.GetValue <string[]>("value", mapRules.Value);
                files = files.Append(mapFiles);
            }

            var yaml = files.Select(s => MiniYaml.FromStream(fileSystem.Open(s), s));

            if (mapRules != null && mapRules.Nodes.Any())
            {
                yaml = yaml.Append(mapRules.Nodes);
            }

            return(Merge(yaml));
        }
Пример #3
0
        public Map(ModData modData, IReadOnlyPackage package)
        {
            this.modData = modData;
            Package      = package;

            if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
            {
                throw new InvalidDataException("Not a valid map\n File:{0}".F(package.Name));
            }

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));

            foreach (var field in YamlFields)
            {
                field.Deserialize(this, yaml.Nodes);
            }

            if (MapFormat != SupportedMapFormat)
            {
                throw new InvalidDataException("Map format {0} is not supported. \n File:{1}".F(MapFormat, package.Name));
            }
            PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
            ActorDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Actors");

            Grid = modData.Manifest.Get <MapGrid>();

            var size = new Size((int)MapSize.X, (int)MapSize.Y);

            //Layer
            Tiles     = new CellLayer <TerrainTile>(Grid.Type, size);
            Resources = new CellLayer <ResourceTile>(Grid.Type, size);
            Height    = new CellLayer <byte>(Grid.Type, size);


            using (var s = Package.GetStream("map.bin"))
            {
                var header = new BinaryDataHeader(s, MapSize);

                if (header.TilesOffset > 0)
                {
                    s.Position = header.TilesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var tile  = s.ReadUInt16();
                            var index = s.ReadUInt8();
                            if (index == byte.MaxValue)
                            {
                                index = (byte)(i % 4 + (j % 4) * 4);
                            }

                            Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
                        }
                    }
                }

                if (header.ResourcesOffset > 0)
                {
                    s.Position = header.ResourcesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var type    = s.ReadUInt8();
                            var density = s.ReadUInt8();
                            Resources[new MPos(i, j)] = new ResourceTile(type, density);
                        }
                    }
                }

                if (header.HeightsOffset > 0)
                {
                    s.Position = header.HeightsOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
                        }
                    }
                }
            }

            if (Grid.MaximumTerrainHeight > 0)
            {
                Tiles.CellEntryChanged  += UpdateProjection;
                Height.CellEntryChanged += UpdateProjection;
            }

            PostInit();

            Uid = ComputeUID(Package);
        }
Пример #4
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;

            yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("mod.yaml"), "mod.yaml")).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }
            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Assemblies     = YamlList(yaml, "Assemblies");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            TileSets       = YamlList(yaml, "TileSets");
            Missions       = YamlList(yaml, "Missions");
            ServerTraits   = YamlList(yaml, "ServerTraits");
            Chrome         = YamlList(yaml, "Chrome");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Fonts          = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });
            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("'LoadScreen' section is not defined.");
            }

            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="parent"></param>
        /// <param name="classification"></param>
        /// <param name="mapCompatibility"></param>
        /// <param name="gridT"></param>
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridT gridT)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;


            var newData = innerData.Clone();

            newData.GridT = gridT;
            newData.Class = classification;

            MiniYaml temp;

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidOperationException("Map format {0} is not supported.".F(format));
                }
            }
            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }
            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }
            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }
            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ? MapStatus.Available : MapStatus.Unavailable;

            try
            {
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                    }
                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = new CPos[0];
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status      = MapStatus.Unavailable;
            }


            try
            {
                //Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () => {
                var ruleDefinitions          = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions        = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions         = LoadRuleSection(yaml, "Voices");
                var musicDefinitions         = LoadRuleSection(yaml, "Music");
                var notificationDefinitions  = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions      = LoadRuleSection(yaml, "Sequences");
                var modelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences");

                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);

                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return(Pair.New(rules, flagged));
            });

            if (Package.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = BitmapFactory.DecodeStream(dataStream, null,
                                                                 new BitmapFactory.Options
                    {
                        InScaled           = false,
                        InDither           = false,
                        InJustDecodeBounds = false,
                        InPurgeable        = true,
                        InInputShareable   = true,
                    });
            }

            innerData = newData;
        }