Exemple #1
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var givesBuildableArea = actorNode.LastChildMatching("GivesBuildableArea");

            if (givesBuildableArea != null)
            {
                givesBuildableArea.AddNode("AreaTypes", "building");
            }

            var building = actorNode.LastChildMatching("Building");

            if (building != null)
            {
                var requiresBuildableArea = new MiniYamlNode("RequiresBuildableArea", "");
                requiresBuildableArea.AddNode("AreaTypes", "building");

                var adjacent = building.LastChildMatching("Adjacent");
                if (adjacent != null)
                {
                    requiresBuildableArea.AddNode(adjacent);
                }

                actorNode.AddNode(requiresBuildableArea);
                building.RemoveNodes("Adjacent");
            }

            yield break;
        }
Exemple #2
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var poolNumber = 0;
            var ammoPools  = actorNode.ChildrenMatching("AmmoPool").ToList();

            foreach (var pool in ammoPools)
            {
                var selfReloads = pool.LastChildMatching("SelfReloads");
                if (selfReloads == null || !selfReloads.NodeValue <bool>())
                {
                    continue;
                }

                poolNumber++;
                var reloadOnCond = new MiniYamlNode("ReloadAmmoPool@" + poolNumber, "");

                var name = pool.LastChildMatching("Name");
                if (name != null)
                {
                    reloadOnCond.AddNode("AmmoPool", name.NodeValue <string>());
                }

                var selfReloadDelay = pool.LastChildMatching("SelfReloadDelay");
                if (selfReloadDelay != null)
                {
                    selfReloadDelay.RenameKey("Delay");
                    reloadOnCond.AddNode(selfReloadDelay);
                    pool.RemoveNodes("SelfReloadDelay");
                }

                pool.RemoveNodes("SelfReloads");

                var reloadCount = pool.LastChildMatching("ReloadCount");
                if (reloadCount != null)
                {
                    reloadCount.RenameKey("Count");
                    reloadOnCond.AddNode(reloadCount);
                    pool.RemoveNodes("ReloadCount");
                }

                var reset = pool.LastChildMatching("ResetOnFire");
                if (reset != null)
                {
                    reloadOnCond.AddNode(reset);
                    pool.RemoveNodes("ResetOnFire");
                }

                var rearmSound = pool.LastChildMatching("RearmSound");
                if (rearmSound != null)
                {
                    rearmSound.RenameKey("Sound");
                    reloadOnCond.AddNode(rearmSound);
                    pool.RemoveNodes("RearmSound");
                }

                actorNode.AddNode(reloadOnCond);
            }

            yield break;
        }
        void AddShakeNode(MiniYamlNode actorNode)
        {
            var shake = new MiniYamlNode("ShakeOnDeath", "");

            shake.AddNode("Duration", "15");
            shake.AddNode("Intensity", "6");
            actorNode.AddNode(shake);
        }
        void UpdatePower(MiniYamlNode power)
        {
            var range     = 1;
            var rangeNode = power.LastChildMatching("Range");

            if (rangeNode != null)
            {
                range = rangeNode.NodeValue <int>();
                if (range > 3)
                {
                    locations.Add("{0} ({1})".F(rangeNode.Key, rangeNode.Location.Filename));
                }

                power.RemoveNode(rangeNode);
            }

            var size = 2 * range + 1;

            power.AddNode(new MiniYamlNode("Dimensions", size.ToString() + ", " + size.ToString()));

            var footprint = string.Empty;

            var emptycell    = range;
            var affectedcell = 1;

            for (var i = 0; i < size; i++)
            {
                for (var e = 0; e < emptycell; e++)
                {
                    footprint += '_';
                }

                for (var a = 0; a < affectedcell; a++)
                {
                    footprint += 'x';
                }

                for (var e = 0; e < emptycell; e++)
                {
                    footprint += '_';
                }

                if (i < range)
                {
                    emptycell--;
                    affectedcell += 2;
                }
                else
                {
                    emptycell++;
                    affectedcell -= 2;
                }

                footprint += ' ';
            }

            power.AddNode(new MiniYamlNode("Footprint", footprint));
        }
Exemple #5
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var autoSelectionSize = actorNode.LastChildMatching("AutoSelectionSize");

            if (autoSelectionSize != null)
            {
                actorNode.AddNode("Interactable", "");
            }

            var customSelectionSize = actorNode.LastChildMatching("CustomSelectionSize");

            if (customSelectionSize != null)
            {
                var bounds           = customSelectionSize.LastChildMatching("CustomBounds");
                var customRenderSize = new MiniYamlNode("Interactable", "");
                if (bounds != null)
                {
                    customRenderSize.AddNode("Bounds", bounds.NodeValue <int[]>());
                }

                actorNode.AddNode(customRenderSize);
            }

            var sd = actorNode.LastChildMatching("SelectionDecorations");

            if (sd != null)
            {
                var boundsNode = sd.LastChildMatching("VisualBounds");
                if (boundsNode != null)
                {
                    boundsNode.RenameKey("DecorationBounds");
                    sd.RemoveNode(boundsNode);
                    var selectable = actorNode.LastChildMatching("Selectable");
                    if (selectable == null)
                    {
                        selectable = new MiniYamlNode("Selectable", new MiniYaml(""));
                        actorNode.AddNode(selectable);
                    }

                    selectable.AddNode(boundsNode);
                }
            }

            if (actorNode.LastChildMatching("-Selectable") != null && actorNode.LastChildMatching("Interactable") == null)
            {
                actorNode.AddNode("Interactable", "");
            }

            actorNode.RemoveNodes("CustomSelectionSize");
            actorNode.RemoveNodes("AutoSelectionSize");
            yield break;
        }
Exemple #6
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var gate = actorNode.LastChildMatching("Gate");

            if (gate == null)
            {
                yield break;
            }

            var openSound    = gate.LastChildMatching("OpeningSound");
            var closeSound   = gate.LastChildMatching("ClosingSound");
            var closeDelay   = gate.LastChildMatching("CloseDelay");
            var transitDelay = gate.LastChildMatching("TransitionDelay");
            var blockHeight  = gate.LastChildMatching("BlocksProjectilesHeight");

            var newGate = new MiniYamlNode("Gate", "");

            gate.RenameKey("Building");

            if (openSound != null)
            {
                newGate.AddNode(openSound);
                gate.RemoveNode(openSound);
            }

            if (closeSound != null)
            {
                newGate.AddNode(closeSound);
                gate.RemoveNode(closeSound);
            }

            if (closeDelay != null)
            {
                newGate.AddNode(closeDelay);
                gate.RemoveNode(closeDelay);
            }

            if (transitDelay != null)
            {
                newGate.AddNode(transitDelay);
                gate.RemoveNode(transitDelay);
            }

            if (blockHeight != null)
            {
                newGate.AddNode(blockHeight);
                gate.RemoveNode(blockHeight);
            }

            actorNode.AddNode(newGate);
            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var canPowerDown = actorNode.LastChildMatching("CanPowerDown");

            if (canPowerDown == null)
            {
                yield break;
            }

            canPowerDown.AddNode("PowerdownCondition", "powerdown");

            var image      = canPowerDown.LastChildMatching("IndicatorImage");
            var seq        = canPowerDown.LastChildMatching("IndicatorSequence");
            var pal        = canPowerDown.LastChildMatching("IndicatorPalette");
            var imageValue = image != null?image.NodeValue <string>() : "poweroff";

            var seqValue = seq != null?seq.NodeValue <string>() : "offline";

            var palValue = pal != null?pal.NodeValue <string>() : "chrome";

            var indicator = new MiniYamlNode("WithDecoration@POWERDOWN", "");

            indicator.AddNode("Image", imageValue);
            indicator.AddNode("Sequence", seqValue);
            indicator.AddNode("Palette", palValue);
            indicator.AddNode("RequiresCondition", "powerdown");
            indicator.AddNode("ReferencePoint", "Center");

            actorNode.AddNode(indicator);
            if (image != null)
            {
                canPowerDown.RemoveNodes("IndicatorImage");
            }
            if (seq != null)
            {
                canPowerDown.RemoveNodes("IndicatorSequence");
            }
            if (pal != null)
            {
                canPowerDown.RemoveNodes("IndicatorPalette");
            }

            if (!displayed)
            {
                displayed = true;
                yield return("'CanPowerDown' now provides a condition. You might need to review your condition setup.");
            }
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            if (complete || actorNode.LastChildMatching("IsometricSelectable") != null)
            {
                yield break;
            }

            var height = 0;

            if (!selectionHeight.TryGetValue(actorNode.Key.ToLowerInvariant(), out height))
            {
                yield break;
            }

            // Don't redefine the default value
            if (height == 24)
            {
                yield break;
            }

            var selection = new MiniYamlNode("IsometricSelectable", "");

            selection.AddNode("Height", FieldSaver.FormatValue(height));

            actorNode.AddNode(selection);
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            // Aircraft isn't conditional or otherwise supports multiple traits, so LastChildMatching is fine.
            var aircraftNode = actorNode.LastChildMatching("Aircraft");

            if (aircraftNode != null)
            {
                var repairBuildings = aircraftNode.LastChildMatching("RepairBuildings");
                if (repairBuildings != null)
                {
                    var repariableNode = new MiniYamlNode("Repairable", "");
                    repairBuildings.MoveAndRenameNode(aircraftNode, repariableNode, "RepairBuildings");

                    var voice = aircraftNode.LastChildMatching("Voice");
                    if (voice != null)
                    {
                        repariableNode.AddNode(voice);
                    }

                    actorNode.AddNode(repariableNode);
                }
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            // RepairableBuilding is hardcoded to only support one instance per actor
            var rb = actorNode.LastChildMatching("RepairableBuilding");

            if (rb != null)
            {
                var imageNode         = rb.LastChildMatching("IndicatorImage");
                var sequenceNode      = rb.LastChildMatching("IndicatorSequence");
                var paletteNode       = rb.LastChildMatching("IndicatorPalette");
                var palettePrefixNode = rb.LastChildMatching("IndicatorPalettePrefix");

                var decoration = new MiniYamlNode("WithBuildingRepairDecoration", "");
                decoration.AddNode("Image", imageNode != null ? imageNode.Value.Value : "allyrepair");
                decoration.AddNode("Sequence", sequenceNode != null ? sequenceNode.Value.Value : "repair");
                decoration.AddNode("ReferencePoint", "Center");

                if (paletteNode != null)
                {
                    decoration.AddNode("Palette", paletteNode.Value.Value);
                }
                else
                {
                    decoration.AddNode("Palette", palettePrefixNode != null ? palettePrefixNode.Value.Value : "player");
                    decoration.AddNode("IsPlayerPalette", true);
                }

                actorNode.AddNode(decoration);

                rb.RemoveNode(imageNode);
                rb.RemoveNode(sequenceNode);
                rb.RemoveNode(paletteNode);
                rb.RemoveNode(palettePrefixNode);
            }

            if (actorNode.LastChildMatching("-RepairableBuilding") != null)
            {
                actorNode.AddNode("-WithBuildingRepairDecoration", "");
            }

            yield break;
        }
