Пример #1
0
 static Dictionary<string, string[]> Load(MiniYaml y, string name)
 {
     var nd = y.ToDictionary();
     return nd.ContainsKey(name)
         ? nd[name].ToDictionary(my => FieldLoader.GetValue<string[]>("(value)", my.Value))
         : new Dictionary<string, string[]>();
 }
Пример #2
0
        public ActorInfo(string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits)
        {
            try
            {
                var allParents = new HashSet<string>();
                var abstractActorType = name.StartsWith("^");

                // Guard against circular inheritance
                allParents.Add(name);
                var mergedNode = MergeWithParents(node, allUnits, allParents).ToDictionary();

                Name = name;

                foreach (var t in mergedNode)
                {
                    if (t.Key[0] == '-')
                        throw new YamlException("Bogus trait removal: " + t.Key);

                    if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
                        try
                        {
                            Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
                        }
                        catch (FieldLoader.MissingFieldsException e)
                        {
                            if (!abstractActorType)
                                throw new YamlException(e.Message);
                        }
                }
            }
            catch (YamlException e)
            {
                throw new YamlException("Actor type {0}: {1}".F(name, e.Message));
            }
        }
Пример #3
0
		public SoundInfo(MiniYaml y)
		{
			FieldLoader.Load(this, y);

			VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(a.Value)));
			NotificationsPools = Exts.Lazy(() => Notifications.ToDictionary(a => a.Key, a => new SoundPool(a.Value)));
		}
Пример #4
0
        void MergeAndPrint(Map map, string key, MiniYaml value)
        {
            var nodes = new List<MiniYamlNode>();
            var includes = new List<string>();
            if (value != null && value.Value != null)
            {
                // The order of the included files matter, so we can defer to system files
                // only as long as they are included first.
                var include = false;
                var files = FieldLoader.GetValue<string[]>("value", value.Value);
                foreach (var f in files)
                {
                    include |= map.Package.Contains(f);
                    if (include)
                        nodes.AddRange(MiniYaml.FromStream(map.Open(f)));
                    else
                        includes.Add(f);
                }
            }

            if (value != null)
                nodes.AddRange(value.Nodes);

            var output = new MiniYaml(includes.JoinWith(", "), nodes);
            Console.WriteLine(output.ToLines(key).JoinWith("\n"));
        }
Пример #5
0
        public CursorProvider(ModData modData)
        {
            var sequenceFiles = modData.Manifest.Cursors;

            cursors = new Dictionary<string, CursorSequence>();
            palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
            var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
            var shadowIndex = new int[] { };

            if (sequences.NodesDict.ContainsKey("ShadowIndex"))
            {
                Array.Resize(ref shadowIndex, shadowIndex.Length + 1);
                Exts.TryParseIntegerInvariant(sequences.NodesDict["ShadowIndex"].Value,
                    out shadowIndex[shadowIndex.Length - 1]);
            }

            palette = new HardwarePalette();
            foreach (var p in sequences.NodesDict["Palettes"].Nodes)
                palette.AddPalette(p.Key, new Palette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);

            var spriteLoader = new SpriteLoader(new string[0], new SheetBuilder(SheetType.Indexed));
            foreach (var s in sequences.NodesDict["Cursors"].Nodes)
                LoadSequencesForCursor(spriteLoader, s.Key, s.Value);

            palette.Initialize();
        }
Пример #6
0
        static void ProcessYaml(ModData modData, Map map, MiniYaml yaml, int engineDate, UpgradeAction processYaml)
        {
            if (yaml == null)
                return;

            if (yaml.Value != null)
            {
                var files = FieldLoader.GetValue<string[]>("value", yaml.Value);
                foreach (var filename in files)
                {
                    var fileNodes = MiniYaml.FromStream(map.Open(filename), filename);
                    processYaml(modData, engineDate, ref fileNodes, null, 0);

                    // HACK: Obtain the writable save path using knowledge of the underlying filesystem workings
                    var packagePath = filename;
                    var package = map.Package;
                    if (filename.Contains("|"))
                        modData.DefaultFileSystem.TryGetPackageContaining(filename, out package, out packagePath);

                    ((IReadWritePackage)package).Update(packagePath, Encoding.ASCII.GetBytes(fileNodes.WriteToString()));
                }
            }

            processYaml(modData, engineDate, ref yaml.Nodes, null, 1);
        }
Пример #7
0
        public CursorProvider(ModData modData)
        {
            var fileSystem = modData.DefaultFileSystem;
            var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(
                s => MiniYaml.FromStream(fileSystem.Open(s), s)));

            var shadowIndex = new int[] { };

            var nodesDict = new MiniYaml(null, sequenceYaml).ToDictionary();
            if (nodesDict.ContainsKey("ShadowIndex"))
            {
                Array.Resize(ref shadowIndex, shadowIndex.Length + 1);
                Exts.TryParseIntegerInvariant(nodesDict["ShadowIndex"].Value,
                    out shadowIndex[shadowIndex.Length - 1]);
            }

            var palettes = new Dictionary<string, ImmutablePalette>();
            foreach (var p in nodesDict["Palettes"].Nodes)
                palettes.Add(p.Key, new ImmutablePalette(fileSystem.Open(p.Value.Value), shadowIndex));

            Palettes = palettes.AsReadOnly();

            var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders);
            var cursors = new Dictionary<string, CursorSequence>();
            foreach (var s in nodesDict["Cursors"].Nodes)
                foreach (var sequence in s.Value.Nodes)
                    cursors.Add(sequence.Key, new CursorSequence(frameCache, sequence.Key, s.Key, s.Value.Value, sequence.Value));

            Cursors = cursors.AsReadOnly();
        }
Пример #8
0
        static Dictionary<string, ModMetadata> ValidateMods()
        {
            var basePath = Platform.ResolvePath(".", "mods");
            var mods = Directory.GetDirectories(basePath)
                .Select(x => x.Substring(basePath.Length + 1));

            var ret = new Dictionary<string, ModMetadata>();
            foreach (var m in mods)
            {
                var yamlPath = Platform.ResolvePath(".", "mods", m, "mod.yaml");
                if (!File.Exists(yamlPath))
                    continue;

                var yaml = new MiniYaml(null, MiniYaml.FromFile(yamlPath));
                var nd = yaml.ToDictionary();
                if (!nd.ContainsKey("Metadata"))
                    continue;

                var mod = FieldLoader.Load<ModMetadata>(nd["Metadata"]);
                mod.Id = m;

                ret.Add(m, mod);
            }

            return ret;
        }
Пример #9
0
        public TerrainTemplateInfo(TileSet tileSet, MiniYaml my)
        {
            FieldLoader.Load(this, my);

            var nodes = my.ToDictionary()["Tiles"].Nodes;

            if (!PickAny)
            {
                tileInfo = new TerrainTileInfo[Size.X * Size.Y];
                foreach (var node in nodes)
                {
                    int key;
                    if (!int.TryParse(node.Key, out key) || key < 0 || key >= tileInfo.Length)
                        throw new InvalidDataException("Invalid tile key '{0}' on template '{1}' of tileset '{2}'.".F(node.Key, Id, tileSet.Id));

                    tileInfo[key] = LoadTileInfo(tileSet, node.Value);
                }
            }
            else
            {
                tileInfo = new TerrainTileInfo[nodes.Count];

                var i = 0;
                foreach (var node in nodes)
                {
                    int key;
                    if (!int.TryParse(node.Key, out key) || key != i++)
                        throw new InvalidDataException("Invalid tile key '{0}' on template '{1}' of tileset '{2}'.".F(node.Key, Id, tileSet.Id));

                    tileInfo[key] = LoadTileInfo(tileSet, node.Value);
                }
            }
        }
