Download CommonLua/Editor/XEditor/XEditorMapVariations.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 12.3 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Editor/XEditor/XEditorMapVariations.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/Editor/XEditor/XEditorMapVariations.lua
-
curl -L -o XEditorMapVariations.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Editor/XEditor/XEditorMapVariations.lua
12.3 kB
| if not Platform.developer then | |
| EditedMapVariation = false | |
| return | |
| end | |
| ----- Notes about the map variation editing internal state | |
| -- | |
| -- 1. The *loaded* map variation is stored in CurrentMapVariation; see MapVariationPreset | |
| -- 2. The *edited* map variation is in EditedMapVariation (either false or equal to CurrentMapVariation) | |
| -- 3. The user can hide the *edited map variation*; in this state: | |
| -- a) the user is editing the *base map*, using a different undo queue | |
| -- b) EditedMapVariation becomes false; and HiddenMapVariationUndoIndex stores the last index in the | |
| -- "map variation undo queue"; we rewind to this index when we go back to the *edited map variation* | |
| -- c) the "save map" action saves the *base map* | |
| local function reset_edited_variation() | |
| EditedMapVariation = false | |
| EditedMapVariationUndoQueue = false | |
| OriginalEditorUndoQueue = false | |
| HiddenMapVariationUndoIndex = false | |
| end | |
| if FirstLoad then | |
| reset_edited_variation() | |
| end | |
| OnMsg.ChangeMap = reset_edited_variation | |
| local function start_editing_loaded_variation() | |
| assert(CurrentMapVariation and not EditedMapVariation) | |
| EditedMapVariationUndoQueue = XEditorUndo | |
| OriginalEditorUndoQueue = XEditorUndoQueue:new() | |
| HiddenMapVariationUndoIndex = false | |
| EditedMapVariation = CurrentMapVariation | |
| XEditorUpdateStatusText() | |
| end | |
| function OnMsg.GameEnterEditor() | |
| -- initiate editing of the current map variation | |
| if CurrentMapVariation and not EditedMapVariation and not HiddenMapVariationUndoIndex then | |
| start_editing_loaded_variation() | |
| end | |
| end | |
| local function drop_edited_variation_changes() | |
| assert(CurrentMapVariation and EditedMapVariation and not HiddenMapVariationUndoIndex) | |
| -- reverse everything from the currently edited variation | |
| HiddenMapVariationUndoIndex = XEditorUndo.undo_index | |
| while XEditorUndo.undo_index ~= 0 do | |
| XEditorUndo:UndoRedo("undo") | |
| end | |
| EditedMapVariation = false | |
| EditorMapDirty = false | |
| XEditorUpdateStatusText() | |
| -- switch back to the "base map editing" undo queue | |
| XEditorUndo = OriginalEditorUndoQueue | |
| XEditorUpdateToolbars() | |
| end | |
| local function restore_edited_variation_changes() | |
| assert(CurrentMapVariation and not EditedMapVariation and HiddenMapVariationUndoIndex) | |
| -- switch to the "map variation editing" undo queue | |
| XEditorUndo = EditedMapVariationUndoQueue | |
| XEditorUpdateToolbars() | |
| -- restore map variation changes | |
| while XEditorUndo.undo_index ~= HiddenMapVariationUndoIndex do | |
| XEditorUndo:UndoRedo("redo") | |
| end | |
| HiddenMapVariationUndoIndex = false | |
| EditedMapVariation = CurrentMapVariation | |
| EditorMapDirty = false | |
| XEditorUpdateStatusText() | |
| end | |
| local function ask_save_and_drop_variation() | |
| assert(CurrentMapVariation) | |
| local save_map = | |
| WaitQuestion(nil, Untranslated("Save changes?"), | |
| Untranslated(string.format("This will remove any changes made by the current map variation '%s'.\nSave it?", MapVariationNameText(CurrentMapVariation))), | |
| Untranslated("Yes"), Untranslated("No")) == "ok" | |
| if HiddenMapVariationUndoIndex then | |
| restore_edited_variation_changes() | |
| end | |
| if save_map then | |
| SaveMap() | |
| end | |
| drop_edited_variation_changes() | |
| end | |
| local function ensure_map_saved(drop_variation) | |
| if drop_variation and CurrentMapVariation then | |
| ask_save_and_drop_variation() | |
| elseif EditorMapDirty then | |
| if WaitQuestion(nil, Untranslated("Map Not Saved"), Untranslated("The map must be saved before creating/editing a variation.")) ~= "ok" then | |
| return false | |
| end | |
| SaveMap() | |
| end | |
| return true | |
| end | |
| function IsMapVariationEdited(preset) | |
| return EditedMapVariation == preset or CurrentMapVariation == preset and HiddenMapVariationUndoIndex | |
| end | |
| function StopEditingCurrentMapVariation(keep_changes) | |
| if not keep_changes and not HiddenMapVariationUndoIndex then | |
| drop_edited_variation_changes() | |
| end | |
| CurrentMapVariation = false | |
| EditedMapVariation = false | |
| EditedMapVariationUndoQueue = false | |
| HiddenMapVariationUndoIndex = false | |
| XEditorUndo = OriginalEditorUndoQueue | |
| OriginalEditorUndoQueue = false | |
| XEditorUpdateStatusText() | |
| end | |
| ----- UI actions | |
| function XEditorCreateNewVariation() | |
| if not ensure_map_saved("drop_variation") then | |
| return | |
| end | |
| local name = WaitInputText(nil, "Map Variation", "Enter variation name...") | |
| if not name then return end | |
| local save_in = WaitListChoice(nil, DlcComboItems(), "Save In") | |
| if not save_in then return end | |
| save_in = save_in.value | |
| if FindMapVariation(name, save_in) then | |
| local message = string.format("The map variation '%s' already exists%s.\n\nOverwrite?", | |
| name, save_in =="" and "" or string.format(" in DLC '%s'", save_in), save_in) | |
| if WaitQuestion(nil, Untranslated("Error"), Untranslated(message)) ~= "ok" then | |
| return | |
| end | |
| end | |
| XEditorUndo = XEditorUndoQueue:new() -- start on an empty undo queue | |
| CreateMapVariation(name, save_in) | |
| start_editing_loaded_variation() | |
| end | |
| function XEditorEditVariation(variation) | |
| assert(variation and CurrentMapVariation ~= variation) | |
| if CurrentMapVariation == variation then return end | |
| if not ensure_map_saved("drop_variation") then | |
| return | |
| end | |
| -- replace the undo queue with one for editing the map variation | |
| OriginalEditorUndoQueue = XEditorUndo | |
| EditedMapVariationUndoQueue = XEditorUndoQueue:new() | |
| HiddenMapVariationUndoIndex = false | |
| XEditorUndo = EditedMapVariationUndoQueue | |
| XEditorUpdateToolbars() -- update undo queue combo | |
| -- apply the patch in this new undo queue for editing | |
| XEditorApplyMapPatch(variation:GetMapPatchPath()) | |
| CurrentMapVariation = variation | |
| EditedMapVariation = variation | |
| XEditorUpdateStatusText() -- update edited map variation, variations button | |
| end | |
| function XEditorHideShowVariation(variation) | |
| assert(variation == CurrentMapVariation) | |
| if HiddenMapVariationUndoIndex then | |
| if not ensure_map_saved() then | |
| return | |
| end | |
| restore_edited_variation_changes() | |
| else | |
| drop_edited_variation_changes() | |
| end | |
| end | |
| function XEditorDeleteVariation(variation) | |
| if WaitQuestion(nil, Untranslated("Confirmation"), | |
| Untranslated(string.format("Delete map variation %s?", MapVariationNameText(variation)))) == "ok" | |
| then | |
| if variation == CurrentMapVariation then | |
| StopEditingCurrentMapVariation() | |
| end | |
| variation:OnEditorDelete() | |
| variation:delete() | |
| end | |
| end | |
| function XEditorMergeVariation(variation) | |
| assert(variation == CurrentMapVariation) | |
| if WaitQuestion(nil, Untranslated("Confirmation"), | |
| Untranslated(string.format("Merge map variation %s into the original map and delete the variation?", MapVariationNameText(variation)))) == "ok" | |
| then | |
| if HiddenMapVariationUndoIndex then | |
| restore_edited_variation_changes() | |
| end | |
| StopEditingCurrentMapVariation("keep_changes") | |
| variation:OnEditorDelete() | |
| variation:delete() | |
| XEditorSaveMap() | |
| end | |
| end | |
| ----- Map variations popup UI | |
| DefineClass("XDarkModeAwarePopupList", "XPopupList", "XDarkModeAwareDialog") | |
| function XDarkModeAwarePopupList:Open(...) | |
| XPopupList.Open(self, ...) | |
| self:SetDarkMode(GetDarkModeSetting()) | |
| end | |
| function XDarkModeAwarePopupList:OnShortcut(shortcut, source, ...) | |
| if shortcut == "Escape" or shortcut == "ButtonB" then | |
| self:Close() | |
| return "break" | |
| end | |
| end | |
| function XEditorOpenMapVariationsPopup() | |
| local popup = XDarkModeAwarePopupList:new({ | |
| Id = "idMapVariationsPopup", | |
| Margins = box(0, 2, 0, 2), | |
| Padding = box(3, 0, 3, 5), | |
| MinWidth = 360, | |
| LayoutMethod = "VList", | |
| DrawOnTop = true, | |
| HandleMouse = true, | |
| OnMouseButtonUp = function(self, pt, button) | |
| if button == "L" then | |
| if not self:MouseInWindow(pt) then | |
| self:Close() | |
| end | |
| return "break" | |
| elseif button == "R" then | |
| self:Close() | |
| return "break" | |
| end | |
| end, | |
| }, terminal.desktop) | |
| -- header | |
| local title = XText:new({ TextStyle = "GedTitle", TextHAlign = "center", }, popup) | |
| title:SetText("Map Variations") | |
| XWindow:new({ Background = RGB(0, 0, 0), Margins = box(10, 1, 10, 1), MinHeight = 1 }, popup) -- separator | |
| -- footer | |
| local button_holder = XWindow:new({ Dock = "bottom", HAlign = "center", LayoutMethod = "HList" }, popup) | |
| XTextButton:new({ | |
| BorderWidth = 1, | |
| Margins = box(2, 2, 2, 2), | |
| VAlign = "center", | |
| Text = "Create new variation", | |
| FocusedBorderColor = RGB(128, 128, 128), | |
| DisabledBorderColor = RGB(128, 128, 128), | |
| RolloverBorderColor = RGB(128, 128, 128), | |
| PressedBorderColor = RGB(128, 128, 128), | |
| OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorCreateNewVariation) end, | |
| }, button_holder) | |
| if Presets.MapVariationPreset then | |
| XTextButton:new({ | |
| BorderWidth = 1, | |
| Margins = box(2, 2, 2, 2), | |
| VAlign = "center", | |
| Text = "Manage", | |
| FocusedBorderColor = RGB(128, 128, 128), | |
| DisabledBorderColor = RGB(128, 128, 128), | |
| RolloverBorderColor = RGB(128, 128, 128), | |
| PressedBorderColor = RGB(128, 128, 128), | |
| OnPress = function(button) | |
| if CurrentMapVariation then | |
| CurrentMapVariation:OpenEditor() | |
| else | |
| OpenPresetEditor("MapVariationPreset") | |
| end | |
| end, | |
| }, button_holder) | |
| end | |
| local help_text = XText:new({ Dock = "bottom", TextHAlign = "center" }, popup) | |
| help_text:SetText("<color 128 128 128>Map variations are saved as patches over the base map.\nThis allows editing the base map and the variation changes separately.") | |
| for idx, item in ipairs(MapVariationItems(CurrentMap)) do | |
| local entry = XContextWindow:new({ | |
| IdNode = true, | |
| Margins = box(3, 2, 3, 2), | |
| OnSetRollover = function(self, rollover) | |
| self:SetBackground(rollover and RGBA(128, 128, 128, 40) or 0) | |
| self.idHintText:SetVisible(rollover and CurrentMapVariation ~= self.context.value) | |
| end | |
| }, popup, item) | |
| -- delete button | |
| XTextButton:new({ | |
| Dock = "left", | |
| VAlign = "center", | |
| Text = "x", | |
| MaxWidth = 20, | |
| MaxHeight = 16, | |
| LayoutHSpacing = 0, | |
| Padding = box(1, 1, 0, 1), | |
| Background = RGBA(0, 0, 0, 0), | |
| RolloverBackground = RGB(204, 232, 255), | |
| PressedBackground = RGB(121, 189, 241), | |
| OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorDeleteVariation, item.value) end, | |
| }, entry) | |
| -- show/hide button | |
| local showhide_button = XTextButton:new({ | |
| Id = "idShowHideButton", | |
| Dock = "right", | |
| FoldWhenHidden = true, | |
| Margins = box(0, 0, 3, 0), | |
| BorderWidth = 1, | |
| VAlign = "center", | |
| Text = HiddenMapVariationUndoIndex and "Show" or "Hide", | |
| FocusedBorderColor = RGB(128, 128, 128), | |
| DisabledBorderColor = RGB(128, 128, 128), | |
| RolloverBorderColor = RGB(128, 128, 128), | |
| PressedBorderColor = RGB(128, 128, 128), | |
| OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorHideShowVariation, item.value) end, | |
| }, entry) | |
| showhide_button:SetVisible(CurrentMapVariation == item.value) | |
| -- merge button | |
| local merge_button = XTextButton:new({ | |
| Id = "idMergeButton", | |
| Dock = "right", | |
| FoldWhenHidden = true, | |
| Margins = box(5, 0, 5, 0), | |
| BorderWidth = 1, | |
| VAlign = "center", | |
| Text = "Merge", | |
| FocusedBorderColor = RGB(128, 128, 128), | |
| DisabledBorderColor = RGB(128, 128, 128), | |
| RolloverBorderColor = RGB(128, 128, 128), | |
| PressedBorderColor = RGB(128, 128, 128), | |
| OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorMergeVariation, item.value) end, | |
| }, entry) | |
| merge_button:SetVisible(CurrentMapVariation == item.value) | |
| -- edit hint | |
| local hint_text = XText:new({ Id = "idHintText", Dock = "right", HandleMouse = false, }, entry) | |
| hint_text:SetText("(click to edit)") | |
| hint_text:SetVisible(false) | |
| -- variation name | |
| local name = XText:new({ Dock = "box", Padding = box(0, 2, 2, 2), }, entry) | |
| name:SetText(item.text) | |
| name:SetTextStyle(CurrentMapVariation == item.value and "GedHighlight" or "GedDefault") | |
| name.OnMouseButtonDown = function(win, pt, button) | |
| XEditorCloseVariationsPopup() | |
| if CurrentMapVariation ~= item.value then | |
| CreateRealTimeThread(XEditorEditVariation, item.value) | |
| end | |
| return "break" | |
| end | |
| end | |
| popup.idContainer:SetBackground(RGB(255, 255, 255)) | |
| popup:SetAnchor(XEditorGetMapButton("idMapVariationsButton").parent.box) | |
| popup:SetAnchorType("top") | |
| popup:Open() | |
| popup:SetModal() | |
| popup:SetFocus() | |
| popup.popup_parent = GetDialog("XEditor") | |
| Msg("XWindowRecreated", popup) | |
| end | |
| function XEditorCloseVariationsPopup() | |
| local popup = rawget(terminal.desktop, "idMapVariationsPopup") | |
| if popup then | |
| popup:Close() | |
| end | |
| end | |
| OnMsg.GameExitEditor = XEditorCloseVariationsPopup | |