Exemple #11
0
        public override IEnumerable <string> UpdateChromeProviderNode(ModData modData, MiniYamlNode chromeProviderNode)
        {
            // Migrate image rectangles
            var regionsNode = new MiniYamlNode("Regions", "");

            foreach (var n in chromeProviderNode.Value.Nodes)
            {
                if (n.Key == "Inherits")
                {
                    continue;
                }

                // Reformat region as a list
                regionsNode.AddNode(n.Key, n.NodeValue <int[]>());

                if (n.Value.Nodes.Any())
                {
                    overrideLocations.Add("{0}.{1} ({2})".F(chromeProviderNode.Key, n.Key, chromeProviderNode.Location.Filename));
                }
            }

            chromeProviderNode.Value.Nodes.RemoveAll(n => n.Key != "Inherits");

            // Migrate image definition
            chromeProviderNode.AddNode(new MiniYamlNode("Image", chromeProviderNode.Value.Value));
            chromeProviderNode.Value.Value = "";

            if (!ExtractPanelDefinition(chromeProviderNode, regionsNode))
            {
                panelLocations.Add("{0} ({1})".F(chromeProviderNode.Key, chromeProviderNode.Location.Filename));
            }

            if (regionsNode.Value.Nodes.Any())
            {
                chromeProviderNode.AddNode(regionsNode);
            }

            yield break;
        }
Exemple #12
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            if (actorNode.ChildrenMatching("ResourceLayer").Any() && !actorNode.ChildrenMatching("ResourceRenderer").Any())
            {
                locations.Add($"{actorNode.Key} ({actorNode.Location.Filename})");
                var resourceRenderer = new MiniYamlNode("ResourceRenderer", "");
                resourceRenderer.AddNode("RenderTypes", "");
                actorNode.AddNode(resourceRenderer);
            }

            if (actorNode.ChildrenMatching("D2kResourceLayer").Any() && !actorNode.ChildrenMatching("D2kResourceRenderer").Any())
            {
                actorNode.RenameChildrenMatching("D2kResourceLayer", "ResourceLayer");

                locations.Add($"{actorNode.Key} ({actorNode.Location.Filename})");
                var resourceRenderer = new MiniYamlNode("D2kResourceRenderer", "");
                resourceRenderer.AddNode("RenderTypes", "");
                actorNode.AddNode(resourceRenderer);
            }

            yield break;
        }
