From 12d38114097a8215f2b0ddea7bbba1300fa1bd82 Mon Sep 17 00:00:00 2001 From: jere0500 Date: Mon, 15 Jul 2024 12:34:28 +0200 Subject: [PATCH 1/4] BattleRoom changes for export --- LuaMenu/widgets/gui_battle_room_window.lua | 89 +++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/LuaMenu/widgets/gui_battle_room_window.lua b/LuaMenu/widgets/gui_battle_room_window.lua index 948354910..c3b55567d 100644 --- a/LuaMenu/widgets/gui_battle_room_window.lua +++ b/LuaMenu/widgets/gui_battle_room_window.lua @@ -27,6 +27,7 @@ local mainWindowFunctions local showDefaultStartCheckbox = false local currentStartRects = {} +local startRectValues = {} -- for exporting the raw values local singleplayerWrapper local multiplayerWrapper @@ -55,6 +56,7 @@ local vote_votingsPattern = "(%d+)/(%d+).-:(%d+)" local vote_whoCalledPattern = "%* (.*) called a vote for command" local vote_mapPattern = 'set map (.*)"' +local playerHandler -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Download management @@ -1117,12 +1119,35 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs parent = leftInfo, } leftOffset = leftOffset + 40 + local btnOptionPresets = Button:New { + name = 'btnOptionpresets', + x = 5, + y = leftOffset, + height = 35, + right = 5, + classname = "option_button", + caption = "Option Presets" .. "\b", + objectOverrideFont = config:GetFont(2), + objectOverrideDisabledFont = config:GetFont(1), + hasDisabledFont = true, + tooltip = tooltip, + OnClick = { + function() + WG.OptionpresetsPanel.ShowPresetPanel() + end + }, + parent = leftInfo, + } + leftOffset = leftOffset + 40 -- gray out the button if we don't have a modoptions panel to show if not modoptions then -- cosmetics when disabled btnModoptions.suppressButtonReaction = true btnModoptions:SetEnabled(false) + -- preset loading is useless if modification of modoptions not allow + btnOptionPresets.suppressButtonReaction = true + btnOptionPresets:SetEnabled(false) end -- the modoptions panel needing a refresh is independant on if we have a modoptions panel from a diffrent version to fall back onto @@ -1138,6 +1163,11 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs btnModoptions:SetEnabled(true) modoptionsLoaded = true + --enable also btnOptionPresets + btnOptionPresets.suppressButtonReaction = false + btnOptionPresets.tooltip = "Create and Load Presets for gameplay options" + btnOptionPresets:SetEnabled(true) + local modoptionspanelExternalFunctions = WG.ModoptionsPanel.GetModoptionsControl() modoptionspanelExternalFunctions:Update() @@ -1267,6 +1297,8 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs offset = offset + 38 btnModoptions:SetPos(nil, offset) offset = offset + 40 + btnOptionPresets:SetPos(nil, offset) + offset = offset + 40 lblGame:SetPos(nil, offset) offset = offset + 26 imHaveGame:SetPos(nil, offset) @@ -1472,6 +1504,9 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs -- it doesnt even know how big it is right nowhere -- Spring.Utilities.TraceFullEcho() + -- adding the raw values + startRectValues[allyNo+1]={["left"]=left, ["top"]=top, ["right"]=right, ["bottom"]=bottom} + local minimapPanelMaxSize = math.max(minimapPanel.width,minimapPanel.height) -1 local ox = math.floor(left * minimapPanelMaxSize / 200) local oy = math.floor(top * minimapPanelMaxSize / 200) @@ -1528,6 +1563,9 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs --try to manage clicking on the startbox not changing it. --TODO: problematic when resizing entire UI :/ + -- updating the raw values + startRectValues[tonumber(obj.caption)]={["left"]=l, ["top"]=t, ["right"]=r, ["bottom"]=b} + obj:Invalidate() --doesnt do much if battleLobby.name == "singleplayer" then WG.Chobby.Configuration.gameConfig.mapStartBoxes.addBox(l,t,r,b,obj.caption) @@ -1573,6 +1611,7 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs if currentStartRects[allyNo+1] then currentStartRects[allyNo+1]:Dispose() currentStartRects[allyNo+1] = nil + startRectValues[allyNo+1] = nil end for i,rect in pairs(currentStartRects) do rect:BringToFront() @@ -1841,6 +1880,7 @@ local function SetupPlayerPanel(playerParent, spectatorParent, battle, battleID) if button == 3 and WG.Chobby.Configuration.lastAddedAiName then quickAddAi = WG.Chobby.Configuration.lastAddedAiName end + WG.PopupPreloader.ShowAiListWindow(battleLobby, battle.gameName, teamIndex, quickAddAi) end, disallowCustomTeams and teamIndex ~= 0, @@ -2119,6 +2159,13 @@ local function SetupPlayerPanel(playerParent, spectatorParent, battle, battleID) RemovePlayerFromTeam(botName) end + function externalFunctions.GetTeam(index) + if(index >= emptyTeamIndex)then + OpenNewTeam() + end + return GetTeam(index) + end + return externalFunctions end @@ -2955,7 +3002,7 @@ local function InitializeControls(battleID, oldLobby, topPoportion, setupData) parent = bottomPanel, } - local playerHandler = SetupPlayerPanel(playerPanel, spectatorPanel, battle, battleID) + playerHandler = SetupPlayerPanel(playerPanel, spectatorPanel, battle, battleID) spadsStatusPanel = Control:New{ @@ -3872,6 +3919,8 @@ function BattleRoomWindow.ShowMultiplayerBattleRoom(battleID) allyNumber = 0, sync = (haveMapAndGame and 1) or 2, -- 0 = unknown, 1 = synced, 2 = unsynced }) + + WG.OptionpresetsPanel.cloneMPModoptions(true) end function BattleRoomWindow.GetSingleplayerControl(setupData) @@ -4083,6 +4132,44 @@ function BattleRoomWindow.ClearChatHistory() end end + +function BattleRoomWindow.GetCurrentStartRects() + return startRectValues +end + +function BattleRoomWindow.AddStartRect(allyNo, left, top, right, bottom) + if battleLobby.name == "singleplayer" then + local infoHandler = mainWindowFunctions.GetInfoHandler() + infoHandler.AddStartRect(allyNo, left, top, right, bottom) + else + battleLobby:SayBattle(string.format("!addbox %d %d %d %d %s", left, top, right, bottom, allyNo+1)) + end +end + +function BattleRoomWindow.RemoveStartRect(allyNo) + if battleLobby.name == "singleplayer" then + local infoHandler = mainWindowFunctions.GetInfoHandler() + infoHandler.RemoveStartRect(allyNo) + end +end + + +function BattleRoomWindow.SetTeams(numberOfTeams) + if not battleLobby.name == "singleplayer" then + -- command to set the teams + battleLobby:SayBattle(string.format("!nbteams %d", numberOfTeams)) + end +end + +function BattleRoomWindow.SetStart(allyNo) + local infoHandler = mainWindowFunctions.GetInfoHandler() + infoHandler.RemoveStartRect(allyNo) +end + +function BattleRoomWindow.GetPlayerHandler() + return playerHandler +end + local function DelayedInitialize() local function onConfigurationChange(listener, key, value) if mainWindowFunctions and key == "canAuthenticateWithSteam" then From 683ce2287fb93707a62d51edc5aae74bf4f7b8dd Mon Sep 17 00:00:00 2001 From: jere0500 Date: Fri, 12 Jul 2024 13:20:09 +0200 Subject: [PATCH 2/4] Implementation of the Option Preset Panel --- LuaMenu/widgets/gui_optionpresets_panel.lua | 779 ++++++++++++++++++++ 1 file changed, 779 insertions(+) create mode 100644 LuaMenu/widgets/gui_optionpresets_panel.lua diff --git a/LuaMenu/widgets/gui_optionpresets_panel.lua b/LuaMenu/widgets/gui_optionpresets_panel.lua new file mode 100644 index 000000000..9d407a339 --- /dev/null +++ b/LuaMenu/widgets/gui_optionpresets_panel.lua @@ -0,0 +1,779 @@ +function widget:GetInfo() + return { + name = 'Optionpreset Panel', + desc = 'Implements the Optionpreset panel.', + author = 'jere0500', + date = '22 June 2024', + license = 'GNU GPL v2', + layer = 0, + enabled = true, + } +end + +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +-- const: +local placeHolder = "" + +-- Variables +local battleLobby +local battle +local OptionpresetsPanel = {} +local window +local multiplayer = false + +-- enabled options +local enabledOptions = {} +local optionCaptions = { + ["Modoptions"] = "settings part of the adv. options menu", + ["Map"] = "current selected map", + ["Bots"] = "all bots (settings, team)", + ["Starting Areas"] = "all start areas with position", + ["Multiplayer Battle Settings"] = "multiplayer specific settings (battle preset, #teams, ...)" +} + +-- edited by the preset +local currentModoptions +local currentMap +local currentAITable +local currentStartRects +local currentMPBattleSettings + +-- used to generate a point to resume +local multiplayerModoptions + +-- now we need to store the object in this class +local jsondata; + +-- preset that is selected in the dropdown menu +local selectedPresetName = placeHolder; + +-- preset that is currently applied +local appliedPresetName = placeHolder; + +-- defining function to later overwrite +local refreshPresetMenu = function() +end + +-- errorStr +local errorStr = "" + +-- write to the error Panel +local writeError = function(errorM) + errorStr = errorM +end + + +-------------------------------------------------------------------------------- +--- Helper functions +-------------------------------------------------------------------------------- +local function refreshJSONData() + local modfile = io.open("optionsPresets.json", 'r') + if modfile ~= nil then + local boolOut + boolOut, jsondata = pcall(json.decode, modfile:read()) + + -- handles broken json file + if not boolOut or jsondata == nil or type(jsondata) ~= "table" then + --error during file reading, should output read text TODO + local localtime = os.date('%Y-%m-%d-%H:%M:%S') + local oldfile = "optionsPresets.json" + local errorfile = "optionsPresetsError:" .. localtime .. ".json" + writeError("Error reading preset file\n " .. oldfile .. " was moved to \n" .. errorfile) + + modfile:close() + local renamesuccess = os.rename(oldfile, errorfile) + if not renamesuccess then + Spring.Echo("fail during rename") + return + end + -- generate a new file + refreshJSONData() + return + end + end + if modfile == nil then + -- creates file when it does not exist + jsondata = {} + -- jsondata["defaultPreset"] = {} + modfile = io.open("optionsPresets.json", 'w') + local jsonobj = json.encode(jsondata) + modfile:write(jsonobj) + end + + modfile:close() +end + +-- writes preset changes to file +local function saveJSONData() + local modfile = io.open("optionsPresets.json", 'w') + if modfile == nil then + -- maybe some logging + return + end + local jsonobj = json.encode(jsondata) + modfile:write(jsonobj) + modfile:close() +end + +-- apply specific preset to the current Lobby +local function applyPreset(presetName) + appliedPresetName = presetName + + local presetObj = jsondata[presetName] + if presetObj ~= nil then + -- only apply in multiplayer + local presetMPBattleSettings = presetObj["Multiplayer Battle Settings"] + if presetMPBattleSettings ~= nil and multiplayer and enabledOptions["Multiplayer Battle Settings"] then + battleLobby:SayBattle("!preset " .. presetMPBattleSettings["preset"]) + if presetMPBattleSettings["locked"] then + battleLobby:SayBattle("!lock") + else + battleLobby:SayBattle("!unlock") + end + battleLobby:SayBattle("!autobalance " .. presetMPBattleSettings["autoBalance"]) + battleLobby:SayBattle("!balanceMode " .. presetMPBattleSettings["balanceMode"]) + battleLobby:SayBattle("!set teamSize " .. presetMPBattleSettings["teamSize"]) + battleLobby:SayBattle("!nbTeams " .. presetMPBattleSettings["nbTeams"]) + end + + -- modoptions + currentModoptions = presetObj["Modoptions"] + if (currentModoptions ~= nil and enabledOptions["Modoptions"]) then + -- if multiplayer have to disable other modoptions first: + if (multiplayer) then + -- now apply the modoptions as the baseline + local combinedModoptions = multiplayerModoptions + for key, value in pairs(currentModoptions) do + multiplayerModoptions[key] = value + end + currentModoptions = combinedModoptions + end + + battleLobby:SetModOptions(currentModoptions) + end + + -- map + local presetMapName = presetObj["Map"] + if (presetMapName ~= nil and enabledOptions["Map"]) then + battleLobby:SelectMap(presetMapName) + end + + -- starting Areas + local presetRectangles = presetObj["Starting Areas"] + -- calculated the required team size, when it is undefined for the preset + if multiplayer and presetMPBattleSettings == nil then + battleLobby:SayBattle("!nbTeams " .. #presetRectangles) + end + + if (presetRectangles ~= nil and enabledOptions["Starting Areas"]) then + WG.BattleRoomWindow.RemoveStartRect() + for index, value in ipairs(presetRectangles) do + local l = value["left"] + local r = value["right"] + local t = value["top"] + local b = value["bottom"] + + WG.BattleRoomWindow.AddStartRect(index - 1, l, t, r, b) + end + end + + -- AIs with their settings + local presetAi = presetObj["Bots"] + if presetAi ~= nil and enabledOptions["Bots"] then + local newAiNames = {} + + for key, _ in pairs(currentAITable) do + battleLobby:RemoveAi(key) + end + currentAITable = {} + for key, value in pairs(presetAi) do + currentAITable[key] = value + local battlestatusoptions = {} + battlestatusoptions.teamColor = value.teamColor + battlestatusoptions.side = value.side + battleLobby:AddAi(key, value.aiLib, value.allyNumber, value.aiVersion, value.aiOptions, + battlestatusoptions) + end + end + end +end + +-- deletes a preset by name +local function deletePreset(presetName) + if presetName ~= placeHolder or presetName ~= "" then + jsondata[presetName] = nil + saveJSONData() + refreshPresetMenu() + end +end + +-- applies changes to specified preset +-- (creates new preset if none with that name exists) +local function writePreset(presetName) + local preset = presetName + if (presetName == nil) then + preset = "defaultPreset" + end + + if jsondata[preset] == nil then + jsondata[preset] = {} + end + + if currentModoptions ~= nil and enabledOptions["Modoptions"] then + if jsondata[preset]["Modoptions"] == nil then + jsondata[preset]["Modoptions"] = {} + end + jsondata[preset]["Modoptions"] = currentModoptions + end + + if currentMap ~= nil and enabledOptions["Map"] then + if jsondata[preset]["Map"] == nil then + jsondata[preset]["Map"] = {} + end + jsondata[preset]["Map"] = currentMap + end + + + if currentAITable ~= nil then + if jsondata[preset]["Bots"] and enabledOptions["ai"] == nil then + jsondata[preset]["Bots"] = {} + end + jsondata[preset]["Bots"] = currentAITable + end + + if currentStartRects ~= nil then + if jsondata[preset]["Starting Areas"] and enabledOptions["startingRects"] == nil then + jsondata[preset]["Starting Areas"] = {} + end + jsondata[preset]["Starting Areas"] = currentStartRects + end + + if currentMPBattleSettings ~= nil then + if jsondata[preset]["Multiplayer Battle Settings"] == nil and enabledOptions["MPBattleSettings"] then + jsondata[preset]["Multiplayer Battle Settings"] = {} + end + jsondata[preset]["Multiplayer Battle Settings"] = currentMPBattleSettings + end + + -- selects to apply preset + selectedPresetName = preset + + saveJSONData() + refreshPresetMenu() +end + +-------------------------------------------------------------------------------- +--- Gui functions +-------------------------------------------------------------------------------- + +-- generate checkbox panel for disabling/ enabling loading +local function ProcessBoolOption(name, active, index) + local label = Label:New { + x = 35, + y = 0, + width = 1200, + height = 30, + valign = "center", + align = "left", + tooltip = optionCaptions[name], --data.name, + caption = name, + objectOverrideFont = WG.Chobby.Configuration:GetFont(2), + } + + local checkBox = Checkbox:New { + x = 5, + y = 0, + width = 30, + height = 30, + boxalign = "left", + boxsize = 25, + caption = "", + tooltip = optionCaptions[name], --data.name, + checked = active, + objectOverrideFont = WG.Chobby.Configuration:GetFont(2), + + OnChange = { + function(_, newState) + enabledOptions[name] = ((newState and true) or false) + end + }, + } + + return Control:New { + x = 0, + y = index * 32, + width = 1600, + height = 32, + padding = { 0, 0, 0, 0 }, + children = { + label, + checkBox + } + } +end + +-- generates the view for the preset selection panel +local function PopulatePresetPanel(parentPanel) + -- reading the default Preset options from the json data + refreshJSONData() + + local function disableSelectedPreset() + deletePreset(selectedPresetName) + end + + + -- popup for entering a new preset Name + local function OpenPresetPopup() + local openPresetPopup = Window:New { + caption = "Create new preset", + name = "createNewPreset", + parent = parentPanel, + align = "center", + width = 450, + height = 200, + resizable = false, + draggable = false, + classname = "main_window", + } + + local presetEditBox = EditBox:New { + x = 10, + y = 10, + width = 300, + right = 10, + height = 30, + text = "", + useIME = false, + hint = "enter a name for your preset", + parent = openPresetPopup, + objectOverrideFont = WG.Chobby.Configuration:GetFont(2), + objectOverrideHintFont = WG.Chobby.Configuration:GetFont(11), + tooltip = "enter a name for your new preset", + } + + Button:New { + x = 10, + width = 135, + y = 50, + height = 70, + caption = "Save", + parent = openPresetPopup, + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + classname = "action_button", + OnClick = { + function() + local presetName = "defaultPreset" + if (presetEditBox.text ~= nil) then + presetName = presetEditBox.text + end + + if presetName == "" or presetName == "" then + refreshPresetMenu() + openPresetPopup:Dispose() + return + end + -- validate presetName + + writePreset(presetName) + openPresetPopup:Dispose() + end + }, + } + + Button:New { + x = 155, + width = 135, + y = 50, + height = 70, + caption = i18n("cancel"), + parent = openPresetPopup, + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + classname = "negative_button", + OnClick = { + function() + refreshPresetMenu() + openPresetPopup:Dispose() + end + }, + } + end + + local presetNames = {} + local presetList = {} + -- (re)generates the dropdown list of presets + refreshPresetMenu = function() + presetNames = {} + if jsondata[selectedPresetName] == nil then + selectedPresetName = placeHolder + end + + table.sort(jsondata) + table.insert(presetNames, selectedPresetName) + table.insert(presetNames, "") + local jsonNames = {} + for key, _ in pairs(jsondata) do + table.insert(jsonNames, key) + end + table.sort(jsonNames) + for _, value in pairs(jsonNames) do + if (value ~= selectedPresetName) then + table.insert(presetNames, value) + end + end + + + parentPanel:RemoveChild(presetList) + presetList = ComboBox:New { + x = 10, + y = 0, + width = 425, + height = 30, + valign = "center", + align = "left", + objectOverrideFont = WG.Chobby.Configuration:GetFont(2), + items = presetNames, + selectByName = true, + selected = selectedPresetName, + OnSelectName = { + function(obj, selectedName) + if (selectedName == "") then + OpenPresetPopup() + presetList.selected = appliedPresetName + selectedPresetName = appliedPresetName + else + selectedPresetName = selectedName + end + end + }, + itemKeyToName = presetNames, + } + parentPanel:AddChild(presetList) + end + + + local buttonSave = Button:New { + x = 10, + width = 135, + y = 40, + height = 70, + caption = "Overwrite", + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + classname = "action_button", + OnClick = { + function() + --verify deletable preset + if selectedPresetName == "" or selectedPresetName == placeHolder or selectedPresetName == "" then + return + end + writePreset(selectedPresetName) + window:Dispose() + -- battleLobby:SetModOptions(localModoptions) + end + }, + } + + + local buttonLoad = Button:New { + x = 155, + width = 135, + y = 40, + height = 70, + caption = i18n("load"), + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + classname = "action_button", + OnClick = { + function() + if (selectedPresetName == nil or selectedPresetName == placeHolder or selectedPresetName == "") then + return + end + applyPreset(selectedPresetName) + window:Dispose() + end + }, + } + + local buttonDelete = Button:New { + x = 300, + width = 135, + y = 40, + height = 70, + caption = i18n("delete_replay"), --seem to contain the appropriate term + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + classname = "negative_button", + OnClick = { + function() + --verify deletable preset + if selectedPresetName == "" or selectedPresetName == "" or selectedPresetName == placeHolder then + return + end + + WG.Chobby.ConfirmationPopup(disableSelectedPreset, + "This will delete preset: \"" .. selectedPresetName .. "\". Are you sure?", nil, + 315, + 170, i18n("yes"), i18n("cancel")) + end + }, + } + + local errorLabel = Label:New { + x = 10, + width = 200, + y = 130, + align = "left", + height = 35, + caption = errorStr, --start with the errorstring defined before + objectOverrideFont = WG.Chobby.Configuration:GetFont(2), + } + -- reset errorStr to only show it once + errorStr = "" + + -- overload the writeError function + writeError = function(errorM) + errorLabel.caption = errorM + end + + refreshPresetMenu() + + parentPanel:AddChild(buttonLoad) + parentPanel:AddChild(buttonDelete) + parentPanel:AddChild(buttonSave) + parentPanel:AddChild(errorLabel) + return { parentPanel } +end + +local function CreateOptionpresetWindow() + local ww, wh = Spring.GetWindowGeometry() + + local optionpresetWindow = Window:New { + caption = "", + align = "center", + name = "OptionpresetsWindow", + parent = WG.Chobby.lobbyInterfaceHolder, + width = math.min(505, ww - 50), + height = math.min(380, wh - 50), + resizable = false, + draggable = false, + classname = "main_window", + } + -- first panel + local contentsPanel = ScrollPanel:New { + x = 4, + right = 0, + y = 10, + bottom = 0, + horizontalScrollbar = false, + } + + -- add the tabs + local tabs = {} + tabs[1] = { + name = "presets", + caption = "Presets", + tooltip = "manage presets", + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + children = { contentsPanel }, + weight = 1, + } + + + -- potential panel 2 + local optionpanel = ScrollPanel:New { + x = 4, + y = 10, + right = 0, + bottom = 0, + -- height = 100, + -- width = 400, + -- parent = contentsPanel, + horizontalScrollbar = false, + } + tabs[2] = { + name = "options", + caption = "Load Options", + tooltip = "specify which options will be loaded from/ saved to preset", + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + children = { optionpanel }, + weight = 2, + } + + -- initiate the tab layout + local tabPanel = Chili.DetachableTabPanel:New { + x = 4, + right = 4, + y = 49, + bottom = 75, + padding = { 0, 0, 0, 0 }, + minTabWidth = 210, + tabs = tabs, + parent = optionpresetWindow, + OnTabChange = { + } + } + + local tabBarHolder = Control:New { + name = "tabBarHolder", + x = 0, + y = 0, + right = 0, + height = 60, + resizable = false, + draggable = false, + padding = { 18, 6, 18, 0 }, + parent = optionpresetWindow, + children = { + Line:New { + classname = "line_solid", + x = 0, + y = 52, + right = 0, + bottom = 0, + }, + tabPanel.tabBar + } + } + + local buttonCancel = Button:New { + right = 6, + width = 135, + bottom = 1, + height = 70, + caption = i18n("cancel"), + objectOverrideFont = WG.Chobby.Configuration:GetFont(3), + parent = optionpresetWindow, + classname = "negative_button", + OnClick = { + function() + -- CancelFunc() + window:Dispose() + end + }, + } + + WG.Chobby.lobbyInterfaceHolder.OnResize = WG.Chobby.lobbyInterfaceHolder.OnResize or {} + WG.Chobby.lobbyInterfaceHolder.OnResize[#WG.Chobby.lobbyInterfaceHolder.OnResize + 1] = function() + local ww, wh = Spring.GetWindowGeometry() + + local neww = math.min(1666, ww - 50) + local newx = (WG.Chobby.lobbyInterfaceHolder.width - neww) / 2 + + local newh = math.min(420, wh - 50) + local newy = (WG.Chobby.lobbyInterfaceHolder.height - newh) / 2 + + optionpresetWindow:SetPos( + newx, + newy, + neww, + newh + ) + end + + local function CancelFunc() + window:Dispose() + end + + local popupHolder = WG.Chobby.PriorityPopup(optionpresetWindow, CancelFunc, nil) + window = optionpresetWindow + PopulatePresetPanel(contentsPanel) + + -- adding the enabled/ disabled options + -- preparing the array + -- first all should be enabled, keys are the same as in the localjson + -- only redefine if undefined + if (enabledOptions["Bots"] == nil) then + enabledOptions["Bots"] = true + enabledOptions["Map"] = true + enabledOptions["Modoptions"] = true + enabledOptions["Starting Areas"] = true + end + if multiplayer and enabledOptions["Multiplayer Battle Settings"] == nil then + enabledOptions["Multiplayer Battle Settings"] = multiplayer + end + + -- disable multiplayer options again when back to singleplayer + if not multiplayer then + enabledOptions["Multiplayer Battle Settings"] = nil + end + + + local counter = 0 + for key, value in pairs(enabledOptions) do + optionpanel:AddChild(ProcessBoolOption(key, value, counter)) + counter = counter + 1 + end +end + +-- clones the multiplayer modoptions to have a reset point that can be used when applying reset value +function OptionpresetsPanel.cloneMPModoptions(force) + if multiplayerModoptions == nil or force then + battleLobby = WG.LibLobby.localLobby + multiplayerModoptions = Spring.Utilities.CopyTable(battleLobby:GetMyBattleModoptions() or {}) + end +end + +-- external function to open the preset Panel +function OptionpresetsPanel.ShowPresetPanel() + battleLobby = WG.LibLobby.localLobby + battle = battleLobby:GetBattle(battleLobby:GetMyBattleID()) + + -- multiplayer case, battle/ lobby are the WG.LibLobby.lobby + if not battle then + battleLobby = WG.LibLobby.lobby + battle = battleLobby:GetBattle(battleLobby:GetMyBattleID()) + multiplayer = true + else + multiplayer = false + end + + + -- copy all options from the battle/ lobby for managing: + + currentModoptions = Spring.Utilities.CopyTable(battleLobby:GetMyBattleModoptions() or {}) + + if battle then + currentMap = battle.mapName + else + Spring.Echo("No battle found") + end + + + local currentAINames = battleLobby.battleAis + currentAITable = {} + for _, value in pairs(currentAINames) do + local aiStatus = battleLobby:GetUserBattleStatus(value) + if (aiStatus ~= nil) then + currentAITable[value] = aiStatus + end + end + + currentStartRects = WG.BattleRoomWindow.GetCurrentStartRects() + + -- multiplayer specific options + if multiplayer then + -- if + WG.OptionpresetsPanel.cloneMPModoptions(false) + + + if currentMPBattleSettings == nil then + currentMPBattleSettings = {} + end + currentMPBattleSettings["locked"] = battle.locked + currentMPBattleSettings["autoBalance"] = battle.autoBalance + currentMPBattleSettings["teamSize"] = battle.teamSize + currentMPBattleSettings["nbTeams"] = battle.nbTeams + currentMPBattleSettings["balanceMode"] = battle.balanceMode + currentMPBattleSettings["preset"] = battle.preset + end + + CreateOptionpresetWindow() +end + +-- make the widget accessible from the preset Panel +function widget:Initialize() + CHOBBY_DIR = LUA_DIRNAME .. "widgets/chobby/" + VFS.Include(LUA_DIRNAME .. "widgets/chobby/headers/exports.lua", nil, VFS.RAW_FIRST) + VFS.Include("libs/json.lua") + + -- clone multiplayer options, if they are defined + WG.OptionpresetsPanel = OptionpresetsPanel +end From e6eba18ce73030095bca771f44825c3dd2a48e3a Mon Sep 17 00:00:00 2001 From: Moose <124457076+AntlerForce@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:08:13 -0700 Subject: [PATCH 3/4] Make option presets button truely unclickable if no game is found --- LuaMenu/widgets/gui_battle_room_window.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LuaMenu/widgets/gui_battle_room_window.lua b/LuaMenu/widgets/gui_battle_room_window.lua index c3b55567d..5bf989988 100644 --- a/LuaMenu/widgets/gui_battle_room_window.lua +++ b/LuaMenu/widgets/gui_battle_room_window.lua @@ -1133,7 +1133,9 @@ local function SetupInfoButtonsPanel(leftInfo, rightInfo, battle, battleID, myUs tooltip = tooltip, OnClick = { function() - WG.OptionpresetsPanel.ShowPresetPanel() + if modoptionsLoaded then + WG.OptionpresetsPanel.ShowPresetPanel() + end end }, parent = leftInfo, From 4cbc5bc1cbf29b82e1be96daa001ac0229599d0b Mon Sep 17 00:00:00 2001 From: Moose <124457076+AntlerForce@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:09:08 -0700 Subject: [PATCH 4/4] Some changes to the English language used --- LuaMenu/widgets/gui_optionpresets_panel.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/LuaMenu/widgets/gui_optionpresets_panel.lua b/LuaMenu/widgets/gui_optionpresets_panel.lua index 9d407a339..80b6abda2 100644 --- a/LuaMenu/widgets/gui_optionpresets_panel.lua +++ b/LuaMenu/widgets/gui_optionpresets_panel.lua @@ -25,11 +25,11 @@ local multiplayer = false -- enabled options local enabledOptions = {} local optionCaptions = { - ["Modoptions"] = "settings part of the adv. options menu", - ["Map"] = "current selected map", - ["Bots"] = "all bots (settings, team)", - ["Starting Areas"] = "all start areas with position", - ["Multiplayer Battle Settings"] = "multiplayer specific settings (battle preset, #teams, ...)" + ["Modoptions"] = "Settings part of the adv. options menu", + ["Map"] = "Current selected map", + ["Bots"] = "All bots (settings, team)", + ["Start Boxes"] = "All start areas with position", + ["Multiplayer Battle Settings"] = "Multiplayer specific settings (battle preset, #teams, ...)" } -- edited by the preset @@ -345,11 +345,11 @@ local function PopulatePresetPanel(parentPanel) height = 30, text = "", useIME = false, - hint = "enter a name for your preset", + hint = "Enter a name for your preset", parent = openPresetPopup, objectOverrideFont = WG.Chobby.Configuration:GetFont(2), objectOverrideHintFont = WG.Chobby.Configuration:GetFont(11), - tooltip = "enter a name for your new preset", + tooltip = "Enter a name for your new preset", } Button:New { @@ -570,7 +570,7 @@ local function CreateOptionpresetWindow() tabs[1] = { name = "presets", caption = "Presets", - tooltip = "manage presets", + tooltip = "Manage presets", objectOverrideFont = WG.Chobby.Configuration:GetFont(3), children = { contentsPanel }, weight = 1, @@ -591,7 +591,7 @@ local function CreateOptionpresetWindow() tabs[2] = { name = "options", caption = "Load Options", - tooltip = "specify which options will be loaded from/ saved to preset", + tooltip = "Specify which options are saved and loaded.", objectOverrideFont = WG.Chobby.Configuration:GetFont(3), children = { optionpanel }, weight = 2, @@ -684,7 +684,7 @@ local function CreateOptionpresetWindow() enabledOptions["Bots"] = true enabledOptions["Map"] = true enabledOptions["Modoptions"] = true - enabledOptions["Starting Areas"] = true + enabledOptions["Start Boxes"] = true end if multiplayer and enabledOptions["Multiplayer Battle Settings"] == nil then enabledOptions["Multiplayer Battle Settings"] = multiplayer