mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Add toolbar saving and better consistency
This commit is contained in:
@@ -61,7 +61,8 @@ return {
|
||||
"modules.gui.production",
|
||||
"modules.gui.playerdata",
|
||||
"modules.gui.surveillance",
|
||||
|
||||
"modules.gui._role_updates",
|
||||
|
||||
"modules.graftorio.require", -- graftorio
|
||||
--- Config Files
|
||||
"config.expcore.permission_groups", -- loads some predefined permission groups
|
||||
|
||||
@@ -1,190 +1,31 @@
|
||||
local Gui = require("modules/exp_gui")
|
||||
local ExpElement = require("modules/exp_gui/prototype")
|
||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||
local PlayerData = require("modules.exp_legacy.expcore.player_data")
|
||||
|
||||
-- Used to store the state of the toolbar when a player leaves
|
||||
local ToolbarState = PlayerData.Settings:combine("ToolbarState")
|
||||
ToolbarState:set_metadata{
|
||||
stringify = function(value)
|
||||
local buttons, favourites = 0, 0
|
||||
for _, state in ipairs(value) do
|
||||
buttons = buttons + 1
|
||||
if state.favourite then
|
||||
favourites = favourites + 1
|
||||
end
|
||||
end
|
||||
|
||||
return string.format("Buttons: %d, Favourites: %d", buttons, favourites)
|
||||
stringify = function()
|
||||
return "Toolbar is saved on exit"
|
||||
end,
|
||||
}
|
||||
|
||||
--- Set the default value for the datastore
|
||||
local datastore_id_map = {} --- @type table<string, ExpElement>
|
||||
local toolbar_default_state = {}
|
||||
ToolbarState:set_default(toolbar_default_state)
|
||||
|
||||
--- Get the datastore id for this element define, to best of ability it should be unique between versions
|
||||
local function to_datastore_id(element_define)
|
||||
-- First try to use the tooltip locale string
|
||||
local tooltip = element_define.tooltip
|
||||
if type(tooltip) == "table" then
|
||||
return tooltip[1]:gsub("%.(.+)", "")
|
||||
end
|
||||
|
||||
-- Then try to use the caption or sprite
|
||||
return element_define.caption or element_define.sprite
|
||||
end
|
||||
|
||||
--- For all top element, register an on click which will copy their style
|
||||
for index, element_define in ipairs(Gui.top_elements) do
|
||||
-- Insert the element into the id map
|
||||
datastore_id_map[to_datastore_id(element_define)] = element_define -- Backwards Compatibility
|
||||
datastore_id_map[element_define.name] = element_define
|
||||
|
||||
-- Add the element to the default state
|
||||
table.insert(toolbar_default_state, {
|
||||
element = element_define.uid,
|
||||
favourite = true,
|
||||
})
|
||||
end
|
||||
|
||||
--- Get the top order based on the players settings
|
||||
Gui.inject_top_flow_order(function(player)
|
||||
local order = ToolbarState:get(player)
|
||||
|
||||
local elements = {}
|
||||
for index, state in ipairs(order) do
|
||||
elements[index] = Gui.defines[state.element]
|
||||
end
|
||||
|
||||
return elements
|
||||
end)
|
||||
|
||||
--- Get the left order based on the player settings, with toolbar menu first, and all remaining after
|
||||
Gui.inject_left_flow_order(function(player)
|
||||
local order = Gui.get_top_flow_order(player)
|
||||
local elements, element_map = { toolbar_container }, { [toolbar_container] = true }
|
||||
|
||||
-- Add the flows that have a top element
|
||||
for _, element_define in ipairs(order) do
|
||||
if element_define.left_flow_element then
|
||||
table.insert(elements, element_define.left_flow_element)
|
||||
element_map[element_define.left_flow_element] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Add the flows that dont have a top element
|
||||
for _, element_define in ipairs(Gui.left_elements) do
|
||||
if not element_map[element_define] then
|
||||
table.insert(elements, element_define)
|
||||
end
|
||||
end
|
||||
|
||||
return elements
|
||||
end)
|
||||
|
||||
--- Overwrite the default update top flow
|
||||
local _update_top_flow = Gui.update_top_flow
|
||||
function Gui.update_top_flow(player)
|
||||
_update_top_flow(player) -- Call the original
|
||||
|
||||
local order = ToolbarState:get(player)
|
||||
for index, state in ipairs(order) do
|
||||
local element_define = Gui.defines[state.element]
|
||||
local top_element = Gui.get_top_element(player, element_define)
|
||||
top_element.visible = top_element.visible and state.favourite or false
|
||||
end
|
||||
end
|
||||
|
||||
--- Uncompress the data to be more useable
|
||||
ToolbarState:on_load(function(player_name, value)
|
||||
-- If there is no value, do nothing
|
||||
if value == nil then return end
|
||||
--- @cast value [ string[], string[], string[], boolean ]
|
||||
-- Old format, we discard it [ string[], string[], string[], boolean ]
|
||||
if type(value) ~= "string" then return end
|
||||
|
||||
-- Create a hash map of the favourites
|
||||
local favourites = {}
|
||||
for _, id in ipairs(value[2]) do
|
||||
favourites[id] = true
|
||||
end
|
||||
|
||||
-- Read the order from the value
|
||||
local elements = {}
|
||||
local element_hash = {}
|
||||
for index, id in ipairs(value[1]) do
|
||||
local element = datastore_id_map[id]
|
||||
if element and not element_hash[element.name] then
|
||||
element_hash[element.name] = true
|
||||
elements[index] = {
|
||||
element = element,
|
||||
favourite = favourites[id] or false,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Add any in the default state that are missing
|
||||
for _, state in ipairs(toolbar_default_state) do
|
||||
if not element_hash[state.element] then
|
||||
table.insert(elements, table.deep_copy(state))
|
||||
end
|
||||
end
|
||||
|
||||
-- Create a hash map of the open left flows
|
||||
local open_left_elements = {}
|
||||
for _, id in ipairs(value[3]) do
|
||||
local element = datastore_id_map[id]
|
||||
local left_element = element.left_flow_element
|
||||
if left_element then
|
||||
open_left_elements[left_element] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the visible state of all left flows
|
||||
local decompressed = helpers.json_to_table(assert(helpers.decode_string(value), "Failed String Decode"))
|
||||
local player = assert(game.get_player(player_name))
|
||||
for left_element in pairs(Gui.left_elements) do
|
||||
Gui.set_left_element_visible(left_element, player, open_left_elements[left_element] or false)
|
||||
end
|
||||
Gui.toolbar.set_state(player, decompressed --[[ @as ExpGui.ToolbarState ]])
|
||||
|
||||
-- Set the toolbar visible state
|
||||
Gui.set_top_flow_visible(player, value[4])
|
||||
|
||||
-- Set the data now and update now, ideally this would be on_update but that had too large of a latency
|
||||
ToolbarState:raw_set(player_name, elements)
|
||||
Gui.reorder_top_flow(player)
|
||||
Gui.reorder_left_flow(player)
|
||||
reorder_toolbar_menu(player)
|
||||
|
||||
return elements
|
||||
return nil -- We don't save the state, use Gui.toolbar.get_state
|
||||
end)
|
||||
|
||||
--- Save the current state of the players toolbar menu
|
||||
ToolbarState:on_save(function(player_name, value)
|
||||
if value == nil then return nil end -- Don't save default
|
||||
local order, favourites, left_flows = {}, {}, {}
|
||||
|
||||
ToolbarState:on_save(function(player_name, _)
|
||||
local player = assert(game.get_player(player_name))
|
||||
local top_flow_open = Gui.get_top_flow(player).parent.visible
|
||||
|
||||
for index, state in ipairs(value) do
|
||||
-- Add the element to the order array
|
||||
--- @diagnostic disable-next-line invisible
|
||||
local element_define = ExpElement._elements[state.element]
|
||||
local id = to_datastore_id(element_define)
|
||||
order[index] = id
|
||||
|
||||
-- If its a favourite then insert it
|
||||
if state.favourite then
|
||||
table.insert(favourites, id)
|
||||
end
|
||||
|
||||
-- If it has a left flow and its open then insert it
|
||||
if element_define.left_flow_element then
|
||||
local left_element = Gui.get_left_element(element_define.left_flow_element, player)
|
||||
if left_element.visible then
|
||||
table.insert(left_flows, id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return { order, favourites, left_flows, top_flow_open }
|
||||
local value = Gui.toolbar.get_state(player)
|
||||
return helpers.encode_string(helpers.table_to_json(value))
|
||||
end)
|
||||
|
||||
7
exp_legacy/module/modules/gui/_role_updates.lua
Normal file
7
exp_legacy/module/modules/gui/_role_updates.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
local Gui = require("modules/exp_gui")
|
||||
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||
local Event = require("modules/exp_legacy/utils/event")
|
||||
|
||||
--- @diagnostic disable invisible
|
||||
Event.add(Roles.events.on_role_assigned, Gui._ensure_consistency)
|
||||
Event.add(Roles.events.on_role_unassigned, Gui._ensure_consistency)
|
||||
Reference in New Issue
Block a user