Exemple #13
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var addNodes = new List <MiniYamlNode>();

            foreach (var burns in actorNode.ChildrenMatching("Burns"))
            {
                var anim      = burns.LastChildMatching("Anim");
                var animValue = anim != null?anim.NodeValue <string>() : "1";

                var damage      = burns.LastChildMatching("Damage");
                var damageValue = damage != null?damage.NodeValue <int>() : 1;

                var interval      = burns.LastChildMatching("Interval");
                var intervalValue = interval != null?interval.NodeValue <int>() : 8;

                var overlay = new MiniYamlNode("WithIdleOverlay@Burns", "");
                overlay.AddNode("Image", FieldSaver.FormatValue("fire"));
                overlay.AddNode("Sequence", FieldSaver.FormatValue(animValue));
                overlay.AddNode("IsDecoration", FieldSaver.FormatValue(true));
                addNodes.Add(overlay);

                var changesHealth = new MiniYamlNode("ChangesHealth", "");
                changesHealth.AddNode("Step", FieldSaver.FormatValue(-damageValue));
                changesHealth.AddNode("StartIfBelow", FieldSaver.FormatValue(101));
                changesHealth.AddNode("Delay", FieldSaver.FormatValue(intervalValue));
                addNodes.Add(changesHealth);
            }

            actorNode.RemoveNodes("Burns");

            foreach (var addNode in addNodes)
            {
                actorNode.AddNode(addNode);
            }

            yield break;
        }
		void ApplyChanges(MiniYamlNode actorNode, MiniYamlNode node)
		{
			// Type renamed to Types
			var type = node.LastChildMatching("Type");
			if (type != null)
				type.RenameKey("Types");

			// Allow(Allies|Neutral|Enemies) replaced with a ValidStances enum
			var stance = Stance.Neutral | Stance.Enemy;
			var allowAllies = node.LastChildMatching("AllowAllies");
			if (allowAllies != null)
			{
				if (allowAllies.NodeValue<bool>())
					stance |= Stance.Ally;
				else
					stance &= ~Stance.Ally;

				node.RemoveNode(allowAllies);
			}

			var allowNeutral = node.LastChildMatching("AllowNeutral");
			if (allowNeutral != null)
			{
				if (allowNeutral.NodeValue<bool>())
					stance |= Stance.Neutral;
				else
					stance &= ~Stance.Neutral;

				node.RemoveNode(allowNeutral);
			}

			var allowEnemies = node.LastChildMatching("AllowEnemies");
			if (allowEnemies != null)
			{
				if (allowEnemies.NodeValue<bool>())
					stance |= Stance.Enemy;
				else
					stance &= ~Stance.Enemy;

				node.RemoveNode(allowEnemies);
			}

			if (stance != (Stance.Neutral | Stance.Enemy))
				node.AddNode("ValidStances", stance);
		}
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            if (actorNode.Key != "Player")
            {
                yield break;
            }

            var hackyAIs = actorNode.ChildrenMatching("HackyAI");

            if (!hackyAIs.Any())
            {
                yield break;
            }

            foreach (var hackyAINode in hackyAIs)
            {
                // We no longer support individual values for each AI,
                // and in practice the default of 5 has proven to be a solid middle-ground,
                // so just removing any custom value and notifying the modder about it should suffice.
                var minQuotient = hackyAINode.LastChildMatching("MinOrderQuotientPerTick");
                if (minQuotient != null)
                {
                    hackyAINode.RemoveNode(minQuotient);
                    if (!showMessage)
                    {
                        showMessage = true;
                    }
                }
            }

            var botOrderManager = actorNode.LastChildMatching("BotOrderManager");

            if (botOrderManager == null)
            {
                var addBotOrderManager = new MiniYamlNode("BotOrderManager", "");
                actorNode.AddNode(addBotOrderManager);
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var nukePowers = actorNode.ChildrenMatching("NukePower").ToList();

            foreach (var nuke in nukePowers)
            {
                var activation = nuke.LastChildMatching("ActivationSequence");
                if (activation == null)
                {
                    continue;
                }

                var sequence = activation.NodeValue <string>();
                nuke.RemoveNode(activation);
                actorNode.AddNode("WithNukeLaunchAnimation", "");
                if (sequence != "active")
                {
                    actorNode.LastChildMatching("WithNukeLaunchAnimation").AddNode("Sequence", sequence);
                }
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var aircraft       = actorNode.LastChildMatching("Aircraft");
            var attackAircraft = actorNode.ChildrenMatching("AttackAircraft");

            if (aircraft != null)
            {
                var abortOnResupply = aircraft.LastChildMatching("AbortOnResupply");
                if (abortOnResupply == null)
                {
                    yield break;
                }

                // Only add field to AttackAircraft if explicitly set to 'false'
                if (!abortOnResupply.NodeValue <bool>())
                {
                    if (attackAircraft.Any())
                    {
                        foreach (var a in attackAircraft)
                        {
                            a.AddNode(abortOnResupply);
                        }
                    }
                    else
                    {
                        var newAttackAircraft = new MiniYamlNode("AttackAircraft", "");
                        newAttackAircraft.AddNode(abortOnResupply);
                        actorNode.AddNode(newAttackAircraft);
                    }
                }

                aircraft.RemoveNode(abortOnResupply);
            }

            yield break;
        }
Exemple #18
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            foreach (var resourceNode in actorNode.ChildrenMatching("ResourceType"))
            {
                var typeNode = resourceNode.LastChildMatching("Type");
                if (typeNode != null)
                {
                    var resourceLayerNode = new MiniYamlNode(typeNode.Value.Value, "");
                    resourceLayer.Nodes.Add(resourceLayerNode);

                    var resourceRendererNode = new MiniYamlNode(typeNode.Value.Value, "");
                    resourceRenderer.Nodes.Add(resourceRendererNode);

                    var indexNode = resourceNode.LastChildMatching("ResourceType");
                    if (indexNode != null)
                    {
                        indexNode.RenameKey("ResourceIndex");
                        resourceLayerNode.AddNode(indexNode);
                    }

                    var terrainTypeNode = resourceNode.LastChildMatching("TerrainType");
                    if (terrainTypeNode != null)
                    {
                        resourceLayerNode.AddNode(terrainTypeNode);
                    }

                    var allowedTerrainNode = resourceNode.LastChildMatching("AllowedTerrainTypes");
                    if (allowedTerrainNode != null)
                    {
                        resourceLayerNode.AddNode(allowedTerrainNode);
                    }

                    var maxDensityNode = resourceNode.LastChildMatching("MaxDensity");
                    if (maxDensityNode != null)
                    {
                        resourceLayerNode.AddNode(maxDensityNode);
                    }

                    var valueNode = resourceNode.LastChildMatching("ValuePerUnit");
                    if (valueNode != null)
                    {
                        values.Nodes.Add(new MiniYamlNode(typeNode.Value.Value, valueNode.Value.Value));
                    }

                    var imageNode = resourceNode.LastChildMatching("Image");
                    if (imageNode != null)
                    {
                        resourceRendererNode.AddNode(imageNode);
                    }

                    var sequencesNode = resourceNode.LastChildMatching("Sequences");
                    if (sequencesNode != null)
                    {
                        resourceRendererNode.AddNode(sequencesNode);
                    }

                    var paletteNode = resourceNode.LastChildMatching("Palette");
                    if (paletteNode != null)
                    {
                        resourceRendererNode.AddNode(paletteNode);
                    }

                    var nameNode = resourceNode.LastChildMatching("Name");
                    if (nameNode != null)
                    {
                        resourceRendererNode.AddNode(nameNode);
                    }
                }
                else
                {
                    yield return("Unable to process definition:\n" +
                                 resourceNode.Value.ToLines(resourceNode.Key).JoinWith("\n") + "\n\n" +
                                 "This override has been removed and must be manually reimplemented if still needed.");
                }
            }

            actorNode.RemoveNodes("ResourceType");

            foreach (var resourceRendererNode in actorNode.ChildrenMatching("ResourceRenderer"))
            {
                resourceRendererNode.RemoveNodes("RenderTypes");
            }

            foreach (var resourceRendererNode in actorNode.ChildrenMatching("D2kResourceRenderer"))
            {
                resourceRendererNode.RemoveNodes("RenderTypes");
            }
        }
Exemple #19
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var reportLocation     = "{0} ({1})".F(actorNode.Key, actorNode.Location.Filename);
            var captureManager     = actorNode.LastChildMatching("CaptureManager") ?? new MiniYamlNode("CaptureManager", "");
            var usesCaptureManager = false;

            // Migrate External*
            foreach (var c in actorNode.ChildrenMatching("ExternalCapturable"))
            {
                c.RenameKey("Capturable");
                if (c.RemoveNodes("CaptureCompleteTime") > 0)
                {
                    externalDelayLocations.Add(reportLocation);
                }
            }

            foreach (var c in actorNode.ChildrenMatching("ExternalCaptures"))
            {
                c.RenameKey("Captures");
                if (c.Key.StartsWith("-"))
                {
                    continue;
                }

                c.AddNode("CaptureDelay", 375);

                var consumeNode = c.LastChildMatching("ConsumeActor");
                if (consumeNode != null)
                {
                    consumeNode.RenameKey("ConsumedByCapture");
                }
                else
                {
                    c.AddNode("ConsumedByCapture", false);
                }

                var conditionNode = c.LastChildMatching("CapturingCondition");
                if (conditionNode != null)
                {
                    conditionNode.MoveNode(c, captureManager);
                }

                var cursorNode = c.LastChildMatching("CaptureCursor");
                if (cursorNode != null)
                {
                    cursorNode.RenameKey("EnterCursor");
                }
                else
                {
                    c.AddNode("EnterCursor", "ability");
                }

                var cursorBlockedNode = c.LastChildMatching("CaptureBlockedCursor");
                if (cursorBlockedNode != null)
                {
                    cursorBlockedNode.RenameKey("EnterBlockedCursor");
                }
                else
                {
                    c.AddNode("EnterBlockedCursor", "move-blocked");
                }
            }

            var addBlinker = false;

            foreach (var c in actorNode.ChildrenMatching("ExternalCapturableBar"))
            {
                c.RenameKey("CapturableProgressBar");
                addBlinker = true;
            }

            if (addBlinker)
            {
                actorNode.AddNode("CapturableProgressBlink", "");
            }

            // Remove any CaptureThreshold nodes and restore the "building" default
            // These run on converted External* traits too
            foreach (var traitNode in actorNode.ChildrenMatching("Capturable"))
            {
                if (!traitNode.Key.StartsWith("-"))
                {
                    usesCaptureManager = true;
                }

                if (traitNode.RemoveNodes("CaptureThreshold") + traitNode.RemoveNodes("Sabotage") > 0)
                {
                    sabotageLocations.Add(reportLocation);
                }

                if (!traitNode.Key.StartsWith("-") && traitNode.LastChildMatching("Types") == null)
                {
                    traitNode.AddNode("Types", "building");
                }
            }

            foreach (var traitNode in actorNode.ChildrenMatching("Captures"))
            {
                if (!traitNode.Key.StartsWith("-"))
                {
                    usesCaptureManager = true;
                }

                if (traitNode.LastChildMatching("CaptureTypes") == null)
                {
                    traitNode.AddNode("CaptureTypes", "building");
                }
            }

            if (usesCaptureManager && actorNode.LastChildMatching("CaptureManager") == null)
            {
                actorNode.AddNode(captureManager);
                captureManagerLocations.Add(reportLocation);
            }

            yield break;
        }
