Merge branch 'explosivegaming:main' into aperx

This commit is contained in:
2026-08-10 20:35:30 +09:00
committed by GitHub
97 changed files with 781 additions and 2434 deletions
+2
View File
@@ -24,6 +24,7 @@ local afk_time_units = {
}
return {
--- @type table<string, LocalisedString | fun(player: LuaPlayer, is_command: boolean): LocalisedString>
messages = { --- @setting messages will trigger when ever the word is said
["discord"] = { "info.discord" },
["expgaming"] = { "info.website" },
@@ -66,6 +67,7 @@ return {
command_admin_only = false, --- @setting command_admin_only when true will only allow chat commands for admins
command_permission = "command/chat-commands", --- @setting command_permission the permission used to allow command prefixes
command_prefix = "!", --- @setting command_prefix prefix used for commands below and to print to all players (if enabled above)
--- @type table<string, LocalisedString | fun(player: LuaPlayer, is_command: boolean): LocalisedString>
commands = { --- @setting commands will trigger only when command prefix is given
["dev"] = { "exp_chat-auto-reply.reply-dev" },
["magic"] = { "exp_chat-auto-reply.reply-magic" },
@@ -15,7 +15,8 @@ local Colors = require("modules/exp_util/include/color")
local format_player_name = ExpUtil.format_player_name_locale
--- Accessors injected by the gui so the actions can read the selected player and set the selected action
local get_selected_player, set_selected_action
local get_selected_player --- @type fun(player: LuaPlayer): LuaPlayer
local set_selected_action --- @type fun(player: LuaPlayer, action: string?)
local function set_accessors(player_getter, action_setter)
get_selected_player, set_selected_action = player_getter, action_setter
end
@@ -31,7 +32,7 @@ end
-- gets the action player and a coloured name for the action to be used on
local function get_action_player(player)
local selected_player = get_selected_player(player) --[[ @as LuaPlayer ]]
local selected_player = get_selected_player(player) --[[@as LuaPlayer]]
local selected_player_color = format_player_name(selected_player)
return selected_player, selected_player_color
end
+6 -6
View File
@@ -87,7 +87,7 @@ return {
amount = 4000,
size = { 26, 27 },
-- offset = {-64,-32}
offset = { -64, -64 },
offset = { x = -64, y = -64 },
},
{
enabled = false,
@@ -95,7 +95,7 @@ return {
amount = 4000,
size = { 26, 27 },
-- offset = {-64, 0}
offset = { 64, -64 },
offset = { x = 64, y = -64 },
},
{
enabled = false,
@@ -103,7 +103,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, 32}
offset = { -64, 64 },
offset = { x = -64, y = 64 },
},
{
enabled = false,
@@ -111,7 +111,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, -64}
offset = { 64, 64 },
offset = { x = 64, y = 64 },
},
{
enabled = false,
@@ -119,7 +119,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, -96}
offset = { 0, 64 },
offset = { x = 0, y = 64 },
},
},
},
@@ -132,7 +132,7 @@ return {
num_patches = 4,
amount = 4000000,
-- offset = {-80, -12},
offset = { -12, 64 },
offset = { x = -12, y = 64 },
-- offset_next = {0, 6}
offset_next = { 6, 0 },
},
+14
View File
@@ -35,6 +35,20 @@ return {
storage_output = 1, -- >0 allows for item teleportation (allowed_items only)
},
--- @class Vlayer.ItemProperties
--- @field starting_value number
--- @field required_area number
--- @field production number?
--- @field discharge number?
--- @field capacity number?
--- @field surface_area number?
--- @field fuel_value number?
--- @field power boolean?
--- @field modded boolean? Set when the item is registered from a modded equivalent
--- @field base_game_equivalent string?
--- @field multiplier number?
--- @type table<string, Vlayer.ItemProperties>
allowed_items = { --- @setting allowed_items List of all items allowed in vlayer storage and their properties
--[[
Allowed properties:
+1
View File
@@ -2,6 +2,7 @@
-- @config Warnings
return {
--- @type (LocalisedString[] | fun(player: LuaPlayer, by_player_name: string, number_of_warnings: number))[]
actions = { --- @setting actions what actions are taking at number of warnings
-- if a localized string is used then __1__ will by_player_name and __2__ will be the current warning count (auto inserted)
{ "warnings.received", "" },
+16 -2
View File
@@ -149,9 +149,23 @@ PlayerData.Statistics:combine('JoinCount')
local Storage = require("modules/exp_util/storage")
local DatastoreManager = {}
local Datastores = {}
local Datastore = {}
local Datastores = {} --- @type table<string, Datastore>
local Data = {}
--- @class Datastore
--- @field name string
--- @field value_name string
--- @field auto_save boolean
--- @field save_to_disk boolean
--- @field propagate_changes boolean
--- @field serializer function | false
--- @field parent Datastore | false
--- @field children table<string, Datastore>
--- @field metadata table
--- @field events table<string, function[]>
--- @field data table
local Datastore = {}
local copy = table.deep_copy
local trace = debug.traceback
local table_to_json = helpers.table_to_json
+10 -8
View File
@@ -14,7 +14,8 @@ end
]]
local ext, var
local ext --- @type table<string, any>
local var --- @type table<string, any>
local concat = table.concat
local External = {}
@@ -29,12 +30,13 @@ end
]]
function External.valid()
if storage.ext == nil then return false end
if ext == storage.ext and var == ext.var then
local stored = storage.ext
if stored == nil then return false end
if ext == stored and var == ext.var then
return var ~= nil
else
ext = storage.ext
var = ext.var
ext = stored
var = stored.var
return var ~= nil
end
end
@@ -48,7 +50,7 @@ local servers = External.get_servers()
]]
function External.get_servers()
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
return assert(ext.servers, "No server list was found, please ensure that the external service is running")
return (assert(ext.servers, "No server list was found, please ensure that the external service is running"))
end
--[[-- Gets a table of all the servers filtered by name, key is the server id, value is the server details
@@ -83,7 +85,7 @@ function External.get_current_server()
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local server_id = assert(ext.current, "No current id was found, please ensure that the external service is running")
return assert(servers[server_id], "No details found for server with id: " .. tostring(server_id))
return (assert(servers[server_id], "No details found for server with id: " .. tostring(server_id)))
end
--[[-- Gets the details of the given server
@@ -97,7 +99,7 @@ local server = External.get_server_details('eu-01')
function External.get_server_details(server_id)
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
return assert(servers[server_id], "No details found for server with id: " .. tostring(server_id))
return (assert(servers[server_id], "No details found for server with id: " .. tostring(server_id)))
end
--[[-- Gets the status of the given server
@@ -142,7 +142,7 @@ group:set_action('toggle_map_editor', false)
]]
function PermissionsGroups._prototype:set_action(action, state)
local input_action = defines.input_action[action] --[[ @as defines.input_action? ]]
local input_action = defines.input_action[action] --[[@as defines.input_action?]]
if input_action == nil then input_action = action end
assert(type(input_action) == "number", tostring(action) .. " is not a valid input action")
self.actions[input_action] = state
+1 -1
View File
@@ -55,7 +55,7 @@ PlayerData:set_serializer(Datastore.name_serializer) -- use player name
--- Store and enum for the data saving preference
local DataSavingPreference = PlayerData:combine("DataSavingPreference")
local PreferenceEnum = { "All", "Statistics", "Settings", "Required" }
local PreferenceEnum = { "All", "Statistics", "Settings", "Required" } --- @type table<string | number, string | number>
for k, v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default("All")
+31 -12
View File
@@ -117,11 +117,28 @@ local Groups = require("modules.exp_legacy.expcore.permission_groups")
local Colours = ExpUtil.color
local write_json = ExpUtil.write_json
--- @class Roles.Role
--- @field name string
--- @field short_hand string
--- @field index number Position within the role order
--- @field allowed_actions table<string, boolean>
--- @field allow_all_actions boolean
--- @field flags table<string, boolean>
--- @field disallowed_actions table<string, boolean>?
--- @field permission_group ([boolean, string] | string)?
--- @field custom_tag string?
--- @field custom_color Color?
--- @field parent string?
--- @field block_auto_assign boolean?
--- @field auto_assign_condition function?
--- @field set_allow_all fun(self: Roles.Role, state: boolean?): Roles.Role Defined on Roles._prototype
local Roles = {
_prototype = {},
config = {
order = {}, -- Contains the order of the roles, lower index is better
roles = {}, -- Contains the raw info for the roles, indexed by role name
order = {}, --- @type string[] Contains the order of the roles, lower index is better
roles = {}, --- @type table<string, Roles.Role> Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
@@ -200,7 +217,7 @@ function Roles.debug()
local output = ""
for index, role_name in ipairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
local color = role.custom_color or Colours.white
local color = (role.custom_color or Colours.white) --[[@as Color.struct]]
local color_str = string.format("[color=%d, %d, %d]", color.r, color.g, color.b)
output = output .. string.format("\n%s %s) %s[/color]", color_str, index, serpent.line(role))
end
@@ -287,6 +304,7 @@ local role = Roles.get_role_by_name(2)
]]
function Roles.get_role_by_order(index)
local name = Roles.config.order[index]
if not name then return end
return Roles.config.roles[name]
end
@@ -348,16 +366,17 @@ end
local role = Roles.get_player_highest_role(game.player)
]]
--- @return Roles.Role
function Roles.get_player_highest_role(player)
local roles = Roles.get_player_roles(player)
local highest
local highest --- @type Roles.Role?
for _, role in ipairs(roles) do
if not highest or role.index < highest.index then
highest = role
end
end
return highest
return (assert(highest, "Player has no roles"))
end
--- Assignment.
@@ -458,7 +477,7 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
-- If the player has a role that needs to defer the role changes, save the roles that need to be unassigned later into a table
local defer_changes = Roles.player_has_flag(player, "defer_role_changes")
if defer_changes then
if defer_changes and valid_player then
local assign_later = Roles.config.deferred_roles[valid_player.name] or {}
for _, role in ipairs(role_objects) do
local role_change = assign_later[role.name]
@@ -719,7 +738,7 @@ local role = Roles.new_role('Moderator', 'Mod')
]]
function Roles.new_role(name, short_hand)
ExpUtil.assert_not_runtime()
if Roles.config.roles[name] then return error("Role name is non unique") end
if Roles.config.roles[name] then error("Role name is non unique") end
local role = setmetatable({
name = name,
short_hand = short_hand or name,
@@ -894,10 +913,9 @@ role:set_permission_group('Admin')
function Roles._prototype:set_permission_group(name, use_factorio_api)
ExpUtil.assert_not_runtime()
if use_factorio_api then
self.permission_group = { true, name }
self.permission_group = { true, name } --[[@as [boolean, string] ]]
else
local group = Groups.get_group_by_name(name)
if not group then return end
assert(Groups.get_group_by_name(name), "Permission group not found: " .. name)
self.permission_group = name
end
return self
@@ -1115,8 +1133,9 @@ local function role_update(event)
-- Updates the players permission group
local highest = Roles.get_player_highest_role(player)
if highest.permission_group then
if highest.permission_group[1] then
local group = game.permissions.get_group(highest.permission_group[2])
local permission_group = highest.permission_group --[[@as [boolean, string] ]]
if permission_group[1] then
local group = game.permissions.get_group(permission_group[2])
if group then
Groups.add_to_permission_group_async(group, player)
end
@@ -34,7 +34,7 @@ for _, config_key in ipairs{ "always_protected_names", "always_protected_types",
end
-- Require roles if a permission is assigned in the config
local Roles
local Roles --- @type table<string, any>
if config.ignore_permission then
Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
end
@@ -4,7 +4,7 @@ local Gui = require("modules/exp_gui")
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
----- Locals -----
local follow_label -- Gui constructor
local follow_label --- @type ExpElement Gui constructor
local following = {}
local spectating = {}
local Public = {}
+19 -18
View File
@@ -14,10 +14,10 @@ local mega = 1000000
local vlayer = {}
local vlayer_data = {
entity_interfaces = {
energy = {},
circuit = {},
storage_input = {},
storage_output = {},
energy = {}, --- @type LuaEntity[]
circuit = {}, --- @type LuaEntity[]
storage_input = {}, --- @type LuaEntity[]
storage_output = {}, --- @type LuaEntity[]
},
properties = {
total_surface_area = 0,
@@ -28,10 +28,10 @@ local vlayer_data = {
capacity = 0,
},
storage = {
items = {},
power_items = {},
items = {}, --- @type table<string, number>
power_items = {}, --- @type table<string, { value: number, count: number }>
energy = 0,
unallocated = {},
unallocated = {}, --- @type table<string, number>
},
surface = table.deep_copy(config.surface),
}
@@ -45,7 +45,7 @@ for name, properties in pairs(config.allowed_items) do
if properties.power then
vlayer_data.storage.power_items[name] = {
value = properties.fuel_value * 1000000,
value = assert(properties.fuel_value) * 1000000,
count = 0,
}
end
@@ -361,7 +361,7 @@ local function handle_input_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.storage_input[index] = nil
else
local inventory = interface.get_inventory(defines.inventory.chest)
local inventory = assert(interface.get_inventory(defines.inventory.chest))
for _, v in pairs(inventory.get_contents()) do
if config.allowed_items[v.name] then
@@ -384,8 +384,9 @@ local function handle_input_interfaces()
if count_deduct and count_add then
if config.allowed_items[v.name].modded then
local modded_item = assert(config.modded_items[v.name])
if config.modded_auto_downgrade then
vlayer.insert_item(config.modded_items[v.name].base_game_equivalent, count_add * config.modded_items[v.name].multiplier)
vlayer.insert_item(modded_item.base_game_equivalent, count_add * modded_item.multiplier)
else
vlayer.insert_item(v.name, count_add)
end
@@ -439,14 +440,14 @@ local function handle_output_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.storage_output[index] = nil
else
local inventory = interface.get_inventory(defines.inventory.chest)
local inventory_request_sections = interface.get_logistic_sections().sections
local inventory = assert(interface.get_inventory(defines.inventory.chest))
local inventory_request_sections = assert(interface.get_logistic_sections()).sections
for i = 1, #inventory_request_sections do
for _, v in pairs(inventory_request_sections[i].filters) do
if v.value and config.allowed_items[v.value.name] then
local current_amount = inventory.get_item_count(v.value.name)
local request_amount = math.min(v.min - current_amount, vlayer_data.storage.items[v.value.name])
local request_amount = math.min(assert(v.min) - current_amount, vlayer_data.storage.items[v.value.name])
if request_amount > 0 and inventory.can_insert{ name = v.value.name, count = request_amount } then
local removed_item_count = vlayer.remove_item(v.value.name, request_amount)
@@ -582,11 +583,11 @@ local function handle_circuit_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.circuit[index] = nil
else
local circuit_oc = interface.get_or_create_control_behavior()
if circuit_oc.sections_count == 0 then
circuit_oc.add_section()
local control = interface.get_or_create_control_behavior() --[[@as LuaConstantCombinatorControlBehavior]]
if control.sections_count == 0 then
control.add_section()
end
circuit_oc = circuit_oc.sections[1]
local circuit_oc = assert(control.sections[1])
local signal_index = 1
local circuit = vlayer.get_circuits()
@@ -617,7 +618,7 @@ local function handle_circuit_interfaces()
-- Clear remaining signals to prevent outdated values being present (caused by count > 0 check)
for clear_index = signal_index, #circuit do
if not circuit_oc.get_slot(clear_index).signal then
if not circuit_oc.get_slot(clear_index).value then
break -- There are no more signals to clear
end
@@ -107,7 +107,7 @@ function Warnings.add_warning(player, by_player_name, reason)
reason = reason or "None given."
local warning_count
local warning_count --- @type number
PlayerWarnings:update(player.name, function(_, warnings)
local warning = {
by_player_name = by_player_name,
+1 -1
View File
@@ -18,7 +18,7 @@ ToolbarState:on_load(function(player_name, value)
local decompressed = helpers.json_to_table(assert(helpers.decode_string(value), "Failed String Decode"))
local player = assert(game.get_player(player_name))
Gui.toolbar.set_state(player, decompressed --[[ @as Gui.ToolbarState ]])
Gui.toolbar.set_state(player, decompressed --[[@as Gui.ToolbarState]])
return nil -- We don't save the state, use Gui.toolbar.get_state
end)
@@ -126,19 +126,19 @@ lib.collect_loginet = function()
end
if config.modules.logistorage then
for name, v in pairs(network.get_contents()) do
stats.items[name] = (stats.items[name] or 0) + v
for _, item in pairs(network.get_contents()) do
stats.items[item.name] = (stats.items[item.name] or 0) + item.count
end
-- pickups and deliveries of items
for _, point_list in pairs{ network.provider_points, network.requester_points, network.storage_points } do
for _, point in pairs(point_list) do
for name, qty in pairs(point.targeted_items_pickup) do
stats.pickups[name] = (stats.pickups[name] or 0) + qty
for _, item in pairs(point.targeted_items_pickup) do
stats.pickups[item.name] = (stats.pickups[item.name] or 0) + item.count
end
for name, qty in pairs(point.targeted_items_deliver) do
stats.deliveries[name] = (stats.deliveries[name] or 0) + qty
for _, item in pairs(point.targeted_items_deliver) do
stats.deliveries[item.name] = (stats.deliveries[item.name] or 0) + item.count
end
end
end
@@ -2,6 +2,6 @@ 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
--- @diagnostic disable: access-invisible
Event.add(Roles.events.on_role_assigned, Gui._ensure_consistency)
Event.add(Roles.events.on_role_unassigned, Gui._ensure_consistency)
+15 -13
View File
@@ -22,9 +22,9 @@ local function aabb_align_expand(aabb)
}
end
local vlayer_container
local vlayer_gui_control_type
local vlayer_gui_control_list
local vlayer_container --- @type ExpElement
local vlayer_gui_control_type --- @type ExpElement
local vlayer_gui_control_list --- @type ExpElement
local vlayer_control_type_list = {
[1] = "energy",
@@ -87,10 +87,10 @@ SelectArea:on_selection(function(event)
local container = Gui.get_left_element(vlayer_container, player)
local disp = container.frame["vlayer_st_2"].disp.table
local target = vlayer_control_type_list[disp[vlayer_gui_control_type.name].selected_index]
local entities
local entities --- @type LuaEntity[]
if config.power_on_space and event.surface and event.surface.platform and target == "energy" then
if player.force.technologies[config.power_on_space_research.name].level >= config.power_on_space_research.level then
if (player.force --[[@as LuaForce]]).technologies[config.power_on_space_research.name].level >= config.power_on_space_research.level then
entities = event.surface.find_entities_filtered{ area = area, name = "constant-combinator", force = player.force }
else
player.print{ "vlayer.power-on-space-research", config.power_on_space_research.name, config.power_on_space_research.level }
@@ -116,7 +116,7 @@ SelectArea:on_selection(function(event)
local e_pos = { x = string.format("%.1f", e.position.x), y = string.format("%.1f", e.position.y) }
local e_circ = nil -- e.get_wire_connectors{ or_create = false }
if e.name and e.name == "steel-chest" and (not e.get_inventory(defines.inventory.chest).is_empty()) then
if e.name and e.name == "steel-chest" and (not assert(e.get_inventory(defines.inventory.chest)).is_empty()) then
player.print{ "vlayer.steel-chest-empty" }
return
end
@@ -325,7 +325,9 @@ local function vlayer_gui_list_refresh(player)
local interface = vlayer.get_interfaces()[vlayer_control_type_list[target]]
for i = 1, vlayer.get_interface_counts()[vlayer_control_type_list[target]], 1 do
table.insert(full_list, i .. " X " .. interface[i].position.x .. " Y " .. interface[i].position.y)
local entity = assert(interface[i])
local entity_position = entity.position
table.insert(full_list, i .. " X " .. entity_position.x .. " Y " .. entity_position.y)
end
disp[vlayer_gui_control_list.name].items = full_list
@@ -379,14 +381,13 @@ local vlayer_gui_control_see = Gui.define("vlayer_gui_control_see")
}:style{
width = 200,
}:on_click(function(def, player, element, event)
local target = element.parent[vlayer_gui_control_type.name].selected_index
local n = element.parent[vlayer_gui_control_list.name].selected_index
local target = assert(element.parent)[vlayer_gui_control_type.name].selected_index
local n = assert(element.parent)[vlayer_gui_control_list.name].selected_index
if target and vlayer_control_type_list[target] and n > 0 then
local i = vlayer.get_interfaces()
local entity = i[vlayer_control_type_list[target]][n]
if entity and entity.valid then
local player = Gui.get_player(event)
player.set_controller{ type = defines.controllers.remote, position = entity.position, surface = entity.surface }
player.print{ "vlayer.result-interface-location", { "vlayer.control-type-" .. vlayer_control_type_list[target]:gsub("_", "-") }, pos_to_gps_string(entity.position, entity.surface.name) }
end
@@ -423,14 +424,15 @@ local vlayer_gui_control_remove = Gui.define("vlayer_gui_control_remove")
}:style{
width = 200,
}:on_click(function(def, player, element)
local target = element.parent[vlayer_gui_control_type.name].selected_index
local n = element.parent[vlayer_gui_control_list.name].selected_index
local target = assert(element.parent)[vlayer_gui_control_type.name].selected_index
local n = assert(element.parent)[vlayer_gui_control_list.name].selected_index
if target and vlayer_control_type_list[target] and n > 0 then
local i = vlayer.get_interfaces()
if i and i[vlayer_control_type_list[target]] then
local interface_type, interface_surface, interface_position = vlayer.remove_interface(i[vlayer_control_type_list[target]][n].surface, i[vlayer_control_type_list[target]][n].position)
local entity = assert(i[vlayer_control_type_list[target]][n])
local interface_type, interface_surface, interface_position = vlayer.remove_interface(entity.surface, entity.position)
if interface_type then
game.print{ "vlayer.interface-result", player.name, pos_to_gps_string(interface_position, interface_surface.name), { "vlayer.result-remove" }, { "vlayer.control-type-" .. interface_type } }
+20 -16
View File
@@ -180,7 +180,7 @@ local warp_icon_button = Gui.define("warp_icon_button")
:style(Styles.sprite32)
:on_click(function(def, player, element)
if element.type == "choose-elem-button" then return end
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
Warps.teleport_player(warp_id, player)
-- Reset the warp cooldown if the player does not have unlimited warps
@@ -226,7 +226,7 @@ local warp_label = Gui.define("warp_label")
horizontally_stretchable = true,
}
:on_click(function(def, player, element)
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
local warp = Warps.get_warp(warp_id)
player.set_controller{ type = defines.controllers.remote, position = warp.position, surface = warp.surface }
end)
@@ -271,9 +271,9 @@ local warp_textfield = Gui.define("warp_textfield")
right_margin = 2,
}
:on_confirmed(function(def, player, element)
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
local warp_name = element.text
local warp_icon = element.parent.parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[ @as SignalID ]]
local warp_icon = assert(element.parent).parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[@as SignalID]]
if warp_icon.type == nil then warp_icon.type = "item" end
Warps.set_editing(warp_id, player.name)
Warps.update_warp(warp_id, warp_name, warp_icon, player.name)
@@ -291,9 +291,13 @@ local confirm_edit_button = Gui.define("confirm_edit_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
local warp_id = element.parent.caption
local warp_name = element.parent.parent["name-" .. warp_id][warp_textfield.name].text
local warp_icon = element.parent.parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[ @as SignalID ]]
local parent = assert(element.parent)
local grandparent = assert(parent.parent)
local warp_id = parent.caption --[[@as string]]
local name_flow = grandparent["name-" .. warp_id]
local icon_flow = grandparent["icon-" .. warp_id]
local warp_name = name_flow[warp_textfield.name].text
local warp_icon = icon_flow[warp_icon_editing.name].elem_value --[[@as SignalID]]
if warp_icon.type == nil then warp_icon.type = "item" end
Warps.set_editing(warp_id, player.name)
Warps.update_warp(warp_id, warp_name, warp_icon, player.name)
@@ -311,7 +315,7 @@ local cancel_edit_button = Gui.define("cancel_edit_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
-- Check if this is the first edit, if so remove the warp.
local warp = Warps.get_warp(warp_id)
if warp.updates == 1 then
@@ -333,7 +337,7 @@ local remove_warp_button = Gui.define("remove_warp_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
Warps.remove_warp(warp_id)
end)
@@ -349,7 +353,7 @@ local edit_warp_button = Gui.define("edit_warp_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
local warp_id = element.parent.caption
local warp_id = assert(element.parent).caption
Warps.set_editing(warp_id, player.name, true)
end)
@@ -429,8 +433,8 @@ local function update_warp_elements(element, warp, warp_player_is_on, on_cooldow
-- Check if button element is valid
if not element or not element.valid then return end
local label_style = element.parent.parent["name-" .. warp.warp_id][warp_label.name].style
local warp_status_element = element.parent.parent["name-" .. warp.warp_id][warp_status.name]
local label_style = assert(element.parent).parent["name-" .. warp.warp_id][warp_label.name].style
local warp_status_element = assert(element.parent).parent["name-" .. warp.warp_id][warp_status.name]
-- If player is not on a warp
if not warp_player_is_on then
@@ -669,7 +673,7 @@ warp_list_container = Gui.define("warp_list_container")
-- Draw the scroll table for the warps
local scroll_table = Gui.elements.scroll_table(container, 250, 3, "scroll")
-- Set the scroll panel to always show the scrollbar (not doing this will result in a changing gui size)
scroll_table.parent.vertical_scroll_policy = "always"
assert(scroll_table.parent).vertical_scroll_policy = "always"
-- Change the style of the scroll table
local scroll_table_style = scroll_table.style
@@ -778,7 +782,7 @@ Event.on_nth_tick(math.floor(60 / config.update_smoothing), function()
end
-- Check if the force has any warps
local closest_warp = nil
local closest_warp = nil --- @type { warp_id: string, name: string }?
local closest_distance = nil
if #warp_ids > 0 then
local surface = player.surface
@@ -838,7 +842,7 @@ end)
Event.add(defines.events.on_player_created, function(event)
-- If the force has no spawn then make a spawn warp
local player = game.players[event.player_index]
local force = player.force
local force = player.force --[[@as LuaForce]]
local spawn_id = Warps.get_spawn_warp_id(force.name)
if not spawn_id then
local spawn_position = force.get_spawn_position(player.surface)
@@ -870,7 +874,7 @@ local function role_update_event(event)
-- Check if user has permission to add warps
local allow_add_warp = check_player_permissions(player, "allow_add_warp")
-- Update container size depending on whether the player is allowed to add warps
frame.parent.style.width = allow_add_warp and 268 or 220
assert(frame.parent).style.width = allow_add_warp and 268 or 220
-- Update the warps, in case the user can now edit them
local scroll_table = frame.scroll.table