Пример #10
0
		public Manifest(string mod)
		{
			var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
			var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

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

			// TODO: Use fieldloader
			Folders = YamlList(yaml, "Folders");
			MapFolders = YamlDictionary(yaml, "MapFolders");
			Packages = YamlDictionary(yaml, "Packages");
			Rules = YamlList(yaml, "Rules");
			ServerTraits = YamlList(yaml, "ServerTraits");
			Sequences = YamlList(yaml, "Sequences");
			VoxelSequences = YamlList(yaml, "VoxelSequences");
			Cursors = YamlList(yaml, "Cursors");
			Chrome = YamlList(yaml, "Chrome");
			Assemblies = YamlList(yaml, "Assemblies");
			ChromeLayout = YamlList(yaml, "ChromeLayout");
			Weapons = YamlList(yaml, "Weapons");
			Voices = YamlList(yaml, "Voices");
			Notifications = YamlList(yaml, "Notifications");
			Music = YamlList(yaml, "Music");
			Movies = YamlList(yaml, "Movies");
			Translations = YamlList(yaml, "Translations");
			TileSets = YamlList(yaml, "TileSets");
			ChromeMetrics = YamlList(yaml, "ChromeMetrics");
			PackageContents = YamlList(yaml, "PackageContents");
			LuaScripts = YamlList(yaml, "LuaScripts");
			Missions = YamlList(yaml, "Missions");

			LoadScreen = yaml["LoadScreen"];
			LobbyDefaults = yaml["LobbyDefaults"];

			if (yaml.ContainsKey("ContentInstaller"))
				ContentInstaller = FieldLoader.Load<InstallData>(yaml["ContentInstaller"]);

			Fonts = yaml["Fonts"].ToDictionary(my =>
				{
					var nd = my.ToDictionary();
					return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
				});

			if (yaml.ContainsKey("TileSize"))
				TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value);

			if (yaml.ContainsKey("TileShape"))
				TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);

			// Allow inherited mods to import parent maps.
			var compat = new List<string>();
			compat.Add(mod);

			if (yaml.ContainsKey("SupportsMapsFrom"))
				foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
					compat.Add(c.Trim());

			MapCompatibility = compat.ToArray();
		}
Пример #11
0
 public MappedImage(string defaultSrc, MiniYaml info)
 {
     FieldLoader.LoadField(this, "rect", info.Value);
     FieldLoader.Load(this, info);
     if (src == null)
         src = defaultSrc;
 }
Пример #12
0
		static object LoadVersus(MiniYaml y)
		{
			var nd = y.ToDictionary();
			return nd.ContainsKey("Versus")
				? nd["Versus"].ToDictionary(my => FieldLoader.GetValue<float>("(value)", my.Value))
				: new Dictionary<string, float>();
		}
Пример #13
0
        public static Dictionary<string, string[]> LoadFilesToExtract(MiniYaml yaml)
        {
            var md = yaml.ToDictionary();

            return md.ContainsKey("ExtractFilesFromCD")
                ? md["ExtractFilesFromCD"].ToDictionary(my => FieldLoader.GetValue<string[]>("(value)", my.Value))
                : new Dictionary<string, string[]>();
        }
Пример #14
0
		static object LoadSpeeds(MiniYaml y)
		{
			var ret = new Dictionary<string, GameSpeed>();
			foreach (var node in y.Nodes)
				ret.Add(node.Key, FieldLoader.Load<GameSpeed>(node.Value));

			return ret;
		}
Пример #15
0
		static object LoadProjectile(MiniYaml yaml)
		{
			MiniYaml proj;
			if (!yaml.ToDictionary().TryGetValue("Projectile", out proj))
				return null;
			var ret = Game.CreateObject<IProjectileInfo>(proj.Value + "Info");
			FieldLoader.Load(ret, proj);
			return ret;
		}
Пример #16
0
		static object LoadConsiderations(MiniYaml yaml)
		{
			var ret = new List<Consideration>();
			foreach (var d in yaml.Nodes)
				if (d.Key.Split('@')[0] == "Consideration")
					ret.Add(new Consideration(d.Value));

			return ret;
		}
Пример #17
0
		static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my)
		{
			if (!string.IsNullOrEmpty(my.Value))
				throw new YamlException("Junk value `{0}` on trait node {1}"
				.F(my.Value, traitName));
			var info = Game.CreateObject<ITraitInfo>(traitName + "Info");
			FieldLoader.Load(info, my);
			return info;
		}
Пример #18
0
		static object LoadOptions(MiniYaml y)
		{
			var options = new MapOptions();
			var nodesDict = y.ToDictionary();
			if (nodesDict.ContainsKey("Options"))
				FieldLoader.Load(options, nodesDict["Options"]);

			return options;
		}
Пример #19
0
        static object LoadPackages(MiniYaml yaml)
        {
            var packages = new Dictionary<string, ModPackage>();
            var packageNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Packages");
            if (packageNode != null)
                foreach (var node in packageNode.Value.Nodes)
                    packages.Add(node.Key, new ModPackage(node.Value));

            return packages;
        }
Пример #20
0
		void TestMixedMerge(MiniYaml result)
		{
			Console.WriteLine(result.ToLines("result").JoinWith("\n"));
			Assert.That(result.Nodes.Any(n => n.Key == "FromA"), Is.True, "Node from A");
			Assert.That(result.Nodes.Any(n => n.Key == "FromB"), Is.True, "Node from B");
			Assert.That(result.Nodes.Any(n => n.Key == "FromARemovedA"), Is.Not.True, "Node from A removed by A");
			Assert.That(result.Nodes.Any(n => n.Key == "FromARemovedB"), Is.Not.True, "Node from A removed by B");
			Assert.That(result.Nodes.Any(n => n.Key == "FromBRemovedA"), Is.Not.True, "Node from B removed by A");
			Assert.That(result.Nodes.Any(n => n.Key == "FromBRemovedB"), Is.Not.True, "Node from B removed by B");
		}
Пример #21
0
 public MiniYaml Save()
 {
     var ret = new MiniYaml( Type );
     foreach( var init in InitDict )
     {
         var initName = init.GetType().Name;
         ret.Nodes.Add( new MiniYamlNode( initName.Substring( 0, initName.Length - 4 ), FieldSaver.Save( init ) ) );
     }
     return ret;
 }
Пример #22
0
		static void LoadVoxelsForUnit(string unit, MiniYaml sequences)
		{
			Game.ModData.LoadScreen.Display();
			try
			{
				var seq = sequences.ToDictionary(my => LoadVoxel(unit, my));
				units.Add(unit, seq);
			}
			catch (FileNotFoundException) { } // Do nothing; we can crash later if we actually wanted art
		}
Пример #23
0
		public MapGrid(MiniYaml yaml)
		{
			FieldLoader.Load(this, yaml);

			// The default subcell index defaults to the middle entry
			if (SubCellDefaultIndex == byte.MaxValue)
				SubCellDefaultIndex = (byte)(SubCellOffsets.Length / 2);
			else if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
				throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");
		}
Пример #24
0
		static void LoadCollection(string name, MiniYaml yaml)
		{
			Game.modData.LoadScreen.Display();
			var collection = new Collection()
			{
				src = yaml.Value,
				regions = yaml.Nodes.ToDictionary(n => n.Key, n => new MappedImage(yaml.Value, n.Value))
			};

			collections.Add(name, collection);
		}
Пример #25
0
        static object LoadPercents(MiniYaml y)
        {
            MiniYaml percents;

            if (!y.ToDictionary().TryGetValue("TerrainModifier", out percents))
                return new Dictionary<string, int>();

            return percents.Nodes.ToDictionary(
                kv => FieldLoader.GetValue<string>("(key)", kv.Key),
                kv => FieldLoader.GetValue<int>("(value)", kv.Value.Value));
        }