Exemple #20
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var turretAttack = actorNode.LastChildMatching("WithTurretAttackAnimation");

            if (turretAttack != null)
            {
                var attackSequence = turretAttack.LastChildMatching("AttackSequence");
                var aimSequence    = turretAttack.LastChildMatching("AimSequence");
                var reloadPrefix   = turretAttack.LastChildMatching("ReloadPrefix");

                if (aimSequence != null)
                {
                    aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
                }

                if (reloadPrefix != null)
                {
                    reloadPrefixLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
                }

                // If only AttackSequence is not null, just rename AttackSequence to Sequence.
                // If only the prefix isn't null (extremely unlikely, but you never know), just rename the trait.
                // If AttackSequence is null but AimSequence isn't, rename the trait and property.
                // If both aren't null, split/copy everything relevant to the new WithTurretAimAnimation.
                // If both are null (extremely unlikely), do nothing.
                if (attackSequence != null && aimSequence == null)
                {
                    attackSequence.RenameKey("Sequence");
                }
                else if (attackSequence == null && aimSequence == null && reloadPrefix != null)
                {
                    turretAttack.RemoveNode(reloadPrefix);
                    turretAttack.RenameKey("WithTurretAimAnimation");
                }
                else if (attackSequence == null && aimSequence != null)
                {
                    turretAttack.RenameKey("WithTurretAimAnimation");
                    aimSequence.RenameKey("Sequence");
                    if (reloadPrefix != null)
                    {
                        turretAttack.RemoveNode(reloadPrefix);
                    }
                }
                else if (attackSequence != null && aimSequence != null)
                {
                    var turretAim = new MiniYamlNode("WithTurretAimAnimation", "");
                    aimSequence.MoveAndRenameNode(turretAttack, turretAim, "Sequence");

                    var turret   = turretAttack.LastChildMatching("Turret");
                    var armament = turretAttack.LastChildMatching("Armament");
                    if (reloadPrefix != null)
                    {
                        turretAttack.RemoveNode(reloadPrefix);
                    }

                    if (turret != null)
                    {
                        turretAim.AddNode(turret);
                    }
                    if (armament != null)
                    {
                        turretAim.AddNode(armament);
                    }

                    attackSequence.RenameKey("Sequence");
                    actorNode.AddNode(turretAim);
                }
            }

            var spriteTurret = actorNode.LastChildMatching("WithSpriteTurret");

            if (spriteTurret != null)
            {
                var aimSequence = spriteTurret.LastChildMatching("AimSequence");
                if (aimSequence != null)
                {
                    aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));

                    var aimAnim = new MiniYamlNode("WithTurretAimAnimation", "");
                    aimSequence.MoveAndRenameNode(spriteTurret, aimAnim, "Sequence");
                    actorNode.AddNode(aimAnim);
                }
            }

            var attackAnim = actorNode.LastChildMatching("WithAttackAnimation");

            if (attackAnim != null)
            {
                var attackSequence = attackAnim.LastChildMatching("AttackSequence");
                var aimSequence    = attackAnim.LastChildMatching("AimSequence");
                var reloadPrefix   = attackAnim.LastChildMatching("ReloadPrefix");

                if (aimSequence != null)
                {
                    aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
                }

                if (reloadPrefix != null)
                {
                    reloadPrefixLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
                }

                // If only AttackSequence is not null, just rename AttackSequence to Sequence.
                // If only the prefix isn't null (extremely unlikely, but you never know), just rename the trait.
                // If AttackSequence is null but AimSequence isn't, rename the trait and property.
                // If both sequences aren't null, split/copy everything relevant to the new WithAimAnimation.
                // If both sequences and the prefix are null (extremely unlikely), do nothing.
                if (attackSequence != null && aimSequence == null && reloadPrefix == null)
                {
                    attackSequence.RenameKey("Sequence");
                }
                else if (attackSequence == null && aimSequence == null && reloadPrefix != null)
                {
                    attackAnim.RemoveNode(reloadPrefix);
                    attackAnim.RenameKey("WithAimAnimation");
                }
                else if (attackSequence == null && aimSequence != null)
                {
                    attackAnim.RenameKey("WithAimAnimation");
                    aimSequence.RenameKey("Sequence");
                    if (reloadPrefix != null)
                    {
                        attackAnim.RemoveNode(reloadPrefix);
                    }
                }
                else if (attackSequence != null && aimSequence != null)
                {
                    var aimAnim = new MiniYamlNode("WithAimAnimation", "");
                    aimSequence.MoveAndRenameNode(attackAnim, aimAnim, "Sequence");

                    var body     = attackAnim.LastChildMatching("Body");
                    var armament = attackAnim.LastChildMatching("Armament");
                    if (reloadPrefix != null)
                    {
                        attackAnim.RemoveNode(reloadPrefix);
                    }

                    if (body != null)
                    {
                        aimAnim.AddNode(body);
                    }
                    if (armament != null)
                    {
                        aimAnim.AddNode(armament);
                    }

                    attackSequence.RenameKey("Sequence");
                    actorNode.AddNode(aimAnim);
                }
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            if (actorNode.Key != "Player")
            {
                yield break;
            }

            var hackyAIs = actorNode.ChildrenMatching("HackyAI");

            if (!hackyAIs.Any())
            {
                yield break;
            }

            var addNodes = new List <MiniYamlNode>();

            // We add a 'default' HarvesterBotModule in any case,
            // and only add more for AIs that define custom values for one of its fields.
            var defaultHarvNode = new MiniYamlNode("HarvesterBotModule", "");

            foreach (var hackyAINode in hackyAIs)
            {
                // HackyAIInfo.Name might contain spaces, so Type is better suited to be used as condition name
                var aiType            = hackyAINode.LastChildMatching("Type").NodeValue <string>();
                var conditionString   = "enable-" + aiType + "-ai";
                var requiresCondition = new MiniYamlNode("RequiresCondition", conditionString);

                var addGrantConditionOnBotOwner = true;
                var grantBotConditions          = actorNode.ChildrenMatching("GrantConditionOnBotOwner");
                foreach (var grant in grantBotConditions)
                {
                    if (grant.LastChildMatching("Condition").NodeValue <string>() == conditionString)
                    {
                        addGrantConditionOnBotOwner = false;
                    }
                }

                if (addGrantConditionOnBotOwner)
                {
                    var grantNode      = new MiniYamlNode("GrantConditionOnBotOwner@" + aiType, "");
                    var grantCondition = new MiniYamlNode("Condition", conditionString);
                    var bot            = new MiniYamlNode("Bots", aiType);
                    grantNode.AddNode(grantCondition);
                    grantNode.AddNode(bot);
                    addNodes.Add(grantNode);
                }

                if (harvesterFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var harvNode = new MiniYamlNode("HarvesterBotModule@" + aiType, "");
                    harvNode.AddNode(requiresCondition);

                    foreach (var hf in harvesterFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(hf);
                        if (fieldNode != null)
                        {
                            if (hf == "AssignRolesInterval")
                            {
                                fieldNode.MoveAndRenameNode(hackyAINode, harvNode, "ScanForIdleHarvestersInterval");
                            }
                            else
                            {
                                fieldNode.MoveNode(hackyAINode, harvNode);
                            }
                        }
                    }

                    addNodes.Add(harvNode);
                }
                else
                {
                    // We want the default module to be enabled for every AI that didn't customise one of its fields,
                    // so we need to update RequiresCondition to be enabled on any of the conditions granted by these AIs,
                    // but only if the condition hasn't been added yet.
                    var requiresConditionNode = defaultHarvNode.LastChildMatching("RequiresCondition");
                    if (requiresConditionNode == null)
                    {
                        defaultHarvNode.AddNode(requiresCondition);
                    }
                    else
                    {
                        var oldValue = requiresConditionNode.NodeValue <string>();
                        if (oldValue.Contains(conditionString))
                        {
                            continue;
                        }

                        requiresConditionNode.ReplaceValue(oldValue + " || " + conditionString);
                    }
                }
            }

            addNodes.Add(defaultHarvNode);

            foreach (var node in addNodes)
            {
                actorNode.AddNode(node);
            }

            yield break;
        }
