diff --git a/src/TSMapEditor/Models/Map.cs b/src/TSMapEditor/Models/Map.cs index 1a14f5e0..449809ca 100644 --- a/src/TSMapEditor/Models/Map.cs +++ b/src/TSMapEditor/Models/Map.cs @@ -1445,21 +1445,21 @@ public string GetNewUniqueInternalId() public void RegenerateInternalIds() { string idBeginning = "0100"; - List scriptElements = new List(); + var scriptElements = new List(); - Func f = (scriptElement) => scriptElement.GetInternalID().StartsWith(idBeginning); + bool filter(IIDContainer scriptElement) => scriptElement.GetInternalID().StartsWith(idBeginning); - var tfs = TaskForces.FindAll(tf => f(tf)); - var scripts = Scripts.FindAll(s => f(s)); - var teamtypes = TeamTypes.FindAll(tt => f(tt)); - var tags = Tags.FindAll(t => f(t)); - var triggers = Triggers.FindAll(t => f(t)); + var tfs = TaskForces.FindAll(filter); + var scripts = Scripts.FindAll(filter); + var teamtypes = TeamTypes.FindAll(filter); + var tags = Tags.FindAll(filter); + var triggers = Triggers.FindAll(filter); - scriptElements.AddRange(TaskForces.FindAll(tf => f(tf))); - scriptElements.AddRange(Scripts.FindAll(s => f(s))); - scriptElements.AddRange(TeamTypes.FindAll(tt => f(tt))); - scriptElements.AddRange(Triggers.FindAll(t => f(t))); - scriptElements.AddRange(Tags.FindAll(t => f(t))); + scriptElements.AddRange(tfs); + scriptElements.AddRange(scripts); + scriptElements.AddRange(teamtypes); + scriptElements.AddRange(tags); + scriptElements.AddRange(triggers); scriptElements = scriptElements.OrderBy(se => se.GetInternalID()).ToList(); tfs.ForEach(tf => LoadedINI.RemoveSection(tf.ININame)); @@ -1468,13 +1468,41 @@ public void RegenerateInternalIds() // Our map writing system takes care of the tags and triggers, no need to manually remove their INI entries // (they don't have sections) - // TODO implement old-ID-to-new-ID lookup table, necessary for fixing up trigger references + // Build dictionary of old ID to scripting element for "ID swizzling" to correct triggers' references to other scripting elements + var dict = new Dictionary(); + scriptElements.ForEach(s => dict.Add(s.GetInternalID(), s)); // Zero out the internal IDs scriptElements.ForEach(se => se.SetInternalID(string.Empty)); // Generate new internal IDs scriptElements.ForEach(se => se.SetInternalID(GetNewUniqueInternalId())); + + // Fix up triggers that refer to the old IDs + foreach (var trigger in triggers) + { + foreach (var action in trigger.Actions) + { + for (int i = 0; i < action.Parameters.Length; i++) + { + if (!string.IsNullOrWhiteSpace(action.Parameters[i]) && dict.TryGetValue(action.Parameters[i], out IIDContainer element)) + { + action.Parameters[i] = element.GetInternalID(); + } + } + } + + foreach (var condition in trigger.Conditions) + { + for (int i = 0; i < condition.Parameters.Length; i++) + { + if (!string.IsNullOrWhiteSpace(condition.Parameters[i]) && dict.TryGetValue(condition.Parameters[i], out IIDContainer element)) + { + condition.Parameters[i] = element.GetInternalID(); + } + } + } + } } public void InitializeRules(GameConfigINIFiles gameConfigINIFiles) diff --git a/src/TSMapEditor/UI/Windows/TriggersWindow.cs b/src/TSMapEditor/UI/Windows/TriggersWindow.cs index 2c69810c..53c7c0c7 100644 --- a/src/TSMapEditor/UI/Windows/TriggersWindow.cs +++ b/src/TSMapEditor/UI/Windows/TriggersWindow.cs @@ -591,12 +591,12 @@ private void RegenerateIDs() "This will re-generate the internal IDs (01000000, 01000001 etc.) for ALL* of your map's script elements" + Environment.NewLine + "that start their ID with 0100 (all editor-generated script elements do)." + Environment.NewLine + Environment.NewLine + "It might make the list more sensible in case there are deleted triggers. However, this feature is" + Environment.NewLine + - "experimental and if it goes wrong, it can destroy all of your scripting. Do you want to continue?" + Environment.NewLine + Environment.NewLine + - "* AITriggers are not yet handled by the editor, so you might need to update them manually afterwards.", + "experimental and if it goes wrong, it can destroy all of your scripting. Do you want to continue?", MessageBoxButtons.YesNo); messageBox.YesClickedAction = _ => map.RegenerateInternalIds(); ListTriggers(); + LbTriggers_SelectedIndexChanged(this, EventArgs.Empty); } private void CloneForEasierDifficulties()