Пример #26
0
        public SoundInfo( MiniYaml y )
        {
            FieldLoader.Load( this, y );
            Variants = Load(y, "Variants");
            Prefixes = Load(y, "Prefixes");
            Voices = Load(y, "Voices");
            Notifications = Load(y, "Notifications");

            VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(a.Value)));
            NotificationsPools = Exts.Lazy(() => Notifications.ToDictionary( a => a.Key, a => new SoundPool(a.Value) ));
        }
Пример #27
0
		static object LoadWarheads(MiniYaml yaml)
		{
			var retList = new List<IWarhead>();
			foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead")))
			{
				var ret = Game.CreateObject<IWarhead>(node.Value.Value + "Warhead");
				FieldLoader.Load(ret, node.Value);
				retList.Add(ret);
			}

			return retList;
		}
Пример #28
0
		static MiniYaml MergeWithParent( MiniYaml node, Dictionary<string, MiniYaml> allUnits )
		{
			var parent = GetParent( node, allUnits );
			if (parent != null)
			{
				var result = MiniYaml.MergeStrict(node, MergeWithParent(parent, allUnits));

				// strip the '-'
				result.Nodes.RemoveAll(a => a.Key.StartsWith("-"));
				return result;
			}
			return node;
		}
Пример #29
0
		public MissionBrowserLogic(Widget widget, Action onStart, Action onExit)
		{
			this.onStart = onStart;

			var missionList = widget.Get<ScrollPanelWidget>("MISSION_LIST");
			var template = widget.Get<ScrollItemWidget>("MISSION_TEMPLATE");

			widget.Get("MISSION_INFO").IsVisible = () => selectedMapPreview != null;

			var previewWidget = widget.Get<MapPreviewWidget>("MISSION_PREVIEW");
			previewWidget.Preview = () => selectedMapPreview;

			descriptionPanel = widget.Get<ScrollPanelWidget>("MISSION_DESCRIPTION_PANEL");
			description = widget.Get<LabelWidget>("MISSION_DESCRIPTION");
			descriptionFont = Game.Renderer.Fonts[description.Font];

			var yaml = new MiniYaml(null, Game.modData.Manifest.Missions.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergeLiberal)).ToDictionary();

			var missionMapPaths = yaml["Missions"].Nodes.Select(n => Path.GetFullPath(n.Key));

			var maps = Game.modData.MapCache
				.Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Map.Path)))
				.Select(p => p.Map);

			missionList.RemoveChildren();
			foreach (var m in maps)
			{
				var map = m;

				var item = ScrollItemWidget.Setup(template,
					() => selectedMapPreview != null && selectedMapPreview.Uid == map.Uid,
					() => SelectMap(map),
					StartMission);

				item.Get<LabelWidget>("TITLE").GetText = () => map.Title;
				missionList.AddChild(item);
			}

			if (maps.Any())
				SelectMap(maps.First());

			widget.Get<ButtonWidget>("STARTGAME_BUTTON").OnClick = StartMission;

			widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
			{
				Game.Disconnect();
				Ui.CloseWindow();
				onExit();
			};
		}
Пример #30
0
		static MiniYaml GetParent( MiniYaml node, Dictionary<string, MiniYaml> allUnits )
		{
			MiniYaml inherits;
			node.ToDictionary().TryGetValue( "Inherits", out inherits );
			if( inherits == null || string.IsNullOrEmpty( inherits.Value ) )
				return null;

			MiniYaml parent;
			allUnits.TryGetValue( inherits.Value, out parent );
			if (parent == null)
				throw new InvalidOperationException(
					"Bogus inheritance -- actor type {0} does not exist".F(inherits.Value));

			return parent;
		}
Пример #31
0
 public ClassicTilesetSpecificSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info)
     : base(modData, tileSet, cache, loader, sequence, animation, info)
 {
 }
Пример #32
0
 static object LoadBuildings(MiniYaml y)
 {
     return(LoadActorList(y, "BuildingFractions"));
 }
Пример #33
0
        void CheckMapYaml(Action <string> emitError, Action <string> emitWarning, ModData modData, IReadOnlyFileSystem fileSystem, MiniYaml weaponDefinitions)
        {
            if (weaponDefinitions == null)
            {
                return;
            }

            var mapFiles = FieldLoader.GetValue <string[]>("value", weaponDefinitions.Value);

            foreach (var f in mapFiles)
            {
                CheckWeapons(MiniYaml.FromStream(fileSystem.Open(f), f), emitError, emitWarning, modData);
            }

            if (weaponDefinitions.Nodes.Any())
            {
                CheckWeapons(weaponDefinitions.Nodes, emitError, emitWarning, modData);
            }
        }
        public void RefreshServerList()
        {
            // Query in progress
            if (currentQuery != null)
            {
                return;
            }

            searchStatus = SearchStatus.Fetching;

            Action <DownloadDataCompletedEventArgs> onComplete = i =>
            {
                currentQuery = null;

                List <GameServer> games = null;
                if (i.Error == null)
                {
                    try
                    {
                        var data = Encoding.UTF8.GetString(i.Result);
                        var yaml = MiniYaml.FromString(data);

                        games = yaml.Select(a => new GameServer(a.Value))
                                .Where(gs => gs.Address != null)
                                .ToList();
                    }
                    catch
                    {
                        searchStatus = SearchStatus.Failed;
                    }
                }

                var lanGames = new List <GameServer>();
                foreach (var bl in lanGameLocations)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(bl.Data))
                        {
                            continue;
                        }

                        var game   = MiniYaml.FromString(bl.Data)[0].Value;
                        var idNode = game.Nodes.FirstOrDefault(n => n.Key == "Id");

                        // Skip beacons created by this instance and replace Id by expected int value
                        if (idNode != null && idNode.Value.Value != Platform.SessionGUID.ToString())
                        {
                            idNode.Value.Value = "-1";

                            // Rewrite the server address with the correct IP
                            var addressNode = game.Nodes.FirstOrDefault(n => n.Key == "Address");
                            if (addressNode != null)
                            {
                                addressNode.Value.Value = bl.Address.ToString().Split(':')[0] + ":" + addressNode.Value.Value.Split(':')[1];
                            }

                            lanGames.Add(new GameServer(game));
                        }
                    }
                    catch
                    {
                        // Ignore any invalid LAN games advertised.
                    }
                }

                var groupedLanGames = lanGames.GroupBy(gs => gs.Address).Select(g => g.Last());
                if (games != null)
                {
                    games.AddRange(groupedLanGames);
                }
                else if (groupedLanGames.Any())
                {
                    games = groupedLanGames.ToList();
                }

                Game.RunAfterTick(() => RefreshServerListInner(games));
            };

            var queryURL = services.ServerList + "?protocol={0}&engine={1}&mod={2}&version={3}".F(
                GameServer.ProtocolVersion,
                Uri.EscapeUriString(Game.EngineVersion),
                Uri.EscapeUriString(Game.ModData.Manifest.Id),
                Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));

            currentQuery = new Download(queryURL, _ => { }, onComplete);
        }
Пример #35
0
        public static Squad Deserialize(IBot bot, SquadManagerBotModule squadManager, MiniYaml yaml)
        {
            var   type        = SquadType.Rush;
            Actor targetActor = null;

            var typeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");

            if (typeNode != null)
            {
                type = FieldLoader.GetValue <SquadType>("Type", typeNode.Value.Value);
            }

            var targetNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Target");

            if (targetNode != null)
            {
                targetActor = squadManager.World.GetActorById(FieldLoader.GetValue <uint>("ActiveUnits", targetNode.Value.Value));
            }

            var squad = new Squad(bot, squadManager, type, targetActor);

            var unitsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Units");

            if (unitsNode != null)
            {
                squad.Units.AddRange(FieldLoader.GetValue <uint[]>("Units", unitsNode.Value.Value)
                                     .Select(a => squadManager.World.GetActorById(a)));
            }

            return(squad);
        }