Exemple #22
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var locationKey = $"{actorNode.Key} ({actorNode.Location.Filename})";
            var anyConditionalSmokeTrail = false;

            foreach (var smokeTrail in actorNode.ChildrenMatching("SmokeTrailWhenDamaged"))
            {
                var spriteNode = smokeTrail.LastChildMatching("Sprite");
                if (spriteNode != null)
                {
                    smokeTrail.RenameChildrenMatching("Sprite", "Image");
                }
                else
                {
                    smokeTrail.AddNode("Image", FieldSaver.FormatValue("smokey"));
                }

                var intervalNode = smokeTrail.LastChildMatching("Interval");
                if (intervalNode != null)
                {
                    var interval = intervalNode.NodeValue <int>();
                    smokeTrail.RenameChildrenMatching("Interval", "MovingInterval");
                    smokeTrail.AddNode("StationaryInterval", FieldSaver.FormatValue(interval));
                }
                else
                {
                    smokeTrail.AddNode("MovingInterval", FieldSaver.FormatValue(3));
                    smokeTrail.AddNode("StationaryInterval", FieldSaver.FormatValue(3));
                }

                var minDamageNode = smokeTrail.LastChildMatching("MinDamage");
                var isConditional = true;
                if (minDamageNode != null)
                {
                    var minDamage = minDamageNode.NodeValue <string>();
                    if (minDamage == "Undamaged")
                    {
                        isConditional = false;
                    }
                    else if (minDamage != "Heavy")
                    {
                        locations.GetOrAdd(locationKey).Add(smokeTrail.Key);
                    }

                    smokeTrail.RemoveNode(minDamageNode);
                }

                smokeTrail.AddNode("SpawnAtLastPosition", FieldSaver.FormatValue(false));
                smokeTrail.AddNode("TrailWhileStationary", FieldSaver.FormatValue(true));
                smokeTrail.AddNode("Type", FieldSaver.FormatValue("CenterPosition"));

                if (isConditional)
                {
                    smokeTrail.AddNode("RequiresCondition", FieldSaver.FormatValue("enable-smoke"));
                    anyConditionalSmokeTrail = true;
                }

                smokeTrail.RenameChildrenMatching("Sequence", "Sequences");
                smokeTrail.RenameChildrenMatching("Offset", "Offsets");
                smokeTrail.RenameKey("LeavesTrails");
            }

            if (anyConditionalSmokeTrail)
            {
                var grantCondition = new MiniYamlNode("GrantConditionOnDamageState@SmokeTrail", "");
                grantCondition.AddNode("Condition", FieldSaver.FormatValue("enable-smoke"));
                actorNode.AddNode(grantCondition);
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var addNodes = new List <MiniYamlNode>();

            foreach (var selectionDecorations in actorNode.ChildrenMatching("SelectionDecorations"))
            {
                customPips |= selectionDecorations.RemoveNodes("Palette") > 0;
                customPips |= selectionDecorations.RemoveNodes("Image") > 0;
            }

            foreach (var ammoPool in actorNode.ChildrenMatching("AmmoPool"))
            {
                var ammoPips = new MiniYamlNode("WithAmmoPipsDecoration", "");
                ammoPips.AddNode("Position", "BottomLeft");
                ammoPips.AddNode("RequiresSelection", "true");

                var pipCountNode = ammoPool.LastChildMatching("PipCount");
                if (pipCountNode != null)
                {
                    ammoPool.RemoveNode(pipCountNode);
                    var pipCount = pipCountNode.NodeValue <int>();
                    if (pipCount == 0)
                    {
                        addNodes.Add(new MiniYamlNode("-" + ammoPips.Key, ""));
                        continue;
                    }

                    var ammoNode = ammoPool.LastChildMatching("Ammo");
                    var maxAmmo  = ammoNode != null?ammoNode.NodeValue <int>() : 0;

                    if (pipCount != maxAmmo)
                    {
                        ammoPips.AddNode("PipCount", pipCount);
                    }
                }

                var pipTypeNode = ammoPool.LastChildMatching("PipType");
                if (pipTypeNode != null)
                {
                    ammoPool.RemoveNode(pipTypeNode);

                    if (PipReplacements.TryGetValue(pipTypeNode.Value.Value.ToLowerInvariant(), out var sequence))
                    {
                        ammoPips.AddNode("FullSequence", sequence);
                    }
                }

                var pipTypeEmptyNode = ammoPool.LastChildMatching("PipTypeEmpty");
                if (pipTypeEmptyNode != null)
                {
                    ammoPool.RemoveNode(pipTypeEmptyNode);

                    if (PipReplacements.TryGetValue(pipTypeEmptyNode.Value.Value.ToLowerInvariant(), out var sequence))
                    {
                        ammoPips.AddNode("EmptySequence", sequence);
                    }
                }

                addNodes.Add(ammoPips);
                locations.Add("{0}: {1} ({2})".F(actorNode.Key, ammoPips.Key, actorNode.Location.Filename));
            }

            foreach (var cargo in actorNode.ChildrenMatching("Cargo"))
            {
                var cargoPips = new MiniYamlNode("WithCargoPipsDecoration", "");
                cargoPips.AddNode("Position", "BottomLeft");
                cargoPips.AddNode("RequiresSelection", "true");

                var pipCountNode = cargo.LastChildMatching("PipCount");
                if (pipCountNode != null)
                {
                    cargo.RemoveNode(pipCountNode);

                    var pipCount = pipCountNode.NodeValue <int>();
                    if (pipCount == 0)
                    {
                        addNodes.Add(new MiniYamlNode("-" + cargoPips.Key, ""));
                        continue;
                    }

                    var maxWeightNode = cargo.LastChildMatching("MaxWeight");
                    var maxWeight     = maxWeightNode != null?maxWeightNode.NodeValue <int>() : 0;

                    if (pipCount != maxWeight)
                    {
                        cargoPips.AddNode("PipCount", pipCount);
                    }
                }
                else
                {
                    continue;
                }

                addNodes.Add(cargoPips);
                locations.Add("{0}: {1} ({2})".F(actorNode.Key, cargoPips.Key, actorNode.Location.Filename));
                cargoPipLocations.Add("{0} ({1})".F(actorNode.Key, actorNode.Location.Filename));
            }

            foreach (var passenger in actorNode.ChildrenMatching("Passenger"))
            {
                var pipTypeNode = passenger.LastChildMatching("PipType");
                if (pipTypeNode != null)
                {
                    pipTypeNode.RenameKey("CustomPipType");
                    pipTypeNode.Value.Value = pipTypeNode.Value.Value.ToLowerInvariant();
                    cargoCustomPips.Add(pipTypeNode.Value.Value);
                }
            }

            foreach (var harvester in actorNode.ChildrenMatching("Harvester"))
            {
                var harvesterPips = new MiniYamlNode("WithHarvesterPipsDecoration", "");
                harvesterPips.AddNode("Position", "BottomLeft");
                harvesterPips.AddNode("RequiresSelection", "true");

                // Harvester hardcoded a default PipCount > 0 so we can't use that to determine whether
                // this is a definition or an override. Resources isn't ideal either, but is better than nothing
                var resourcesNode = harvester.LastChildMatching("Resources");
                if (resourcesNode == null)
                {
                    continue;
                }

                var pipCountNode = harvester.LastChildMatching("PipCount");
                if (pipCountNode != null)
                {
                    harvester.RemoveNode(pipCountNode);

                    var pipCount = pipCountNode.NodeValue <int>();
                    if (pipCount == 0)
                    {
                        addNodes.Add(new MiniYamlNode("-" + harvesterPips.Key, ""));
                        continue;
                    }

                    harvesterPips.AddNode("PipCount", pipCount);
                }
                else
                {
                    harvesterPips.AddNode("PipCount", 7);
                }

                addNodes.Add(harvesterPips);
                locations.Add("{0}: {1} ({2})".F(actorNode.Key, harvesterPips.Key, actorNode.Location.Filename));
                harvesterPipLocations.Add("{0} ({1})".F(actorNode.Key, actorNode.Location.Filename));
            }

            foreach (var resourceType in actorNode.ChildrenMatching("ResourceType"))
            {
                var pipColor     = "yellow";
                var pipCountNode = resourceType.LastChildMatching("PipColor");
                if (pipCountNode != null)
                {
                    pipColor = pipCountNode.Value.Value.ToLowerInvariant();
                    resourceType.RemoveNode(pipCountNode);
                }

                var typeNode = resourceType.LastChildMatching("Type");
                if (typeNode != null)
                {
                    harvesterCustomPips.Add(typeNode.Value.Value, pipColor);
                }
            }

            foreach (var storesResources in actorNode.ChildrenMatching("StoresResources"))
            {
                var storagePips = new MiniYamlNode("WithResourceStoragePipsDecoration", "");
                storagePips.AddNode("Position", "BottomLeft");
                storagePips.AddNode("RequiresSelection", "true");

                var pipCountNode = storesResources.LastChildMatching("PipCount");
                if (pipCountNode != null)
                {
                    storesResources.RemoveNode(pipCountNode);
                    var pipCount = pipCountNode.NodeValue <int>();
                    if (pipCount == 0)
                    {
                        addNodes.Add(new MiniYamlNode("-" + storagePips.Key, ""));
                        continue;
                    }

                    storagePips.AddNode("PipCount", pipCount);
                }
                else
                {
                    continue;
                }

                // Default pip color changed from yellow to green for consistency with other pip traits
                var pipColorNode = storesResources.LastChildMatching("PipColor");
                if (pipColorNode != null)
                {
                    storesResources.RemoveNode(pipColorNode);

                    var type = pipColorNode.Value.Value.ToLowerInvariant();
                    if (type != "green" && PipReplacements.TryGetValue(type, out var sequence))
                    {
                        storagePips.AddNode("FullSequence", sequence);
                    }
                }
                else
                {
                    storagePips.AddNode("FullSequence", PipReplacements["yellow"]);
                }

                addNodes.Add(storagePips);
                locations.Add("{0}: {1} ({2})".F(actorNode.Key, storagePips.Key, actorNode.Location.Filename));
            }

            foreach (var addNode in addNodes)
            {
                actorNode.AddNode(addNode);
            }

            yield break;
        }
