#region Copyright & License Information /* * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. For more * information, see COPYING. */ #endregion using System; using System.Collections.Generic; using System.Linq; namespace OpenRA.Mods.Common.UpdateRules.Rules { public class DefineNotificationDefaults : UpdateRule { public override string Name { get { return "Move mod-specific notifications to yaml"; } } public override string Description { get { return "Mod-specific default notifications values have been removed from several traits and the Radar widget\n" + "(" + traits.Select(f => f.Trait).JoinWith(", ") + ")\n" + "The mod chrome is updated automatically and uses of these traits are listed for inspection so the values can be overriden in yaml."; } } class TraitWrapper { public readonly string Trait; public readonly Dictionary Fields; public List Uses = new List(); public TraitWrapper(string trait, Dictionary fields) { Trait = trait; Fields = fields; } } TraitWrapper[] traits = { new TraitWrapper("PrimaryBuilding", new Dictionary { { "SelectionNotification", "PrimaryBuildingSelected" } }), new TraitWrapper("RepairableBuilding", new Dictionary { { "RepairingNotification", "Repairing" } }), new TraitWrapper("RepairsUnits", new Dictionary { { "StartRepairingNotification", "Repairing" } }), new TraitWrapper("GainsExperience", new Dictionary { { "LevelUpNotification", "LevelUp" } }), new TraitWrapper("MissionObjectives", new Dictionary { { "WinNotification", "Win" }, { "LoseNotification", "Lose" }, { "LeaveNotification", "Leave" } }), new TraitWrapper("PlaceBuilding", new Dictionary { { "NewOptionsNotification", "NewOptions" }, { "CannotPlaceNotification", "BuildingCannotPlaceAudio" } }), new TraitWrapper("PlayerResources", new Dictionary { { "CashTickUpNotification", "CashTickUp" }, { "CashTickDownNotification", "CashTickDown" } }), new TraitWrapper("ProductionQueue", new Dictionary { { "ReadyAudio", "UnitReady" }, { "BlockedAudio", "NoBuild" }, { "QueuedAudio", "Training" }, { "OnHoldAudio", "OnHold" }, { "CancelledAudio", "Cancelled" } }), new TraitWrapper("PowerManager", new Dictionary { { "SpeechNotification", "LowPower" } }) }; string BuildMessage(TraitWrapper t) { return "Default notification values have been removed from {0}.\n".F(t.Trait) + "You may wish to explicitly define the following overrides:\n " + t.Trait + ":\n" + UpdateUtils.FormatMessageList(t.Fields.Select(kv => " " + kv.Key + ": " + kv.Value), separator: " ") + "\non the following actors (if they have not already been inherited from a parent).\n" + UpdateUtils.FormatMessageList(t.Uses); } public override IEnumerable AfterUpdate(ModData modData) { foreach (var t in traits) { if (t.Uses.Any()) yield return BuildMessage(t); t.Uses.Clear(); } } public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) { foreach (var t in traits) { foreach (var traitNode in actorNode.ChildrenMatching(t.Trait)) { foreach (var f in t.Fields) { var node = traitNode.LastChildMatching(f.Key); if (node == null) { var location = "{0} ({1})".F(actorNode.Key, traitNode.Location.Filename); if (!t.Uses.Contains(location)) t.Uses.Add(location); } } } } yield break; } public override IEnumerable UpdateChromeNode(ModData modData, MiniYamlNode chromeNode) { foreach (var node in chromeNode.ChildrenMatching("Radar")) { if (!node.ChildrenMatching("SoundUp").Any()) node.AddNode("SoundUp", "RadarUp"); if (!node.ChildrenMatching("SoundDown").Any()) node.AddNode("SoundDown", "RadarDown"); } yield break; } } }