Пример #36
0
 public static Slot Deserialize(MiniYaml data)
 {
     return(FieldLoader.Load <Slot>(data));
 }
Пример #37
0
        static void ExtractFromPackage(ExtractionType type, string path, MiniYaml actionYaml, List <string> extractedFiles, Action <string> updateMessage)
        {
            var sourcePath = Path.Combine(path, actionYaml.Value);

            // Try as an absolute path
            if (!File.Exists(sourcePath))
            {
                sourcePath = Platform.ResolvePath(actionYaml.Value);
            }

            using (var source = File.OpenRead(sourcePath))
            {
                foreach (var node in actionYaml.Nodes)
                {
                    var targetPath = Platform.ResolvePath(node.Key);

                    if (File.Exists(targetPath))
                    {
                        Log.Write("install", "Skipping installed file " + targetPath);
                        continue;
                    }

                    var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
                    if (offsetNode == null)
                    {
                        Log.Write("install", "Skipping entry with missing Offset definition " + targetPath);
                        continue;
                    }

                    var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
                    if (lengthNode == null)
                    {
                        Log.Write("install", "Skipping entry with missing Length definition " + targetPath);
                        continue;
                    }

                    var length = FieldLoader.GetValue <int>("Length", lengthNode.Value.Value);
                    source.Position = FieldLoader.GetValue <int>("Offset", offsetNode.Value.Value);

                    extractedFiles.Add(targetPath);
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                    var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));

                    Action <long> onProgress = null;
                    if (length < ShowPercentageThreshold)
                    {
                        updateMessage("Extracting " + displayFilename);
                    }
                    else
                    {
                        onProgress = b => updateMessage("Extracting " + displayFilename + " ({0}%)".F(100 * b / length));
                    }

                    using (var target = File.OpenWrite(targetPath))
                    {
                        Log.Write("install", "Extracting {0} -> {1}".F(sourcePath, targetPath));
                        if (type == ExtractionType.Blast)
                        {
                            Action <long, long> onBlastProgress = (read, _) =>
                            {
                                if (onProgress != null)
                                {
                                    onProgress(read);
                                }
                            };

                            Blast.Decompress(source, target, onBlastProgress);
                        }
                        else
                        {
                            CopyStream(source, target, length, onProgress);
                        }
                    }
                }
            }
        }
Пример #38
0
        /// <summary>
        /// Loads a YamlFileSet containing any internal definitions yaml referenced by a map yaml block.
        /// External references or internal references to missing files are ignored.
        /// </summary>
        static YamlFileSet LoadInternalMapYaml(ModData modData, IReadWritePackage mapPackage, MiniYaml yaml, HashSet <string> externalFilenames)
        {
            var fileSet = new YamlFileSet()
            {
                Tuple.Create <IReadWritePackage, string, List <MiniYamlNode> >(null, "map.yaml", yaml.Nodes)
            };

            var files = FieldLoader.GetValue <string[]>("value", yaml.Value);

            foreach (var filename in files)
            {
                // Ignore any files that aren't in the map bundle
                if (!filename.Contains("|") && mapPackage.Contains(filename))
                {
                    fileSet.Add(Tuple.Create(mapPackage, filename, MiniYaml.FromStream(mapPackage.GetStream(filename), filename, false)));
                }
                else if (modData.ModFiles.Exists(filename))
                {
                    externalFilenames.Add(filename);
                }
            }

            return(fileSet);
        }
Пример #39
0
        public Sequence(SpriteCache cache, string unit, string name, MiniYaml info)
        {
            var srcOverride = info.Value;

            Name = name;
            var d         = info.ToDictionary();
            var offset    = float2.Zero;
            var blendMode = BlendMode.Alpha;

            try
            {
                if (d.ContainsKey("Start"))
                {
                    Start = Exts.ParseIntegerInvariant(d["Start"].Value);
                }

                if (d.ContainsKey("Offset"))
                {
                    offset = FieldLoader.GetValue <float2>("Offset", d["Offset"].Value);
                }

                if (d.ContainsKey("BlendMode"))
                {
                    blendMode = FieldLoader.GetValue <BlendMode>("BlendMode", d["BlendMode"].Value);
                }

                // Apply offset to each sprite in the sequence
                // Different sequences may apply different offsets to the same frame
                sprites = cache[srcOverride ?? unit].Select(
                    s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel, blendMode)).ToArray();

                if (!d.ContainsKey("Length"))
                {
                    Length = 1;
                }
                else if (d["Length"].Value == "*")
                {
                    Length = sprites.Length - Start;
                }
                else
                {
                    Length = Exts.ParseIntegerInvariant(d["Length"].Value);
                }

                if (d.ContainsKey("Stride"))
                {
                    Stride = Exts.ParseIntegerInvariant(d["Stride"].Value);
                }
                else
                {
                    Stride = Length;
                }

                if (d.ContainsKey("Facings"))
                {
                    var f = Exts.ParseIntegerInvariant(d["Facings"].Value);
                    Facings        = Math.Abs(f);
                    reverseFacings = f < 0;
                }
                else
                {
                    Facings = 1;
                }

                if (d.ContainsKey("Tick"))
                {
                    Tick = Exts.ParseIntegerInvariant(d["Tick"].Value);
                }
                else
                {
                    Tick = 40;
                }

                if (d.ContainsKey("Transpose"))
                {
                    transpose = bool.Parse(d["Transpose"].Value);
                }

                if (d.ContainsKey("Frames"))
                {
                    Frames = Array.ConvertAll <string, int>(d["Frames"].Value.Split(','), Exts.ParseIntegerInvariant);
                }

                if (d.ContainsKey("ShadowStart"))
                {
                    ShadowStart = Exts.ParseIntegerInvariant(d["ShadowStart"].Value);
                }
                else
                {
                    ShadowStart = -1;
                }

                if (d.ContainsKey("ShadowZOffset"))
                {
                    WRange r;
                    if (WRange.TryParse(d["ShadowZOffset"].Value, out r))
                    {
                        ShadowZOffset = r.Range;
                    }
                }
                else
                {
                    ShadowZOffset = -5;
                }

                if (d.ContainsKey("ZOffset"))
                {
                    WRange r;
                    if (WRange.TryParse(d["ZOffset"].Value, out r))
                    {
                        ZOffset = r.Range;
                    }
                }

                if (Length > Stride)
                {
                    throw new InvalidOperationException(
                              "{0}: Sequence {1}.{2}: Length must be <= stride"
                              .F(info.Nodes[0].Location, unit, name));
                }

                if (Start < 0 || Start + Facings * Stride > sprites.Length || ShadowStart + Facings * Stride > sprites.Length)
                {
                    throw new InvalidOperationException(
                              "{6}: Sequence {0}.{1} uses frames [{2}..{3}] of SHP `{4}`, but only 0..{5} actually exist"
                              .F(unit, name, Start, Start + Facings * Stride - 1, srcOverride ?? unit, sprites.Length - 1,
                                 info.Nodes[0].Location));
                }
            }
            catch (FormatException f)
            {
                throw new FormatException("Failed to parse sequences for {0}.{1} at {2}:\n{3}".F(unit, name, info.Nodes[0].Location, f));
            }
        }