Exemple #24
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            if (actorNode.Key != "Player")
            {
                yield break;
            }

            var dummyAIs = actorNode.ChildrenMatching("DummyAI");

            foreach (var dummyAINode in dummyAIs)
            {
                dummyAINode.RenameKey("DummyBot");
            }

            var hackyAIRemovals = actorNode.ChildrenMatching("-HackyAI");

            foreach (var hackyAIRemovalNode in hackyAIRemovals)
            {
                hackyAIRemovalNode.RenameKey("-ModularBot");
            }

            var hackyAIs = actorNode.ChildrenMatching("HackyAI", includeRemovals: false);

            if (!hackyAIs.Any())
            {
                yield break;
            }

            var addNodes = new List <MiniYamlNode>();

            // We add a 'default' HarvesterBotModule in any case (unless the file doesn't contain any HackyAI base definition),
            // and only add more for AIs that define custom values for one of its fields.
            var defaultHarvNode = new MiniYamlNode("HarvesterBotModule", "");

            // We add a 'default' BuildingRepairBotModule in any case,
            // and just don't enable it for AIs that had 'ShouldRepairBuildings: false'.
            var defaultRepairNode = new MiniYamlNode("BuildingRepairBotModule", "");

            foreach (var hackyAINode in hackyAIs)
            {
                // HackyAIInfo.Name might contain spaces, so Type is better suited to be used as condition name.
                // Type can be 'null' if the place we're updating is overriding the default rules (like a map's rules.yaml).
                // If that's the case, it's better to not perform most of the updates on this particular yaml file,
                // as most - or more likely all - necessary updates will already have been performed on the base ai yaml.
                var aiTypeNode = hackyAINode.LastChildMatching("Type");
                var aiType     = aiTypeNode != null?aiTypeNode.NodeValue <string>() : null;

                if (aiType == null)
                {
                    locations.Add("{0} ({1})".F(hackyAINode.Key, hackyAINode.Location.Filename));
                    continue;
                }

                var conditionString = "enable-" + aiType + "-ai";

                var addGrantConditionOnBotOwner = true;

                // Don't add GrantConditionOnBotOwner if it's already been added with matching condition
                var grantBotConditions = actorNode.ChildrenMatching("GrantConditionOnBotOwner");
                foreach (var grant in grantBotConditions)
                {
                    if (grant.LastChildMatching("Condition").NodeValue <string>() == conditionString)
                    {
                        addGrantConditionOnBotOwner = false;
                    }
                }

                if (addGrantConditionOnBotOwner)
                {
                    var grantNode      = new MiniYamlNode("GrantConditionOnBotOwner@" + aiType, "");
                    var grantCondition = new MiniYamlNode("Condition", conditionString);
                    var bot            = new MiniYamlNode("Bots", aiType);
                    grantNode.AddNode(grantCondition);
                    grantNode.AddNode(bot);
                    addNodes.Add(grantNode);
                }

                if (harvesterFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var harvNode = new MiniYamlNode("HarvesterBotModule@" + aiType, "");
                    harvNode.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var hf in harvesterFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(hf);
                        if (fieldNode != null)
                        {
                            if (hf == "AssignRolesInterval")
                            {
                                fieldNode.MoveAndRenameNode(hackyAINode, harvNode, "ScanForIdleHarvestersInterval");
                            }
                            else
                            {
                                fieldNode.MoveNode(hackyAINode, harvNode);
                            }
                        }
                    }

                    addNodes.Add(harvNode);
                }
                else
                {
                    // We want the default harvester module to be enabled for every AI that didn't customise one of its fields,
                    // so we need to update RequiresCondition to be enabled on any of the conditions granted by these AIs,
                    // but only if the condition hasn't been added yet.
                    var requiresConditionNode = defaultHarvNode.LastChildMatching("RequiresCondition");
                    if (requiresConditionNode == null)
                    {
                        defaultHarvNode.AddNode(new MiniYamlNode("RequiresCondition", conditionString));
                    }
                    else
                    {
                        var oldValue = requiresConditionNode.NodeValue <string>();
                        if (oldValue.Contains(conditionString))
                        {
                            continue;
                        }

                        requiresConditionNode.ReplaceValue(oldValue + " || " + conditionString);
                    }
                }

                if (supportPowerFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var spNode = new MiniYamlNode("SupportPowerBotModule@" + aiType, "");
                    spNode.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var spf in supportPowerFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(spf);
                        if (fieldNode != null)
                        {
                            fieldNode.MoveAndRenameNode(hackyAINode, spNode, "Decisions");
                        }
                    }

                    addNodes.Add(spNode);
                }

                if (baseBuilderFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var bmNode = new MiniYamlNode("BaseBuilderBotModule@" + aiType, "");
                    bmNode.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var bmf in baseBuilderFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(bmf);
                        if (fieldNode != null)
                        {
                            if (fieldNode.KeyMatches("BuildingFractions", includeRemovals: false))
                            {
                                var buildingNodes = fieldNode.Value.Nodes;
                                foreach (var n in buildingNodes)
                                {
                                    ConvertFractionToInteger(n);
                                }
                            }

                            if (copyBaseBuilderFields.Any(f => f == bmf))
                            {
                                bmNode.AddNode(fieldNode);
                            }
                            else if (fieldNode.KeyMatches("BuildingCommonNames", includeRemovals: false))
                            {
                                foreach (var n in fieldNode.Value.Nodes)
                                {
                                    bmNode.AddNode(n.Key + "Types", n.Value.Value);
                                }
                            }
                            else
                            {
                                fieldNode.MoveNode(hackyAINode, bmNode);
                            }
                        }
                    }

                    addNodes.Add(bmNode);
                }

                // We want the default repair module to be enabled for every AI that didn't disable 'ShouldRepairBuildings',
                // so we need to update RequiresCondition to be enabled on any of the conditions granted by these AIs,
                // but only if the condition hasn't been added yet.
                var shouldRepairNode     = hackyAINode.LastChildMatching("ShouldRepairBuildings");
                var enableBuildingRepair = shouldRepairNode == null || shouldRepairNode.NodeValue <bool>();
                if (enableBuildingRepair)
                {
                    var requiresConditionNode = defaultRepairNode.LastChildMatching("RequiresCondition");
                    if (requiresConditionNode == null)
                    {
                        defaultRepairNode.AddNode(new MiniYamlNode("RequiresCondition", conditionString));
                    }
                    else
                    {
                        var oldValue = requiresConditionNode.NodeValue <string>();
                        if (oldValue.Contains(conditionString))
                        {
                            continue;
                        }

                        requiresConditionNode.ReplaceValue(oldValue + " || " + conditionString);
                    }
                }

                if (captureManagerFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var node = new MiniYamlNode("CaptureManagerBotModule@" + aiType, "");
                    node.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var field in captureManagerFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(field);
                        if (fieldNode != null)
                        {
                            fieldNode.MoveNode(hackyAINode, node);
                        }
                    }

                    addNodes.Add(node);
                }

                if (squadManagerFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var node = new MiniYamlNode("SquadManagerBotModule@" + aiType, "");
                    node.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var field in squadManagerFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(field);
                        if (fieldNode != null)
                        {
                            if (fieldNode.KeyMatches("UnitsCommonNames", includeRemovals: false))
                            {
                                var mcvNode        = fieldNode.LastChildMatching("Mcv");
                                var excludeNode    = fieldNode.LastChildMatching("ExcludeFromSquads");
                                var navalUnitsNode = fieldNode.LastChildMatching("NavalUnits");

                                // In the old code, actors listed under Mcv were also excluded from squads.
                                // However, Mcv[Types] is moved to McvManagerBotModule now, so we need to add them under ExcludeFromSquads as well.
                                if (excludeNode == null && mcvNode != null)
                                {
                                    node.AddNode("ExcludeFromSquadsTypes", mcvNode.Value.Value);
                                }
                                else if (excludeNode != null && mcvNode != null)
                                {
                                    var mcvValue     = mcvNode.NodeValue <string>();
                                    var excludeValue = excludeNode.NodeValue <string>();
                                    node.AddNode("ExcludeFromSquadsTypes", excludeValue + ", " + mcvValue);
                                }

                                if (navalUnitsNode != null)
                                {
                                    node.AddNode("NavalUnitsTypes", navalUnitsNode.Value.Value);
                                }
                            }
                            else if (fieldNode.KeyMatches("BuildingCommonNames", includeRemovals: false))
                            {
                                foreach (var b in fieldNode.Value.Nodes)
                                {
                                    if (squadManagerCommonNames.Any(f => f == b.Key))
                                    {
                                        node.AddNode(b.Key + "Types", b.Value.Value);
                                    }
                                }
                            }
                            else if (fieldNode.KeyMatches("AssignRolesInterval") || fieldNode.KeyMatches("MaxBaseRadius"))
                            {
                                node.AddNode(fieldNode.Key, fieldNode.Value.Value);
                            }
                            else
                            {
                                fieldNode.MoveNode(hackyAINode, node);
                            }
                        }
                    }

                    addNodes.Add(node);
                }

                if (unitBuilderFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var node = new MiniYamlNode("UnitBuilderBotModule@" + aiType, "");
                    node.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var field in unitBuilderFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(field);
                        if (fieldNode != null)
                        {
                            if (fieldNode.KeyMatches("UnitsToBuild", includeRemovals: false))
                            {
                                var unitNodes = fieldNode.Value.Nodes;
                                foreach (var n in unitNodes)
                                {
                                    ConvertFractionToInteger(n);
                                }
                            }

                            fieldNode.MoveNode(hackyAINode, node);
                        }
                    }

                    addNodes.Add(node);
                }

                if (mcvManagerFields.Any(f => hackyAINode.ChildrenMatching(f).Any()))
                {
                    var node = new MiniYamlNode("McvManagerBotModule@" + aiType, "");
                    node.AddNode(new MiniYamlNode("RequiresCondition", conditionString));

                    foreach (var field in mcvManagerFields)
                    {
                        var fieldNode = hackyAINode.LastChildMatching(field);
                        if (fieldNode != null)
                        {
                            if (fieldNode.KeyMatches("UnitsCommonNames", includeRemovals: false))
                            {
                                var mcvNode = fieldNode.LastChildMatching("Mcv");
                                if (mcvNode != null)
                                {
                                    mcvNode.MoveAndRenameNode(hackyAINode, node, "McvTypes");
                                }

                                // Nothing left that needs UnitCommonNames, so we can finally remove it
                                hackyAINode.RemoveNode(fieldNode);
                            }
                            else if (fieldNode.KeyMatches("BuildingCommonNames", includeRemovals: false))
                            {
                                foreach (var n in fieldNode.Value.Nodes)
                                {
                                    if (n.KeyMatches("VehiclesFactory"))
                                    {
                                        node.AddNode("McvFactoryTypes", n.Value.Value);
                                    }
                                    else if (n.KeyMatches("ConstructionYard"))
                                    {
                                        node.AddNode("ConstructionYardTypes", n.Value.Value);
                                    }
                                }

                                // Nothing left that needs BuildingCommonNames, so we can finally remove it
                                hackyAINode.RemoveNode(fieldNode);
                            }
                            else
                            {
                                fieldNode.MoveNode(hackyAINode, node);
                            }
                        }
                    }

                    addNodes.Add(node);
                }

                hackyAINode.RenameKey("ModularBot");
            }

            // Only add module if any bot is using/enabling it.
            var harvRequiresConditionNode = defaultHarvNode.LastChildMatching("RequiresCondition");

            if (harvRequiresConditionNode != null)
            {
                addNodes.Add(defaultHarvNode);
            }

            // Only add module if any bot is using/enabling it.
            var repRequiresConditionNode = defaultRepairNode.LastChildMatching("RequiresCondition");

            if (repRequiresConditionNode != null)
            {
                addNodes.Add(defaultRepairNode);
            }

            foreach (var node in addNodes)
            {
                actorNode.AddNode(node);
            }

            yield break;
        }
Exemple #25
0
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var aircraftNodes  = actorNode.ChildrenMatching("Aircraft");
            var minelayerNodes = actorNode.ChildrenMatching("Minelayer");
            var ammoPoolNodes  = actorNode.ChildrenMatching("AmmoPool");
            var addNodes       = new List <MiniYamlNode>();

            var ammoPoolNames = new List <string>()
            {
                "primary"
            };

            foreach (var ap in ammoPoolNodes)
            {
                var poolName = ap.LastChildMatching("Name");
                if (poolName != null && poolName.NodeValue <string>() != "primary")
                {
                    ammoPoolNames.Add(poolName.NodeValue <string>());
                }
            }

            var rearmableAdded = false;

            foreach (var aircraftNode in aircraftNodes)
            {
                var rearmBuildings = aircraftNode.LastChildMatching("RearmBuildings");
                if (rearmBuildings != null)
                {
                    if (!rearmableAdded)
                    {
                        var rearmableNode = new MiniYamlNode("Rearmable", "");
                        rearmBuildings.MoveAndRenameNode(aircraftNode, rearmableNode, "RearmActors");

                        // If the list has more than one entry, at least one of them won't be "primary"
                        if (ammoPoolNames.Count > 1)
                        {
                            var ammoPools = new MiniYamlNode("AmmoPools", string.Join(", ", ammoPoolNames));
                            rearmableNode.AddNode(ammoPools);
                        }

                        addNodes.Add(rearmableNode);
                        rearmableAdded = true;
                    }
                    else
                    {
                        aircraftNode.RemoveNodes("RearmBuildings");
                    }
                }
            }

            // If it's a minelayer, it won't be an aircraft and rearmableAdded should still be false, so we can use it here
            foreach (var minelayerNode in minelayerNodes)
            {
                var rearmableNode = new MiniYamlNode("Rearmable", "");

                var rearmBuildings = minelayerNode.LastChildMatching("RearmBuildings");
                if (!rearmableAdded)
                {
                    if (rearmBuildings != null)
                    {
                        rearmBuildings.MoveAndRenameNode(minelayerNode, rearmableNode, "RearmActors");
                    }
                    else
                    {
                        rearmableNode.AddNode(new MiniYamlNode("RearmActors", "fix"));
                    }

                    // If the list has more than one entry, at least one of them won't be "primary"
                    if (ammoPoolNames.Count > 1)
                    {
                        var ammoPools = new MiniYamlNode("AmmoPools", string.Join(", ", ammoPoolNames));
                        rearmableNode.AddNode(ammoPools);
                    }

                    addNodes.Add(rearmableNode);
                    rearmableAdded = true;
                }
                else if (rearmableAdded && rearmBuildings != null)
                {
                    minelayerNode.RemoveNodes("RearmBuildings");
                }
            }

            foreach (var node in addNodes)
            {
                actorNode.AddNode(node);
            }

            yield break;
        }