Пример #40
0
        public void RefreshServerList()
        {
            // Query in progress
            if (activeQuery)
            {
                return;
            }

            searchStatus = SearchStatus.Fetching;

            var queryURL = new HttpQueryBuilder(services.ServerList)
            {
                { "protocol", GameServer.ProtocolVersion },
                { "engine", Game.EngineVersion },
                { "mod", Game.ModData.Manifest.Id },
                { "version", Game.ModData.Manifest.Metadata.Version }
            }.ToString();

            Task.Run(async() =>
            {
                var games  = new List <GameServer>();
                var client = HttpClientFactory.Create();
                var httpResponseMessage = await client.GetAsync(queryURL);
                var result = await httpResponseMessage.Content.ReadAsStringAsync();

                activeQuery = true;

                try
                {
                    var yaml = MiniYaml.FromString(result);
                    foreach (var node in yaml)
                    {
                        try
                        {
                            var gs = new GameServer(node.Value);
                            if (gs.Address != null)
                            {
                                games.Add(gs);
                            }
                        }
                        catch
                        {
                            // Ignore any invalid games advertised.
                        }
                    }
                }
                catch
                {
                    searchStatus = SearchStatus.Failed;
                }

                var lanGames = new List <GameServer>();
                foreach (var bl in lanGameLocations)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(bl.Data))
                        {
                            continue;
                        }

                        var game   = MiniYaml.FromString(bl.Data)[0].Value;
                        var idNode = game.Nodes.FirstOrDefault(n => n.Key == "Id");

                        // Skip beacons created by this instance and replace Id by expected int value
                        if (idNode != null && idNode.Value.Value != Platform.SessionGUID.ToString())
                        {
                            idNode.Value.Value = "-1";

                            // Rewrite the server address with the correct IP
                            var addressNode = game.Nodes.FirstOrDefault(n => n.Key == "Address");
                            if (addressNode != null)
                            {
                                addressNode.Value.Value = bl.Address.ToString().Split(':')[0] + ":" + addressNode.Value.Value.Split(':')[1];
                            }

                            game.Nodes.Add(new MiniYamlNode("Location", "Local Network"));

                            lanGames.Add(new GameServer(game));
                        }
                    }
                    catch
                    {
                        // Ignore any invalid LAN games advertised.
                    }
                }

                var groupedLanGames = lanGames.GroupBy(gs => gs.Address).Select(g => g.Last());
                if (games != null)
                {
                    games.AddRange(groupedLanGames);
                }
                else if (groupedLanGames.Any())
                {
                    games = groupedLanGames.ToList();
                }

                Game.RunAfterTick(() => RefreshServerListInner(games));

                activeQuery = false;
            });
        }
Пример #41
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;
            Game.ModData.MapCache.LoadMaps();

            var engineDate = Exts.ParseIntegerInvariant(args[1]);

            Console.WriteLine("Processing Rules:");
            foreach (var filename in Game.ModData.Manifest.Rules)
            {
                Console.WriteLine("\t" + filename);
                var yaml = MiniYaml.FromFile(filename);
                UpgradeRules.UpgradeActorRules(engineDate, ref yaml, null, 0);

                using (var file = new StreamWriter(filename))
                    file.WriteLine(yaml.WriteToString());
            }

            Console.WriteLine("Processing Weapons:");
            foreach (var filename in Game.ModData.Manifest.Weapons)
            {
                Console.WriteLine("\t" + filename);
                var yaml = MiniYaml.FromFile(filename);
                UpgradeRules.UpgradeWeaponRules(engineDate, ref yaml, null, 0);

                using (var file = new StreamWriter(filename))
                    file.WriteLine(yaml.WriteToString());
            }

            Console.WriteLine("Processing Tilesets:");
            foreach (var filename in Game.ModData.Manifest.TileSets)
            {
                Console.WriteLine("\t" + filename);
                var yaml = MiniYaml.FromFile(filename);
                UpgradeRules.UpgradeTileset(engineDate, ref yaml, null, 0);

                using (var file = new StreamWriter(filename))
                    file.WriteLine(yaml.WriteToString());
            }

            Console.WriteLine("Processing Cursors:");
            foreach (var filename in Game.ModData.Manifest.Cursors)
            {
                Console.WriteLine("\t" + filename);
                var yaml = MiniYaml.FromFile(filename);
                UpgradeRules.UpgradeCursors(engineDate, ref yaml, null, 0);

                using (var file = new StreamWriter(filename))
                    file.WriteLine(yaml.WriteToString());
            }

            Console.WriteLine("Processing Maps:");
            var maps = Game.ModData.MapCache
                       .Where(m => m.Status == MapStatus.Available)
                       .Select(m => m.Map);

            foreach (var map in maps)
            {
                Console.WriteLine("\t" + map.Path);
                UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
                UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
                map.Save(map.Path);
            }
        }
Пример #42
0
			public ResourceTypeInfo(MiniYaml yaml)
			{
				FieldLoader.Load(this, yaml);
			}
Пример #43
0
 static object LoadBuildingLimits(MiniYaml y)
 {
     return(LoadList <int>(y, "BuildingLimits"));
 }
Пример #44
0
 public override ISpriteSequence CreateSequence(ModData modData, TileSet tileSet, SpriteCache cache, string sequence, string animation, MiniYaml info)
 {
     return(new ClassicTilesetSpecificSpriteSequence(modData, tileSet, cache, this, sequence, animation, info));
 }
Пример #45
0
        static void ExtractFromISCab(string path, MiniYaml actionYaml, List <string> extractedFiles, Action <string> updateMessage)
        {
            var sourcePath = Path.Combine(path, actionYaml.Value);

            // Try as an absolute path
            if (!File.Exists(sourcePath))
            {
                sourcePath = Platform.ResolvePath(actionYaml.Value);
            }

            var volumeNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Volumes");

            if (volumeNode == null)
            {
                throw new InvalidDataException("extract-iscab entry doesn't define a Volumes node");
            }

            var extractNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Extract");

            if (extractNode == null)
            {
                throw new InvalidDataException("extract-iscab entry doesn't define an Extract node");
            }

            var volumes = new Dictionary <int, Stream>();

            try
            {
                foreach (var node in volumeNode.Value.Nodes)
                {
                    var volume = FieldLoader.GetValue <int>("(key)", node.Key);
                    var stream = File.OpenRead(Path.Combine(path, node.Value.Value));
                    volumes.Add(volume, stream);
                }

                using (var source = File.OpenRead(sourcePath))
                {
                    var reader = new InstallShieldCABCompression(source, volumes);
                    foreach (var node in extractNode.Value.Nodes)
                    {
                        var targetPath = Platform.ResolvePath(node.Key);

                        if (File.Exists(targetPath))
                        {
                            Log.Write("install", "Skipping installed file " + targetPath);
                            continue;
                        }

                        extractedFiles.Add(targetPath);
                        Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                        using (var target = File.OpenWrite(targetPath))
                        {
                            Log.Write("install", "Extracting {0} -> {1}".F(sourcePath, targetPath));
                            var          displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
                            Action <int> onProgress      = percent => updateMessage("Extracting {0} ({1}%)".F(displayFilename, percent));
                            reader.ExtractFile(node.Value.Value, target, onProgress);
                        }
                    }
                }
            }
            finally
            {
                foreach (var kv in volumes)
                {
                    kv.Value.Dispose();
                }
            }
        }
Пример #46
0
 public Consideration(MiniYaml yaml)
 {
     FieldLoader.Load(this, yaml);
 }