Exemple #26
0
        bool ExtractPanelDefinition(MiniYamlNode chromeProviderNode, MiniYamlNode regionsNode)
        {
            var cNode     = regionsNode.LastChildMatching("background");
            var hasCenter = cNode != null;
            var hasEdges  = edgeKeys.Any(k => regionsNode.LastChildMatching(k) != null);

            // Not a panel
            if (!hasCenter && !hasEdges)
            {
                return(true);
            }

            // Panels may define just the background
            if (hasCenter && !hasEdges)
            {
                var bgRect = cNode.NodeValue <Rectangle>();
                chromeProviderNode.AddNode("PanelRegion", new[]
                {
                    bgRect.X, bgRect.Y,
                    0, 0,
                    bgRect.Width, bgRect.Height,
                    0, 0
                });

                chromeProviderNode.AddNode("PanelSides", PanelSides.Center);
                regionsNode.RemoveNode(cNode);
                return(true);
            }

            // Panels may define just the edges, or edges plus background
            var tlNode = regionsNode.LastChildMatching("corner-tl");

            if (tlNode == null)
            {
                return(false);
            }

            var tlRect = tlNode.NodeValue <Rectangle>();

            var tNode = regionsNode.LastChildMatching("border-t");

            if (tNode == null)
            {
                return(false);
            }

            var tRect = tNode.NodeValue <Rectangle>();

            if (tRect.Left != tlRect.Right || tRect.Top != tlRect.Top || tRect.Bottom != tlRect.Bottom)
            {
                return(false);
            }

            var trNode = regionsNode.LastChildMatching("corner-tr");

            if (trNode == null)
            {
                return(false);
            }

            var trRect = trNode.NodeValue <Rectangle>();

            if (trRect.Left != tRect.Right || trRect.Top != tRect.Top || trRect.Bottom != tRect.Bottom)
            {
                return(false);
            }

            var lNode = regionsNode.LastChildMatching("border-l");

            if (lNode == null)
            {
                return(false);
            }

            var lRect = lNode.NodeValue <Rectangle>();

            if (lRect.Left != tlRect.Left || lRect.Top != tlRect.Bottom || lRect.Right != tlRect.Right)
            {
                return(false);
            }

            var rNode = regionsNode.LastChildMatching("border-r");

            if (rNode == null)
            {
                return(false);
            }

            var rRect = rNode.NodeValue <Rectangle>();

            if (rRect.Left != trRect.Left || rRect.Top != trRect.Bottom || rRect.Bottom != lRect.Bottom || rRect.Right != trRect.Right)
            {
                return(false);
            }

            var blNode = regionsNode.LastChildMatching("corner-bl");

            if (blNode == null)
            {
                return(false);
            }

            var blRect = blNode.NodeValue <Rectangle>();

            if (blRect.Left != lRect.Left || blRect.Top != lRect.Bottom || blRect.Right != lRect.Right)
            {
                return(false);
            }

            var bNode = regionsNode.LastChildMatching("border-b");

            if (bNode == null)
            {
                return(false);
            }

            var bRect = bNode.NodeValue <Rectangle>();

            if (bRect.Left != blRect.Right || bRect.Top != blRect.Top || bRect.Bottom != blRect.Bottom || bRect.Right != tRect.Right)
            {
                return(false);
            }

            var brNode = regionsNode.LastChildMatching("corner-br");

            if (brNode == null)
            {
                return(false);
            }

            var brRect = brNode.NodeValue <Rectangle>();

            if (brRect.Left != bRect.Right || brRect.Top != bRect.Top || brRect.Bottom != bRect.Bottom || brRect.Right != rRect.Right)
            {
                return(false);
            }

            // Background definition may be omitted
            if (hasCenter)
            {
                var bgRect = cNode.NodeValue <Rectangle>();
                if (bgRect.Left != lRect.Right || bgRect.Top != lRect.Top || bgRect.Bottom != lRect.Bottom || bgRect.Right != tRect.Right)
                {
                    return(false);
                }
            }

            // Define the short-form panel region
            chromeProviderNode.AddNode("PanelRegion", new[]
            {
                tlRect.X, tlRect.Y,
                tlRect.Width, tlRect.Height,
                trRect.Left - tlRect.Right, blRect.Top - tlRect.Bottom,
                brRect.Width, brRect.Height
            });

            if (!hasCenter)
            {
                chromeProviderNode.AddNode("PanelSides", PanelSides.Edges);
            }

            // Remove the now redundant regions
            regionsNode.RemoveNode(tlNode);
            regionsNode.RemoveNode(tNode);
            regionsNode.RemoveNode(trNode);
            regionsNode.RemoveNode(lNode);
            regionsNode.RemoveNode(rNode);
            regionsNode.RemoveNode(blNode);
            regionsNode.RemoveNode(bNode);
            regionsNode.RemoveNode(brNode);

            if (cNode != null)
            {
                regionsNode.RemoveNode(cNode);
            }

            return(true);
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var addNodes = new List <MiniYamlNode>();

            foreach (var mobileNode in actorNode.ChildrenMatching("Mobile"))
            {
                var checkFields = locomotorFields.Append(subterraneanFields).Append(jumpjetFields);
                if (checkFields.Any(f => mobileNode.ChildrenMatching(f).Any()))
                {
                    locations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
                }

                var tunnelConditionNode = mobileNode.LastChildMatching("TunnelCondition");
                if (tunnelConditionNode != null)
                {
                    var grantNode = new MiniYamlNode("GrantConditionOnTunnelLayer", "");
                    tunnelConditionNode.MoveAndRenameNode(mobileNode, grantNode, "Condition");
                    addNodes.Add(grantNode);
                }

                var subterraneanNode = mobileNode.LastChildMatching("Subterranean");
                if (subterraneanNode != null)
                {
                    subterraneanUsed = true;

                    mobileNode.RemoveNodes("Subterranean");
                    var conditionNode = mobileNode.LastChildMatching("SubterraneanCondition");
                    if (conditionNode != null)
                    {
                        conditionNode.RenameKey("Condition");
                    }

                    var transitionImageNode    = mobileNode.LastChildMatching("SubterraneanTransitionImage");
                    var transitionSequenceNode = mobileNode.LastChildMatching("SubterraneanTransitionSequence");
                    var transitionPaletteNode  = mobileNode.LastChildMatching("SubterraneanTransitionPalette");
                    var transitionSoundNode    = mobileNode.LastChildMatching("SubterraneanTransitionSound");

                    var nodes = new[]
                    {
                        conditionNode,
                        transitionImageNode,
                        transitionSequenceNode,
                        transitionPaletteNode,
                        transitionSoundNode
                    };

                    if (nodes.Any(n => n != null))
                    {
                        var grantNode = new MiniYamlNode("GrantConditionOnSubterraneanLayer", "");
                        foreach (var node in nodes)
                        {
                            if (node != null)
                            {
                                node.MoveNode(mobileNode, grantNode);
                            }
                        }

                        addNodes.Add(grantNode);
                    }
                }

                var jumpjetNode = mobileNode.LastChildMatching("Jumpjet");
                if (jumpjetNode != null)
                {
                    jumpjetUsed = true;

                    mobileNode.RemoveNodes("Jumpjet");
                    var conditionNode = mobileNode.LastChildMatching("JumpjetCondition");
                    if (conditionNode != null)
                    {
                        var grantNode = new MiniYamlNode("GrantConditionOnJumpjetLayer", "");
                        conditionNode.MoveAndRenameNode(mobileNode, grantNode, "Condition");
                        addNodes.Add(grantNode);
                    }
                }
            }

            foreach (var node in addNodes)
            {
                actorNode.AddNode(node);
            }

            yield break;
        }
        public override IEnumerable <string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
        {
            var cpd = actorNode.LastChildMatching("CanPowerDown");

            if (cpd == null)
            {
                yield break;
            }

            cpd.RenameKey("ToggleConditionOnOrder");
            var upSound = cpd.LastChildMatching("PowerupSound");

            if (upSound != null)
            {
                upSound.RenameKey("DisabledSound");
            }

            var upSpeech = cpd.LastChildMatching("PowerupSpeech");

            if (upSpeech != null)
            {
                upSpeech.RenameKey("DisabledSpeech");
            }

            var downSound = cpd.LastChildMatching("PowerdownSound");

            if (downSound != null)
            {
                downSound.RenameKey("EnabledSound");
            }

            var downSpeech = cpd.LastChildMatching("PowerdownSpeech");

            if (downSpeech != null)
            {
                downSpeech.RenameKey("EnabledSpeech");
            }

            cpd.AddNode("OrderName", "PowerDown");

            var condition = cpd.LastChildMatching("PowerdownCondition");

            if (condition != null)
            {
                condition.RenameKey("Condition");
            }
            else
            {
                cpd.AddNode("Condition", "powerdown");
            }

            if (cpd.ChildrenMatching("CancelWhenDisabled").Any())
            {
                cpd.RemoveNodes("CancelWhenDisabled");
                yield return("CancelWhenDisabled was removed when CanPowerDown was replaced by ToggleConditionOnOrder.\n" +
                             "Use PauseOnCondition instead of RequiresCondition to replicate the behavior of 'false'.");
            }

            actorNode.AddNode(new MiniYamlNode("PowerMultiplier@POWERDOWN", new MiniYaml("", new List <MiniYamlNode>()
            {
                new MiniYamlNode("RequiresCondition", condition.Value.Value),
                new MiniYamlNode("Modifier", "0")
            })));
            yield break;
        }