Пример #47
0
        public GameServer(MiniYaml yaml)
        {
            FieldLoader.Load(this, yaml);

            // Games advertised using the old API used a single Mods field
            if (Mod == null || Version == null)
            {
                var modsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Mods");
                if (modsNode != null)
                {
                    var modVersion = modsNode.Value.Value.Split('@');
                    Mod     = modVersion[0];
                    Version = modVersion[1];
                }
            }

            // Games advertised using the old API calculated the play time locally
            if (State == 2 && PlayTime < 0)
            {
                DateTime startTime;
                if (DateTime.TryParse(Started, out startTime))
                {
                    PlayTime = (int)(DateTime.UtcNow - startTime).TotalSeconds;
                }
            }

            ExternalMod external;
            var         externalKey = ExternalMod.MakeKey(Mod, Version);

            if (Game.ExternalMods.TryGetValue(externalKey, out external) && external.Version == Version)
            {
                IsCompatible = true;
            }

            // Games advertised using the old API used local mod metadata
            if (string.IsNullOrEmpty(ModTitle))
            {
                Manifest mod;

                if (external != null && external.Version == Version)
                {
                    // Use external mod registration to populate the section header
                    ModTitle = external.Title;
                }
                else if (Game.Mods.TryGetValue(Mod, out mod))
                {
                    // Use internal mod data to populate the section header, but
                    // on-connect switching must use the external mod plumbing.
                    ModTitle = mod.Metadata.Title;
                }
                else
                {
                    // Some platforms (e.g. macOS) package each mod separately, so the Mods check above won't work.
                    // Guess based on the most recent ExternalMod instead.
                    var guessMod = Game.ExternalMods.Values
                                   .OrderByDescending(m => m.Version)
                                   .FirstOrDefault(m => m.Id == Mod);

                    if (guessMod != null)
                    {
                        ModTitle = "{0}".F(guessMod.Title);
                    }
                    else
                    {
                        ModTitle = "Unknown mod: {0}".F(Mod);
                    }
                }
            }

            var mapAvailable = Game.Settings.Game.AllowDownloading || Game.ModData.MapCache[Map].Status == MapStatus.Available;

            IsJoinable = IsCompatible && State == 1 && mapAvailable;
        }
Пример #48
0
 public SupportPowerDecision(MiniYaml yaml)
 {
     FieldLoader.Load(this, yaml);
 }
Пример #49
0
 public static ClientPing Deserialize(MiniYaml data)
 {
     return(FieldLoader.Load <ClientPing>(data));
 }
Пример #50
0
        public SequenceProvider(IReadOnlyFileSystem fileSystem, ModData modData, TileSet tileSet, MiniYaml additionalSequences)
        {
            this.modData = modData;
            this.tileSet = tileSet;
            sequences    = Exts.Lazy(() =>
            {
                using (new Support.PerfTimer("LoadSequences"))
                    return(Load(fileSystem, additionalSequences));
            });

            spriteCache = Exts.Lazy(() => new SpriteCache(fileSystem, modData.SpriteLoaders));
        }
Пример #51
0
 static object LoadUnits(MiniYaml y)
 {
     return(LoadList <float>(y, "UnitsToBuild"));
 }
Пример #52
0
 static object LoadBuildings(MiniYaml y)
 {
     return(LoadList <float>(y, "BuildingFractions"));
 }
Пример #53
0
        public void Run(Action <string> emitError, Action <string> emitWarning, Map map)
        {
            if (map.SequenceDefinitions == null)
            {
                return;
            }

            var modData = Game.ModData;

            this.emitError = emitError;

            sequenceDefinitions = MiniYaml.Load(map, modData.Manifest.Sequences, map.SequenceDefinitions);

            var rules             = map.Rules;
            var factions          = rules.Actors["world"].TraitInfos <FactionInfo>().Select(f => f.InternalName).ToArray();
            var sequenceProviders = new[] { rules.Sequences };

            foreach (var actorInfo in rules.Actors)
            {
                foreach (var renderInfo in actorInfo.Value.TraitInfos <RenderSpritesInfo>())
                {
                    foreach (var faction in factions)
                    {
                        foreach (var sequenceProvider in sequenceProviders)
                        {
                            var image = renderInfo.GetImage(actorInfo.Value, sequenceProvider, faction);
                            if (sequenceDefinitions.All(s => s.Key != image.ToLowerInvariant()) && !actorInfo.Value.Name.Contains("^"))
                            {
                                emitError("Sprite image {0} from actor {1} using faction {2} has no sequence definition."
                                          .F(image, actorInfo.Value.Name, faction));
                            }
                        }
                    }
                }

                foreach (var traitInfo in actorInfo.Value.TraitInfos <ITraitInfo>())
                {
                    var fields = traitInfo.GetType().GetFields();
                    foreach (var field in fields)
                    {
                        if (field.HasAttribute <SequenceReferenceAttribute>())
                        {
                            var sequences = LintExts.GetFieldValues(traitInfo, field, emitError);
                            foreach (var sequence in sequences)
                            {
                                if (string.IsNullOrEmpty(sequence))
                                {
                                    continue;
                                }

                                var renderInfo = actorInfo.Value.TraitInfos <RenderSpritesInfo>().FirstOrDefault();
                                if (renderInfo == null)
                                {
                                    continue;
                                }

                                foreach (var faction in factions)
                                {
                                    var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault();
                                    if (sequenceReference != null && !string.IsNullOrEmpty(sequenceReference.ImageReference))
                                    {
                                        var imageField = fields.FirstOrDefault(f => f.Name == sequenceReference.ImageReference);
                                        if (imageField != null)
                                        {
                                            foreach (var imageOverride in LintExts.GetFieldValues(traitInfo, imageField, emitError))
                                            {
                                                if (!string.IsNullOrEmpty(imageOverride) && sequenceDefinitions.All(s => s.Key != imageOverride.ToLowerInvariant()))
                                                {
                                                    emitError("Custom sprite image {0} from actor {1} has no sequence definition.".F(imageOverride, actorInfo.Value.Name));
                                                }
                                                else
                                                {
                                                    CheckDefintions(imageOverride, sequenceReference, actorInfo, sequence, faction, field, traitInfo);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (var sequenceProvider in sequenceProviders)
                                        {
                                            var image = renderInfo.GetImage(actorInfo.Value, sequenceProvider, faction);
                                            CheckDefintions(image, sequenceReference, actorInfo, sequence, faction, field, traitInfo);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                foreach (var weaponInfo in rules.Weapons)
                {
                    var projectileInfo = weaponInfo.Value.Projectile;
                    if (projectileInfo == null)
                    {
                        continue;
                    }

                    var fields = projectileInfo.GetType().GetFields();
                    foreach (var field in fields)
                    {
                        if (field.HasAttribute <SequenceReferenceAttribute>())
                        {
                            var sequences = LintExts.GetFieldValues(projectileInfo, field, emitError);
                            foreach (var sequence in sequences)
                            {
                                if (string.IsNullOrEmpty(sequence))
                                {
                                    continue;
                                }

                                var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault();
                                if (sequenceReference != null && !string.IsNullOrEmpty(sequenceReference.ImageReference))
                                {
                                    var imageField = fields.FirstOrDefault(f => f.Name == sequenceReference.ImageReference);
                                    if (imageField != null)
                                    {
                                        foreach (var imageOverride in LintExts.GetFieldValues(projectileInfo, imageField, emitError))
                                        {
                                            if (!string.IsNullOrEmpty(imageOverride))
                                            {
                                                var definitions = sequenceDefinitions.FirstOrDefault(n => n.Key == imageOverride.ToLowerInvariant());
                                                if (definitions == null)
                                                {
                                                    emitError("Can't find sequence definition for projectile image {0} at weapon {1}.".F(imageOverride, weaponInfo.Key));
                                                }
                                                else if (!definitions.Value.Nodes.Any(n => n.Key == sequence))
                                                {
                                                    emitError("Projectile sprite image {0} from weapon {1} does not define sequence {2} from field {3} of {4}"
                                                              .F(imageOverride, weaponInfo.Key, sequence, field.Name, projectileInfo));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #54
0
        static void ExtractSmudges(MiniYaml yaml)
        {
            var smudges = yaml.Nodes.FirstOrDefault(n => n.Key == "Smudges");

            if (smudges == null || !smudges.Value.Nodes.Any())
            {
                return;
            }

            var scorches = new List <MiniYamlNode>();
            var craters  = new List <MiniYamlNode>();

            foreach (var s in smudges.Value.Nodes)
            {
                // loc=type,loc,depth
                var parts = s.Key.Split(' ');
                var value = "{0},{1}".F(parts[0], parts[2]);
                var node  = new MiniYamlNode(parts[1], value);
                if (parts[0].StartsWith("sc"))
                {
                    scorches.Add(node);
                }
                else if (parts[0].StartsWith("cr"))
                {
                    craters.Add(node);
                }
            }

            var rulesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules");

            if (rulesNode == null)
            {
                rulesNode = new MiniYamlNode("Rules", new MiniYaml("", new List <MiniYamlNode>()));
                yaml.Nodes.Add(rulesNode);
            }

            var worldNode = rulesNode.Value.Nodes.FirstOrDefault(n => n.Key == "World");

            if (worldNode == null)
            {
                worldNode = new MiniYamlNode("World", new MiniYaml("", new List <MiniYamlNode>()));
                rulesNode.Value.Nodes.Add(rulesNode);
            }

            if (scorches.Any())
            {
                var initialScorches = new MiniYamlNode("InitialSmudges", new MiniYaml("", scorches));
                var smudgeLayer     = new MiniYamlNode("SmudgeLayer@SCORCH", new MiniYaml("", new List <MiniYamlNode>()
                {
                    initialScorches
                }));
                worldNode.Value.Nodes.Add(smudgeLayer);
            }

            if (craters.Any())
            {
                var initialCraters = new MiniYamlNode("InitialSmudges", new MiniYaml("", craters));
                var smudgeLayer    = new MiniYamlNode("SmudgeLayer@CRATER", new MiniYaml("", new List <MiniYamlNode>()
                {
                    initialCraters
                }));
                worldNode.Value.Nodes.Add(smudgeLayer);
            }
        }
Пример #55
0
        public ModContentPromptLogic(Widget widget, Manifest mod, ModContent content, Action continueLoading)
        {
            this.content = content;
            CheckRequiredContentInstalled();

            var panel          = widget.Get("CONTENT_PROMPT_PANEL");
            var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE");
            var headerLines    = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : Array.Empty <string>();
            var headerHeight   = 0;

            foreach (var l in headerLines)
            {
                var line = (LabelWidget)headerTemplate.Clone();
                line.GetText   = () => l;
                line.Bounds.Y += headerHeight;
                panel.AddChild(line);

                headerHeight += headerTemplate.Bounds.Height;
            }

            panel.Bounds.Height += headerHeight;
            panel.Bounds.Y      -= headerHeight / 2;

            var advancedButton = panel.Get <ButtonWidget>("ADVANCED_BUTTON");

            advancedButton.Bounds.Y += headerHeight;
            advancedButton.OnClick   = () =>
            {
                Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs
                {
                    { "mod", mod },
                    { "content", content },
                    { "onCancel", CheckRequiredContentInstalled }
                });
            };

            var quickButton = panel.Get <ButtonWidget>("QUICK_BUTTON");

            quickButton.IsVisible = () => !string.IsNullOrEmpty(content.QuickDownload);
            quickButton.Bounds.Y += headerHeight;
            quickButton.OnClick   = () =>
            {
                var modObjectCreator  = new ObjectCreator(mod, Game.Mods);
                var modPackageLoaders = modObjectCreator.GetLoaders <IPackageLoader>(mod.PackageFormats, "package");
                var modFileSystem     = new FS(mod.Id, Game.Mods, modPackageLoaders);
                modFileSystem.LoadFromManifest(mod);

                var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null);
                modFileSystem.UnmountAll();

                var download = downloadYaml.FirstOrDefault(n => n.Key == content.QuickDownload);
                if (download == null)
                {
                    throw new InvalidOperationException($"Mod QuickDownload `{content.QuickDownload}` definition not found.");
                }

                Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs
                {
                    { "download", new ModContent.ModDownload(download.Value) },
                    { "onSuccess", continueLoading }
                });
            };

            var quitButton = panel.Get <ButtonWidget>("QUIT_BUTTON");

            quitButton.GetText   = () => requiredContentInstalled ? "Continue" : "Quit";
            quitButton.Bounds.Y += headerHeight;
            quitButton.OnClick   = () =>
            {
                if (requiredContentInstalled)
                {
                    continueLoading();
                }
                else
                {
                    Game.Exit();
                }
            };

            Game.RunAfterTick(Ui.ResetTooltips);
        }
Пример #56
0
 static object LoadUnitsCommonNames(MiniYaml y)
 {
     return(LoadList <string[]>(y, "UnitsCommonNames"));
 }
Пример #57
0
 static object LoadUnits(MiniYaml y)
 {
     return(LoadActorList(y, "UnitsToBuild"));
 }
Пример #58
0
 static object LoadActorList(MiniYaml y, string field)
 {
     return(y.NodesDict[field].Nodes.ToDictionary(
                t => t.Key,
                t => FieldLoader.GetValue <float>(field, t.Value.Value)));
 }
Пример #59
0
 static object LoadBuildingsCommonNames(MiniYaml y)
 {
     return(LoadList <string[]>(y, "BuildingCommonNames"));
 }
Пример #60
0
        internal static void UpgradeMapFormat(ModData modData, IReadWritePackage package)
        {
            if (package == null)
            {
                return;
            }

            var yamlStream = package.GetStream("map.yaml");

            if (yamlStream == null)
            {
                return;
            }

            var yaml      = new MiniYaml(null, MiniYaml.FromStream(yamlStream, package.Name));
            var nd        = yaml.ToDictionary();
            var mapFormat = FieldLoader.GetValue <int>("MapFormat", nd["MapFormat"].Value);

            if (mapFormat < 6)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(mapFormat, package.Name));
            }

            // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
            if (mapFormat < 7)
            {
                MiniYaml useAsShellmap;
                if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value))
                {
                    yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("Shellmap")));
                }
                else if (nd["Type"].Value == "Mission" || nd["Type"].Value == "Campaign")
                {
                    yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("MissionSelector")));
                }
            }

            // Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors
            if (mapFormat < 8)
            {
                var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players");
                if (players != null)
                {
                    bool noteHexColors = false;
                    bool noteColorRamp = false;
                    foreach (var player in players.Value.Nodes)
                    {
                        var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp");
                        if (colorRampNode != null)
                        {
                            Color dummy;
                            var   parts = colorRampNode.Value.Value.Split(',');
                            if (parts.Length == 3 || parts.Length == 4)
                            {
                                // Try to convert old normalized HSL value to a rgb hex color
                                try
                                {
                                    HSLColor color = new HSLColor(
                                        (byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255),
                                        (byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255),
                                        (byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255));
                                    colorRampNode.Value.Value = FieldSaver.FormatValue(color);
                                    noteHexColors             = true;
                                }
                                catch (Exception)
                                {
                                    throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name);
                                }
                            }
                            else if (parts.Length != 1 || !HSLColor.TryParseRGB(parts[0], out dummy))
                            {
                                throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name);
                            }

                            colorRampNode.Key = "Color";
                            noteColorRamp     = true;
                        }
                    }

                    if (noteHexColors)
                    {
                        Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa].");
                    }
                    else if (noteColorRamp)
                    {
                        Console.WriteLine("ColorRamp is now called Color.");
                    }
                }
            }

            // Format 8 -> 9 moved map options and videos from the map file itself to traits
            if (mapFormat < 9)
            {
                var rules     = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules");
                var worldNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "World");
                if (worldNode == null)
                {
                    worldNode = new MiniYamlNode("World", new MiniYaml("", new List <MiniYamlNode>()));
                }

                var playerNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "Player");
                if (playerNode == null)
                {
                    playerNode = new MiniYamlNode("Player", new MiniYaml("", new List <MiniYamlNode>()));
                }

                var visibilityNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Visibility");
                if (visibilityNode != null)
                {
                    var visibility = FieldLoader.GetValue <MapVisibility>("Visibility", visibilityNode.Value.Value);
                    if (visibility.HasFlag(MapVisibility.MissionSelector))
                    {
                        var missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List <MiniYamlNode>()));
                        worldNode.Value.Nodes.Add(missionData);

                        var description = yaml.Nodes.FirstOrDefault(n => n.Key == "Description");
                        if (description != null)
                        {
                            missionData.Value.Nodes.Add(new MiniYamlNode("Briefing", description.Value.Value));
                        }

                        var videos = yaml.Nodes.FirstOrDefault(n => n.Key == "Videos");
                        if (videos != null && videos.Value.Nodes.Any())
                        {
                            var backgroundVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "BackgroundInfo");
                            if (backgroundVideo != null)
                            {
                                missionData.Value.Nodes.Add(new MiniYamlNode("BackgroundVideo", backgroundVideo.Value.Value));
                            }

                            var briefingVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "Briefing");
                            if (briefingVideo != null)
                            {
                                missionData.Value.Nodes.Add(new MiniYamlNode("BriefingVideo", briefingVideo.Value.Value));
                            }

                            var startVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameStart");
                            if (startVideo != null)
                            {
                                missionData.Value.Nodes.Add(new MiniYamlNode("StartVideo", startVideo.Value.Value));
                            }

                            var winVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameWon");
                            if (winVideo != null)
                            {
                                missionData.Value.Nodes.Add(new MiniYamlNode("WinVideo", winVideo.Value.Value));
                            }

                            var lossVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameLost");
                            if (lossVideo != null)
                            {
                                missionData.Value.Nodes.Add(new MiniYamlNode("LossVideo", lossVideo.Value.Value));
                            }
                        }
                    }
                }

                var mapOptions = yaml.Nodes.FirstOrDefault(n => n.Key == "Options");
                if (mapOptions != null)
                {
                    var cheats = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Cheats");
                    if (cheats != null)
                    {
                        worldNode.Value.Nodes.Add(new MiniYamlNode("DeveloperMode", new MiniYaml("", new List <MiniYamlNode>()
                        {
                            new MiniYamlNode("Locked", "True"),
                            new MiniYamlNode("Enabled", cheats.Value.Value)
                        })));
                    }

                    var crates = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Crates");
                    if (crates != null && !worldNode.Value.Nodes.Any(n => n.Key == "-CrateSpawner"))
                    {
                        if (!FieldLoader.GetValue <bool>("crates", crates.Value.Value))
                        {
                            worldNode.Value.Nodes.Add(new MiniYamlNode("-CrateSpawner", new MiniYaml("")));
                        }
                    }

                    var creeps = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Creeps");
                    if (creeps != null)
                    {
                        worldNode.Value.Nodes.Add(new MiniYamlNode("MapCreeps", new MiniYaml("", new List <MiniYamlNode>()
                        {
                            new MiniYamlNode("Locked", "True"),
                            new MiniYamlNode("Enabled", creeps.Value.Value)
                        })));
                    }

                    var fog    = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Fog");
                    var shroud = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Shroud");
                    if (fog != null || shroud != null)
                    {
                        var shroudNode = new MiniYamlNode("Shroud", new MiniYaml("", new List <MiniYamlNode>()));
                        playerNode.Value.Nodes.Add(shroudNode);

                        if (fog != null)
                        {
                            shroudNode.Value.Nodes.Add(new MiniYamlNode("FogLocked", "True"));
                            shroudNode.Value.Nodes.Add(new MiniYamlNode("FogEnabled", fog.Value.Value));
                        }

                        if (shroud != null)
                        {
                            var enabled = FieldLoader.GetValue <bool>("shroud", shroud.Value.Value);
                            shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapLocked", "True"));
                            shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapEnabled", FieldSaver.FormatValue(!enabled)));
                        }
                    }

                    var allyBuildRadius = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "AllyBuildRadius");
                    if (allyBuildRadius != null)
                    {
                        worldNode.Value.Nodes.Add(new MiniYamlNode("MapBuildRadius", new MiniYaml("", new List <MiniYamlNode>()
                        {
                            new MiniYamlNode("AllyBuildRadiusLocked", "True"),
                            new MiniYamlNode("AllyBuildRadiusEnabled", allyBuildRadius.Value.Value)
                        })));
                    }

                    var startingCash = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "StartingCash");
                    if (startingCash != null)
                    {
                        playerNode.Value.Nodes.Add(new MiniYamlNode("PlayerResources", new MiniYaml("", new List <MiniYamlNode>()
                        {
                            new MiniYamlNode("DefaultCashLocked", "True"),
                            new MiniYamlNode("DefaultCash", startingCash.Value.Value)
                        })));
                    }

                    var startingUnits = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ConfigurableStartingUnits");
                    if (startingUnits != null && !worldNode.Value.Nodes.Any(n => n.Key == "-SpawnMPUnits"))
                    {
                        worldNode.Value.Nodes.Add(new MiniYamlNode("SpawnMPUnits", new MiniYaml("", new List <MiniYamlNode>()
                        {
                            new MiniYamlNode("Locked", "True"),
                        })));
                    }

                    var techLevel    = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "TechLevel");
                    var difficulties = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Difficulties");
                    var shortGame    = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ShortGame");
                    if (techLevel != null || difficulties != null || shortGame != null)
                    {
                        var optionsNode = new MiniYamlNode("MapOptions", new MiniYaml("", new List <MiniYamlNode>()));
                        worldNode.Value.Nodes.Add(optionsNode);

                        if (techLevel != null)
                        {
                            optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevelLocked", "True"));
                            optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevel", techLevel.Value.Value));
                        }

                        if (difficulties != null)
                        {
                            optionsNode.Value.Nodes.Add(new MiniYamlNode("Difficulties", difficulties.Value.Value));
                        }

                        if (shortGame != null)
                        {
                            optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameLocked", "True"));
                            optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameEnabled", shortGame.Value.Value));
                        }
                    }
                }

                if (worldNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(worldNode))
                {
                    rules.Value.Nodes.Add(worldNode);
                }

                if (playerNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(playerNode))
                {
                    rules.Value.Nodes.Add(playerNode);
                }
            }

            // Format 9 -> 10 moved smudges to SmudgeLayer, and uses map.png for all maps
            if (mapFormat < 10)
            {
                ExtractSmudges(yaml);
                if (package.Contains("map.png"))
                {
                    yaml.Nodes.Add(new MiniYamlNode("LockPreview", new MiniYaml("True")));
                }
            }

            // Format 10 -> 11 replaced the single map type field with a list of categories
            if (mapFormat < 11)
            {
                var type = yaml.Nodes.First(n => n.Key == "Type");
                yaml.Nodes.Add(new MiniYamlNode("Categories", type.Value));
                yaml.Nodes.Remove(type);
            }

            if (mapFormat < Map.SupportedMapFormat)
            {
                yaml.Nodes.First(n => n.Key == "MapFormat").Value = new MiniYaml(Map.SupportedMapFormat.ToString());
                Console.WriteLine("Converted {0} to MapFormat {1}.", package.Name, Map.SupportedMapFormat);
            }

            package.Update("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString()));
        }