From f8c74c9dd3ad82f883c5f94b429572d6c7886a10 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Mon, 30 Sep 2024 22:32:35 +0100 Subject: [PATCH] Merge Game, FlyingText, Common and table --- .luarc.json | 26 +- exp_commands/module/commands/rcon.lua | 2 + exp_commands/module/module_exports.lua | 8 +- exp_legacy/module/async.lua | 0 exp_legacy/module/config/chat_reply.lua | 6 +- .../config/expcore/command_general_parse.lua | 3 +- .../config/expcore/command_role_parse.lua | 3 +- .../module/config/gui/player_list_actions.lua | 11 +- exp_legacy/module/control.lua | 6 - exp_legacy/module/expcore/commands.lua | 30 +- exp_legacy/module/expcore/common.lua | 832 ------------------ exp_legacy/module/expcore/external.lua | 2 +- exp_legacy/module/expcore/gui/_require.lua | 5 +- exp_legacy/module/expcore/gui/left_flow.lua | 3 +- exp_legacy/module/expcore/gui/prototype.lua | 9 +- exp_legacy/module/expcore/gui/top_flow.lua | 3 +- .../module/expcore/permission_groups.lua | 8 +- exp_legacy/module/expcore/roles.lua | 33 +- .../module/modules/addons/chat-popups.lua | 14 +- .../module/modules/addons/damage-popups.lua | 13 +- .../module/modules/addons/death-logger.lua | 29 +- exp_legacy/module/modules/addons/deconlog.lua | 5 +- .../module/modules/addons/discord-alerts.lua | 10 +- .../module/modules/addons/inventory-clear.lua | 12 +- exp_legacy/module/modules/addons/miner.lua | 2 +- .../module/modules/addons/nukeprotect.lua | 18 +- .../module/modules/addons/protection-jail.lua | 5 +- .../module/modules/addons/report-jail.lua | 5 +- .../module/modules/addons/scorched-earth.lua | 31 - .../module/modules/commands/admin-chat.lua | 5 +- .../modules/commands/clear-inventory.lua | 27 +- .../module/modules/commands/interface.lua | 7 +- exp_legacy/module/modules/commands/jail.lua | 11 +- .../module/modules/commands/last-location.lua | 5 +- .../module/modules/commands/protection.lua | 5 +- .../module/modules/commands/rainbow.lua | 3 +- .../module/modules/commands/reports.lua | 17 +- exp_legacy/module/modules/commands/roles.lua | 7 +- exp_legacy/module/modules/commands/search.lua | 10 +- .../modules/commands/surface-clearing.lua | 18 +- .../module/modules/commands/warnings.lua | 17 +- exp_legacy/module/modules/control/jail.lua | 7 +- exp_legacy/module/modules/control/reports.lua | 3 +- exp_legacy/module/modules/control/vlayer.lua | 18 +- .../module/modules/control/warnings.lua | 7 +- exp_legacy/module/modules/control/warps.lua | 2 +- .../module/modules/data/player-colours.lua | 2 +- exp_legacy/module/modules/data/statistics.lua | 27 +- .../module/modules/factorio-control.lua | 162 ++-- exp_legacy/module/modules/gui/autofill.lua | 13 +- .../gui/debug/expcore_datastore_view.lua | 8 +- exp_legacy/module/modules/gui/player-list.lua | 12 +- exp_legacy/module/modules/gui/playerdata.lua | 32 +- exp_legacy/module/modules/gui/readme.lua | 6 +- exp_legacy/module/modules/gui/research.lua | 34 +- exp_legacy/module/modules/gui/rocket-info.lua | 10 +- .../module/modules/gui/science-info.lua | 21 +- exp_legacy/module/modules/gui/task-list.lua | 5 +- exp_legacy/module/modules/gui/warp-list.lua | 14 +- exp_legacy/module/overrides/table.lua | 448 ---------- exp_legacy/module/overrides/version.lua | 5 - exp_legacy/module/utils/game.lua | 40 - exp_util/module/common.lua | 425 ++++++--- exp_util/module/floating_text.lua | 180 ---- exp_util/module/flying_text.lua | 89 ++ exp_util/module/include/table.lua | 16 +- 66 files changed, 817 insertions(+), 2035 deletions(-) create mode 100644 exp_legacy/module/async.lua delete mode 100644 exp_legacy/module/expcore/common.lua delete mode 100644 exp_legacy/module/overrides/table.lua delete mode 100644 exp_legacy/module/overrides/version.lua delete mode 100644 exp_legacy/module/utils/game.lua delete mode 100644 exp_util/module/floating_text.lua create mode 100644 exp_util/module/flying_text.lua diff --git a/.luarc.json b/.luarc.json index eaed9d20..5771c303 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,9 +1,8 @@ { "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", "completion.requireSeparator": "/", - "doc.privateName": [ "__" ], - "doc.protectedName": [ "_" ], - "runtime.version": "Lua 5.2", + "doc.privateName": [ "__(\\w+)" ], + "doc.protectedName": [ "_(\\w+)" ], "runtime.pluginArgs": [ "--clusterio-modules" ], @@ -40,7 +39,15 @@ "type" : "pattern", "param": "_?_?(\\w+)", "$1": "snake_case" - }, "pascal_case"], + }, { + "type" : "pattern", + "param": "_?_?(\\w+)", + "$1": "upper_snake_case" + }, { + "type" : "pattern", + "param": "_?_?(\\w+)", + "$1": "pascal_case" + }], "function_param_name_style": [{ "type" : "pattern", "param": "_?_?(\\w+)?", @@ -62,9 +69,14 @@ "$1": "snake_case" }], "global_variable_name_style": [{ - "type": "ignore", - "param": ["_VERSION"] - }, "snake_case", "upper_snake_case" ], + "type" : "pattern", + "param": "_?_?(\\w+)", + "$1": "snake_case" + }, { + "type" : "pattern", + "param": "_?_?(\\w+)", + "$1": "upper_snake_case" + }], "module_name_style": [ "pascal_case", "snake_case" ], "require_module_name_style": [ "pascal_case", "snake_case" ], "class_name_style": "pascal_case", diff --git a/exp_commands/module/commands/rcon.lua b/exp_commands/module/commands/rcon.lua index cea218b3..555bdd4e 100644 --- a/exp_commands/module/commands/rcon.lua +++ b/exp_commands/module/commands/rcon.lua @@ -22,12 +22,14 @@ setmetatable(rcon_statics, { __index = _G }) setmetatable(rcon_env, { __index = rcon_statics }) --- Some common static values which can be added now +--- @diagnostic disable: name-style-check rcon_statics.Async = Async rcon_statics.ExpUtil = ExpUtil rcon_statics.Commands = Commands rcon_statics.Clustorio = Clustorio rcon_statics.output = Commands.print rcon_statics.ipc = Clustorio.send_json +--- @diagnostic enable: name-style-check --- Some common callback values which are useful when a player uses the command function rcon_callbacks.player(player) return player end diff --git a/exp_commands/module/module_exports.lua b/exp_commands/module/module_exports.lua index 3b3e866a..bc9f10df 100644 --- a/exp_commands/module/module_exports.lua +++ b/exp_commands/module/module_exports.lua @@ -364,9 +364,11 @@ function Commands.print(message, color, sound) if not player then rcon.print(ExpUtil.format_any(message)) else - local formatted = ExpUtil.format_any(message, nil, 20) - player.print(formatted, color or Color.white) - player.play_sound{ path = sound or "utility/scenario_message" } + local formatted = ExpUtil.format_any(message, { max_line_count = 20 }) + player.print(formatted, { + color = color or Color.white, + sound_path = sound or "utility/scenario_message", + }) end end diff --git a/exp_legacy/module/async.lua b/exp_legacy/module/async.lua new file mode 100644 index 00000000..e69de29b diff --git a/exp_legacy/module/config/chat_reply.lua b/exp_legacy/module/config/chat_reply.lua index 12397432..36ba39fc 100644 --- a/exp_legacy/module/config/chat_reply.lua +++ b/exp_legacy/module/config/chat_reply.lua @@ -47,7 +47,7 @@ return { end end - return { "chat-bot.afk", max.name, ExpUtil.format_locale_time(max.afk_time, "long", afk_time_units) } + return { "chat-bot.afk", max.name, ExpUtil.format_time_locale(max.afk_time, "long", afk_time_units) } end, ["players"] = function(_player, _is_command) return { "chat-bot.players", #game.players } @@ -70,7 +70,7 @@ return { names[#names + 1] = next_player.name end - return { "chat-bot.blame", table.get_random_dictionary_entry(names) } + return { "chat-bot.blame", table.get_random(names) } end, ["magic"] = { "chat-bot.magic" }, ["aids"] = { "chat-bot.aids" }, @@ -78,7 +78,7 @@ return { ["lenny"] = { "chat-bot.lenny" }, ["hodor"] = function(_player, _is_command) local options = { "?", ".", "!", "!!!" } - return { "chat-bot.hodor", table.get_random_dictionary_entry(options) } + return { "chat-bot.hodor", table.get_random(options) } end, ["evolution"] = function(_player, _is_command) return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].evolution_factor) } diff --git a/exp_legacy/module/config/expcore/command_general_parse.lua b/exp_legacy/module/config/expcore/command_general_parse.lua index 0eded247..7502cec7 100644 --- a/exp_legacy/module/config/expcore/command_general_parse.lua +++ b/exp_legacy/module/config/expcore/command_general_parse.lua @@ -19,6 +19,7 @@ see ./expcore/commands.lua for more details surface ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -- luacheck:ignore 212/player @@ -37,7 +38,7 @@ end) Commands.add_parse("string-options", function(input, player, reject, options) if not input then return end -- nil check - local option = _C.auto_complete(options, input) + local option = ExpUtil.auto_complete(options, input) return option or reject{ "expcore-commands.reject-string-options", table.concat(options, ", ") } end) diff --git a/exp_legacy/module/config/expcore/command_role_parse.lua b/exp_legacy/module/config/expcore/command_role_parse.lua index ce23f053..6dedd8de 100644 --- a/exp_legacy/module/config/expcore/command_role_parse.lua +++ b/exp_legacy/module/config/expcore/command_role_parse.lua @@ -7,9 +7,10 @@ player-role-alive ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles -local auto_complete = _C.auto_complete --- @dep expcore.common +local auto_complete = ExpUtil.auto_complete --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_general_parse") -- luacheck:ignore 212/player diff --git a/exp_legacy/module/config/gui/player_list_actions.lua b/exp_legacy/module/config/gui/player_list_actions.lua index 18244240..a8c64331 100644 --- a/exp_legacy/module/config/gui/player_list_actions.lua +++ b/exp_legacy/module/config/gui/player_list_actions.lua @@ -5,13 +5,14 @@ -- the key used for the name of the button is the permission name used by the role system; -- @config Player-List +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports local Warnings = require("modules.exp_legacy.modules.control.warnings") --- @dep modules.control.warnings local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail local Colors = require("modules/exp_util/include/color") -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common local SelectedPlayer, SelectedAction local function set_datastores(player, action) @@ -31,7 +32,7 @@ end local function get_action_player_name(player) local selected_player_name = SelectedPlayer:get(player) local selected_player = game.players[selected_player_name] - local selected_player_color = format_chat_player_name(selected_player) + local selected_player_color = format_player_name(selected_player) return selected_player_name, selected_player_color end @@ -98,7 +99,7 @@ local report_player = new_button("utility/spawn_flag", { "player-list.report-pla local function report_player_callback(player, reason) local selected_player_name, selected_player_color = get_action_player_name(player) - local by_player_name_color = format_chat_player_name(player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-report.non-admin", selected_player_color, reason } Roles.print_to_roles_higher("Trainee", { "expcom-report.admin", selected_player_color, by_player_name_color, reason }) Reports.report_player(selected_player_name, player.name, reason) @@ -113,7 +114,7 @@ local warn_player = new_button("utility/spawn_flag", { "player-list.warn-player" local function warn_player_callback(player, reason) local selected_player_name, selected_player_color = get_action_player_name(player) - local by_player_name_color = format_chat_player_name(player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-warnings.received", selected_player_color, by_player_name_color, reason } Warnings.add_warning(selected_player_name, player.name, reason) end @@ -132,7 +133,7 @@ local jail_player = new_button("utility/multiplayer_waiting_icon", { "player-lis local function jail_player_callback(player, reason) local selected_player_name, selected_player_color = get_action_player_name(player) - local by_player_name_color = format_chat_player_name(player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-jail.give", selected_player_color, by_player_name_color, reason } Jail.jail_player(selected_player_name, player.name, reason) end diff --git a/exp_legacy/module/control.lua b/exp_legacy/module/control.lua index 361d37f9..abaa2359 100644 --- a/exp_legacy/module/control.lua +++ b/exp_legacy/module/control.lua @@ -15,12 +15,6 @@ end log("[START] -----| Explosive Gaming Scenario Loader |-----") log("[INFO] Setting up lua environment") --- Require the global overrides -require("modules.exp_legacy.overrides.table") -- Adds alot more functions to the table module -storage.version = require("modules.exp_legacy.overrides.version") -- The current version for exp gaming scenario ---- @diagnostic disable-next-line -_C = require("modules.exp_legacy.expcore.common") -- _C is used to store lots of common functions expected to be used - -- Please go to config/file_loader.lua to edit the files that are loaded log("[INFO] Reading loader config") local files = require("modules.exp_legacy.config._file_loader") diff --git a/exp_legacy/module/expcore/commands.lua b/exp_legacy/module/expcore/commands.lua index 3ed374e6..252f9240 100644 --- a/exp_legacy/module/expcore/commands.lua +++ b/exp_legacy/module/expcore/commands.lua @@ -185,7 +185,8 @@ end) ]] -local player_return, write_json = _C.player_return, _C.write_json --- @dep expcore.common +local ExpUtil = require("modules/exp_util") +local write_json = ExpUtil.write_json --- @dep expcore.common local trace = debug.traceback local Commands = { @@ -203,12 +204,29 @@ local Commands = { authenticators = {}, --- Used to store default functions which are common parse function such as player or number in range parsers = {}, - --- Returns a value to the player, different to success as this does not signal the end of your command - print = player_return, --- The command prototype which stores all command defining functions _prototype = {}, } +local Colours = ExpUtil.color +--- This is copied in so that _C.player_return can be removed +--- Returns a value to the player, different to success as this does not signal the end of your command +function Commands.print(value, colour, player) + colour = type(colour) == "table" and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white + player = player or game.player + local output = ExpUtil.format_any(value) + if player then + player = type(player) == "userdata" and player or game.get_player(player) + if not player then error("Invalid Player given to Commands.print", 2) end + player.print(output, { + color = colour, + sound_path = "utility/scenario_message", + }) + else + rcon.print(output) + end +end + --- Authentication. -- Functions that control who can use commands -- @section auth @@ -658,8 +676,8 @@ return 'Your message has been printed' ]] function Commands.success(value) - if value ~= nil then player_return(value) end - player_return({ "expcore-commands.command-ran" }, "cyan") + if value ~= nil then Commands.print(value) end + Commands.print({ "expcore-commands.command-ran" }, "cyan") return Commands.defines.success end @@ -685,7 +703,7 @@ return Commands.error('The player you selected is offline') ]] function Commands.error(error_message, play_sound) error_message = error_message or "" - player_return({ "expcore-commands.command-fail", error_message }, "orange_red") + Commands.print({ "expcore-commands.command-fail", error_message }, "orange_red") if play_sound ~= false then play_sound = play_sound or "utility/wire_pickup" if game.player then game.player.play_sound{ path = play_sound } end diff --git a/exp_legacy/module/expcore/common.lua b/exp_legacy/module/expcore/common.lua deleted file mode 100644 index cfa14407..00000000 --- a/exp_legacy/module/expcore/common.lua +++ /dev/null @@ -1,832 +0,0 @@ ---[[-- Core Module - Common -- Adds some commonly used functions used in many modules -@core Common -@alias Common -]] - -local Colours = require("modules/exp_util/include/color") -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game - -local Common = {} - ---- Type Checking. --- @section typeCheck - ---[[-- Asserts the argument is of type test_type -@tparam any value the value to be tested -@tparam[opt=nil] string test_type the type to test for if not given then it tests for nil -@treturn boolean is v of type test_type - -@usage-- Check for a string value -local is_string = type_check(value, 'string') - -@usage-- Check for a nil value -local is_nil = type_check(value) - -]] -function Common.type_check(value, test_type) - return test_type and value and type(value) == test_type or not test_type and not value or false -end - ---[[-- Raises an error if the value is of the wrong type -@tparam any value the value that you want to test the type of -@tparam string test_type the type that the value should be -@tparam string error_message the error message that is returned -@tparam number level the level to call the error on (level = 1 is the caller) -@treturn boolean true if no error was called - -@usage-- Raise error if value is not a number -type_error(value, 'number', 'Value must be a number') - -]] -function Common.type_error(value, test_type, error_message, level) - level = level and level + 1 or 2 - return Common.type_check(value, test_type) or error(error_message, level) -end - ---[[-- Asserts the argument is one of type test_types -@param value the variable to check -@param test_types the type as a table of strings -@treturn boolean true if value is one of test_types - -@usage-- Check for a string or table -local is_string_or_table = multi_type_check(value, {'string', 'table'}) - -]] -function Common.multi_type_check(value, test_types) - local vtype = type(value) - for _, arg_type in ipairs(test_types) do - if vtype == arg_type then - return true - end - end - - return false -end - ---[[-- Raises an error if the value is of the wrong type -@tparam any value the value that you want to test the type of -@tparam table test_types the type as a table of strings -@tparam string error_message the error message that is returned -@tparam number level the level to call the error on (level = 1 is the caller) -@treturn boolean true if no error was called - -@usage-- Raise error if value is not a string or table -multi_type_error('foo', {'string', 'table'}, 'Value must be a string or table') - -]] -function Common.multi_type_error(value, test_types, error_message, level) - level = level and level + 1 or 2 - return Common.mult_type_check(value, test_types) or error(error_message, level) -end - ---[[-- Raises an error when the value is the incorrect type, uses a consistent error message format -@tparam any value the value that you want to test the type of -@tparam string test_type the type that the value should be -@tparam number param_number the number param it is -@tparam[opt] string param_name the name of the param -@treturn boolean true if no error was raised - -@usage-- Output: "Bad argument #2 to ""; argument is of type string expected number" -validate_argument_type(value, 'number', 2) - -@usage-- Output: "Bad argument #2 to ""; "repeat_count" is of type string expected number" -validate_argument_type(value, 'number', 2, 'repeat_count') - -]] -function Common.validate_argument_type(value, test_type, param_number, param_name) - if not Common.test_type(value, test_type) then - local function_name = debug.getinfo(2, "n").name or "" - local error_message - if param_name then - error_message = string.format("Bad argument #%d to %q; %q is of type %s expected %s", param_number, function_name, param_name, type(value), test_type) - else - error_message = string.format("Bad argument #%d to %q; argument is of type %s expected %s", param_number, function_name, type(value), test_type) - end - return error(error_message, 3) - end - return true -end - ---[[-- Raises an error when the value is the incorrect type, uses a consistent error message format -@tparam any value the value that you want to test the type of -@tparam string test_types the types that the value should be -@tparam number param_number the number param it is -@tparam[opt] string param_name the name of the param -@treturn boolean true if no error was raised - -@usage-- Output: "Bad argument #2 to ""; argument is of type number expected string or table" -validate_argument_type(value, {'string', 'table'}, 2) - -@usage-- Output: "Bad argument #2 to ""; "player" is of type number expected string or table" -validate_argument_type(value, {'string', 'table'}, 2, 'player') - -]] -function Common.validate_argument_multi_type(value, test_types, param_number, param_name) - if not Common.multi_type_check(value, test_types) then - local function_name = debug.getinfo(2, "n").name or "" - local error_message - if param_name then - error_message = string.format("Bad argument #%2d to %q; %q is of type %s expected %s", param_number, function_name, param_name, type(value), table.concat(test_types, " or ")) - else - error_message = string.format("Bad argument #%2d to %q; argument is of type %s expected %s", param_number, function_name, type(value), table.concat(test_types, " or ")) - end - return error(error_message, 3) - end - return true -end - ---- Will raise an error if called during runtime --- @usage error_if_runtime() -function Common.error_if_runtime() - if package.lifecycle == 8 then - local function_name = debug.getinfo(2, "n").name or "" - error(function_name .. " can not be called during runtime", 3) - end -end - ---- Value Returns. --- @section valueReturns - ---[[-- Tests if a string contains a given substring. -@tparam string s the string to check for the substring -@tparam string contains the substring to test for -@treturn boolean true if the substring was found in the string - -@usage-- Test if a string contains a sub string -local found = string_contains(str, 'foo') - -]] -function Common.string_contains(s, contains) - return s and string.find(s, contains) ~= nil -end - ---[[-- Used to resolve a value that could also be a function returning that value -@tparam any value the value which you want to test is not nil and if it is a function then call the function -@treturn any the value given or returned by value if it is a function - -@usage-- Default value handling --- if default value is not a function then it is returned --- if default value is a function then it is called with the first argument being self -local value = Common.resolve_value(self.defaut_value, self) - -]] -function Common.resolve_value(value, ...) - return value and type(value) == "function" and value(...) or value -end - ---- Converts a varible into its boolean value, nil and false return false --- @treturn boolean the boolean form of the varible --- @usage local bool = cast_bool(var) -function Common.cast_bool(var) - return var and true or false -end - ---- Returns either the second or third argument based on the first argument --- @usage ternary(input_string == 'test', 'Input is test', 'Input is not test') -function Common.ternary(c, t, f) - return c and t or f -end - ---- Returns a string for a number with comma seperators --- @usage comma_value(input_number) -function Common.comma_value(n) -- credit http://richard.warburton.it - local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$") - return left .. (num:reverse():gsub("(%d%d%d)", "%1, "):reverse()) .. right -end - ---[[-- Sets a table element to value while also returning value. -@tparam table tbl to change the element of -@tparam string key the key to set the value of -@tparam any value the value to set the key as -@treturn any the value that was set - -@usage-- Set and return value -local value = set_and_return(players, player.name, player.online_time) - -]] -function Common.set_and_return(tbl, key, value) - tbl[key] = value - return value -end - ---[[-- Writes a table object to a file in json format -@tparam string path the path of the file to write include / to use dir -@tparam table tbl the table that will be converted to a json string and wrote to file - -@usage-- Write a lua table as a json to script-outpt/dump -write_json('dump', tbl) - -]] -function Common.write_json(path, tbl) - game.write_file(path, game.table_to_json(tbl) .. "\n", true, 0) -end - ---[[-- Calls a require that will not error if the file is not found -@usage local file = opt_require('file.not.present') -- will not cause any error -@tparam string path the path that you want to require -@return the returns from that file or nil, error if not loaded - -@usage-- Require a file without causing errors, for when a file might not exist -local Module = opt_require 'expcore.common' - -]] -function Common.opt_require(path) - local success, rtn = pcall(require, path) - if success then - return rtn - else - return nil, rtn - end -end - ---[[-- Returns a desync safe file path for the current file -@tparam[opt=0] number offset the offset in the stack to get, 0 is current file -@treturn string the file path - -@usage-- Get the current file path -local file_path = get_file_path() - -]] -function Common.get_file_path(offset) - offset = offset or 0 - return debug.getinfo(offset + 2, "S").short_src:sub(10, -5) -end - ---[[-- Converts a table to an enum -@tparam table tbl table the that will be converted -@treturn table the new table that acts like an enum - -@usage-- Make an enum -local colors = enum{ - 'red', - 'green', - 'blue' -} - -]] -function Common.enum(tbl) - local rtn = {} - for k, v in pairs(tbl) do - if type(k) ~= "number" then - rtn[v] = k - end - end - - for k, v in pairs(tbl) do - if type(k) == "number" then - table.insert(rtn, v) - end - end - - for k, v in pairs(rtn) do - rtn[v] = k - end - - return rtn -end - ---[[-- Returns the closest match to the input -@tparam table options table a of options for the auto complete -@tparam string input string the input that will be completed -@tparam[opt=false] boolean use_key when true the keys of options will be used as the options -@tparam[opt=false] boolean rtn_key when true the the key will be returned rather than the value -@return the list item found that matches the input - -@usage-- Get the element that includes "foo" -local value = auto_complete(tbl, "foo") - -@usage-- Get the element with a key that includes "foo" -local value = auto_complete(tbl, "foo", true) - -@usage-- Get the key with that includes "foo" -local key = auto_complete(tbl, "foo", true, true) - -]] -function Common.auto_complete(options, input, use_key, rtn_key) - if type(input) ~= "string" then return end - input = input:lower() - for key, value in pairs(options) do - local check = use_key and key or value - if Common.string_contains(string.lower(check), input) then - return rtn_key and key or value - end - end -end - ---- Formatting. --- @section formatting - ---[[-- Returns a valid string with the name of the actor of a command. -@tparam string player_name the name of the player to use rather than server, used only if game.player is nil -@treturn string the name of the current actor - -@usage-- Get the current actor -local player_name = get_actor() - -]] -function Common.get_actor(player_name) - return game.player and game.player.name or player_name or "" -end - ---[[-- Returns a message with valid chat tags to change its colour -@tparam string message the message that will be in the output -@tparam table color a color which contains r, g, b as its keys -@treturn string the message with the color tags included - -@usage-- Use factorio tags to color a chat message -local message = format_chat_colour('Hello, World!', { r=355, g=100, b=100 }) - -]] -function Common.format_chat_colour(message, color) - color = color or Colours.white - local color_tag = "[color=" .. math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3) .. "]" - return string.format("%s%s[/color]", color_tag, message) -end - ---[[-- Returns a message with valid chat tags to change its colour, using localization -@tparam ?string|table message the message that will be in the output -@tparam table color a color which contains r, g, b as its keys -@treturn table the message with the color tags included - -@usage-- Use factorio tags and locale strings to color a chat message -local message = format_chat_colour_localized('Hello, World!', { r=355, g=100, b=100 }) - -]] -function Common.format_chat_colour_localized(message, color) - color = color or Colours.white - color = math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3) - return { "color-tag", color, message } -end - ---[[-- Returns the players name in the players color -@tparam LuaPlayer player the player to use the name and color of -@tparam[opt=false] boolean raw_string when true a string is returned rather than a localized string -@treturn table the players name with tags for the players color - -@usage-- Format a players name using the players color as a string -local message = format_chat_player_name(game.player, true) - -]] -function Common.format_chat_player_name(player, raw_string) - player = Game.get_player_from_any(player) - local player_name = player and player.name or "" - local player_chat_colour = player and player.chat_color or Colours.white - if raw_string then - return Common.format_chat_colour(player_name, player_chat_colour) - else - return Common.format_chat_colour_localized(player_name, player_chat_colour) - end -end - ---[[-- Will return a value of any type to the player/server console, allows colour for in-game players -@tparam any value a value of any type that will be returned to the player or console -@tparam[opt=defines.colour.white] ?defines.color|string colour the colour of the text for the player, ignored when printing to console -@tparam[opt=game.player] LuaPlayer player the player that return will go to, if no game.player then returns to server - -@usage-- Return a value to the current actor, rcon included -player_return('Hello, World!') - -@usage-- Return a value to the current actor, with color -player_return('Hello, World!', 'green') - -@usage-- Return to a player other than the current -player_return('Hello, World!', nil, player) - -]] -function Common.player_return(value, colour, player) - colour = Common.type_check(colour, "table") and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white - player = player or game.player - -- converts the value to a string - local string_return - if Common.type_check(value, "table") or type(value) == "userdata" then - if Common.type_check(value.__self, "userdata") or type(value) == "userdata" then - -- value is userdata - string_return = "Cant Display Userdata" - elseif Common.type_check(value[1], "string") and string.find(value[1], ".+[.].+") and not string.find(value[1], "%s") then - -- value is a locale string - string_return = value - elseif getmetatable(value) ~= nil and not tostring(value):find("table: 0x") then - -- value has a tostring meta method - string_return = tostring(value) - else - -- value is a table - string_return = table.inspect(value, { depth = 5, indent = " ", newline = "\n" }) - end - elseif Common.type_check(value, "function") then - -- value is a function - string_return = "Cant Display Functions" - else - string_return = tostring(value) - end - -- returns to the player or the server - if player then - -- allows any valid player identifier to be used - player = Game.get_player_from_any(player) - if not player then error("Invalid Player given to player_return", 2) end - -- plays a nice sound that is different to normal message sound - player.play_sound{ path = "utility/scenario_message" } - player.print(string_return, colour) - else - rcon.print(string_return) - end -end - ---[[-- Formats tick into a clean format, denominations from highest to lowest --- time will use : separates --- when a denomination is false it will overflow into the next one -@tparam number ticks the number of ticks that represents a time -@tparam table options table a of options to use for the format -@treturn string a locale string that can be used - -@usage-- Output: "0h 5m" -local time = format_time(18000, { hours=true, minutes=true, string=true }) - -@usage-- Output: "0 hours and 5 minutes" -local time = format_time(18000, { hours=true, minutes=true, string=true, long=true }) - -@usage-- Output: "00:05:00" -local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true }) - -@usage-- Output: "--:--:--" -local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true, null=true }) - -]] -function Common.format_time(ticks, options) - -- Sets up the options - options = options or { - days = false, - hours = true, - minutes = true, - seconds = false, - long = false, - time = false, - string = false, - null = false, - } - -- Basic numbers that are used in calculations - local max_days, max_hours, max_minutes, max_seconds = ticks / 5184000, ticks / 216000, ticks / 3600, ticks / 60 - local days, hours = max_days, max_hours - math.floor(max_days) * 24 - local minutes, seconds = max_minutes - math.floor(max_hours) * 60, max_seconds - math.floor(max_minutes) * 60 - -- Handles overflow of disabled denominations - local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = - math.floor(days) --[[@as string | number | table]], - math.floor(hours) --[[@as string | number | table]], - math.floor(minutes) --[[@as string | number | table]], - math.floor(seconds) --[[@as string | number | table]] - if not options.days then - rtn_hours = rtn_hours + rtn_days * 24 - end - if not options.hours then - rtn_minutes = rtn_minutes + rtn_hours * 60 - end - if not options.minutes then - rtn_seconds = rtn_seconds + rtn_minutes * 60 - end - -- Creates the null time format, does not work with long - if options.null and not options.long then - rtn_days = "--" - rtn_hours = "--" - rtn_minutes = "--" - rtn_seconds = "--" - end - -- Format options - local suffix = "time-symbol-" - local suffix_2 = "-short" - if options.long then - suffix = "" - suffix_2 = "" - end - local div = options.string and " " or "time-format.simple-format-tagged" - if options.time then - div = options.string and ":" or "time-format.simple-format-div" - -- suffix = false -- Can't get the types to work - end - -- Adds formatting - if not options.time then -- Can't get the types to work - if options.string then - -- format it as a string - local long = suffix == "" - rtn_days = long and rtn_days .. " days" or rtn_days .. "d" - rtn_hours = long and rtn_hours .. " hours" or rtn_hours .. "h" - rtn_minutes = long and rtn_minutes .. " minutes" or rtn_minutes .. "m" - rtn_seconds = long and rtn_seconds .. " seconds" or rtn_seconds .. "s" - else - rtn_days = { suffix .. "days" .. suffix_2, rtn_days } - rtn_hours = { suffix .. "hours" .. suffix_2, rtn_hours } - rtn_minutes = { suffix .. "minutes" .. suffix_2, rtn_minutes } - rtn_seconds = { suffix .. "seconds" .. suffix_2, rtn_seconds } - end - elseif not options.null then - -- weather string or not it has same format - rtn_days = string.format("%02d", rtn_days) - rtn_hours = string.format("%02d", rtn_hours) - rtn_minutes = string.format("%02d", rtn_minutes) - rtn_seconds = string.format("%02d", rtn_seconds) - end - -- The final return is construed - local rtn - local append = function(dom, value) - if dom and options.string then - rtn = rtn and rtn .. div .. value or value - elseif dom then - rtn = rtn and { div, rtn, value } or value - end - end - append(options.days, rtn_days) - append(options.hours, rtn_hours) - append(options.minutes, rtn_minutes) - append(options.seconds, rtn_seconds) - return rtn -end - ---- Factorio. --- @section factorio - ---[[-- Copies items to the position and stores them in the closest entity of the type given --- Copies the items by prototype name, but keeps them in the original inventory -@tparam table items items which are to be added to the chests, an array of LuaItemStack -@tparam[opt=navies] LuaSurface surface the surface that the items will be copied to -@tparam[opt={0, 0}] table position the position that the items will be copied to {x=100, y=100} -@tparam[opt=32] number radius the radius in which the items are allowed to be placed -@tparam[opt=iron-chest] string chest_type the chest type that the items should be copied into -@treturn LuaEntity the last chest that had items inserted into it - -@usage-- Copy all the items in a players inventory and place them in chests at {0, 0} -copy_items_stack(game.player.get_main_inventory().get_contents()) - -]] -function Common.copy_items_stack(items, surface, position, radius, chest_type) - chest_type = chest_type or "iron-chest" - surface = surface or game.surfaces[1] - if position and type(position) ~= "table" then return end - if type(items) ~= "table" then return end - -- Finds all entities of the given type - local p = position or { x = 0, y = 0 } - local r = radius or 32 - local entities = surface.find_entities_filtered{ area = { { p.x - r, p.y - r }, { p.x + r, p.y + r } }, name = chest_type } or {} - local count = #entities - local current = 1 - -- Makes a new empty chest when it is needed - local function make_new_chest() - local pos = surface.find_non_colliding_position(chest_type, position, 32, 1) - local chest = surface.create_entity{ name = chest_type, position = pos, force = "neutral" } - table.insert(entities, chest) - count = count + 1 - return chest - end - -- Function used to round robin the items into all chests - local function next_chest(item) - local chest = entities[current] - if count == 0 then return make_new_chest() end - if chest.get_inventory(defines.inventory.chest).can_insert(item) then - -- If the item can be inserted then the chest is returned - current = current + 1 - if current > count then current = 1 end - return chest - else - -- Other wise it is removed from the list - table.remove(entities, current) - count = count - 1 - end - end - -- Inserts the items into the chests - local last_chest - for i = 1, #items do - local item = items[i] - if item.valid_for_read then - local chest = next_chest(item) - if not chest or not chest.valid then return error(string.format("Cant move item %s to %s{%s, %s} no valid chest in radius", item.name, surface.name, p.x, p.y)) end - chest.insert(item) - last_chest = chest - end - end - - return last_chest -end - ---[[-- Moves items to the position and stores them in the closest entity of the type given --- Differs from move_items by accepting a table of LuaItemStack and transferring them into the inventory - not copying -@tparam table items items which are to be added to the chests, an array of LuaItemStack -@tparam[opt=navies] LuaSurface surface the surface that the items will be moved to -@tparam[opt={0, 0}] table position the position that the items will be moved to {x=100, y=100} -@tparam[opt=32] number radius the radius in which the items are allowed to be placed -@tparam[opt=iron-chest] string chest_type the chest type that the items should be moved into -@treturn LuaEntity the last chest that had items inserted into it - -@usage-- Copy all the items in a players inventory and place them in chests at {0, 0} -move_items_stack(game.player.get_main_inventory()) - -]] -function Common.move_items_stack(items, surface, position, radius, chest_type) - chest_type = chest_type or "steel-chest" - surface = surface or game.surfaces[1] - - if position and type(position) ~= "table" then - return - end - - if type(items) ~= "table" then - return - end - - -- Finds all entities of the given type - local p = position or { x = 0, y = 0 } - local r = radius or 32 - local entities = surface.find_entities_filtered{ area = { { p.x - r, p.y - r }, { p.x + r, p.y + r } }, name = { chest_type, "iron-chest" } } or {} - local count = #entities - local current = 0 - local last_entity = nil - - -- ipairs does not work on LuaInventory - for i = 1, #items do - local item = items[i] - if item.valid_for_read then - local inserted = false - - -- Attempt to insert the items - for j = 1, count do - local entity = entities[((current + j - 1) % count) + 1] - - if entity.can_insert(item) then - last_entity = entity - current = current + 1 - entity.insert(item) - inserted = true - break - end - end - - -- If it was not inserted then a new entity is needed - if not inserted then - --[[ - if not options.allow_creation then - error('Unable to insert items into a valid entity, consider enabling allow_creation') - end - - if options.name == nil then - error('Name must be provided to allow creation of new entities') - end - - if options.position then - pos = surface.find_non_colliding_position(chest_type, p, r, 1, true) - - elseif options.area then - pos = surface.find_non_colliding_position_in_box(chest_type, options.area, 1, true) - - else - pos = surface.find_non_colliding_position(chest_type, {0,0}, 0, 1, true) - end - ]] - - local pos = surface.find_non_colliding_position(chest_type, p, r, 1, true) - last_entity = surface.create_entity{ name = chest_type, position = pos, force = "neutral" } - - count = count + 1 - entities[count] = last_entity - - last_entity.insert(item) - end - end - end - - --[[ - -- Makes a new empty chest when it is needed - local function make_new_chest() - local pos = surface.find_non_colliding_position(chest_type, position, 32, 1) - local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'} - table.insert(entities, chest) - count = count + 1 - - return chest - end - - -- Function used to round robin the items into all chests - local function next_chest(item) - local chest = entities[current] - - if count == 0 then - return make_new_chest() - end - - if chest.get_inventory(defines.inventory.chest).can_insert(item) then - -- If the item can be inserted then the chest is returned - current = current + 1 - if current > count then - current = 1 - end - - return chest - - else - -- Other wise it is removed from the list - table.remove(entities, current) - count = count - 1 - end - end - - -- Inserts the items into the chests - local last_chest - - for i=1,#items do - local item = items[i] - - if item.valid_for_read then - local chest = next_chest(item) - - if not chest or not chest.valid then - return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) - end - - local empty_stack = chest.get_inventory(defines.inventory.chest).find_empty_stack(item.name) - - if not empty_stack then - return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) - end - - empty_stack.transfer_stack(item) - last_chest = chest - end - end - return last_chest - ]] - - return last_entity -end - ---[[-- Prints a colored value on a location, color is based on the value. -nb: src is below but the gradent has been edited -https://github.com/Refactorio/RedMew/blob/9184b2940f311d8c9c891e83429fc57ec7e0c4a2/map_gen/maps/diggy/debug.lua#L31 -@tparam number value the value to show must be between -1 and 1, scale can be used to achive this -@tparam LuaSurface surface the surface to palce the value on -@tparam table position {x, y} the possition to palce the value at -@tparam[opt=1] number scale how much to scale the colours by -@tparam[opt=0] number offset the offset in the +x +y direction -@tparam[opt=false] boolean immutable if immutable, only set, never do a surface lookup, values never change - -@usage-- Place a 0 at {0, 0} -print_grid_value(0, game.player.surface, { x=0, y=0 }) - -]] -function Common.print_grid_value(value, surface, position, scale, offset, immutable) - local is_string = type(value) == "string" - local color = Colours.white - local text = value - - if type(immutable) ~= "boolean" then - immutable = false - end - - if not is_string then - scale = scale or 1 - offset = offset or 0 - position = { x = position.x + offset, y = position.y + offset } - local r = math.clamp(-value / scale, 0, 1) - local g = math.clamp(1 - math.abs(value) / scale, 0, 1) - local b = math.clamp(value / scale, 0, 1) - - color = { r = r, g = g, b = b } - - -- round at precision of 2 - text = math.floor(100 * value) * 0.01 - - if (0 == text) then - text = "0.00" - end - end - - if not immutable then - local text_entity = surface.find_entity("flying-text", position) - - if text_entity then - text_entity.text = text - text_entity.color = color - return - end - end - - surface.create_entity{ - name = "flying-text", - color = color, - text = text, - position = position, - }.active = false -end - ---[[-- Clears all flying text entities on a surface -@tparam LuaSurface surface the surface to clear - -@usage-- Remove all flying text on the surface -clear_flying_text(game.player.surface) - -]] -function Common.clear_flying_text(surface) - local entities = surface.find_entities_filtered{ name = "flying-text" } - for _, entity in pairs(entities) do - if entity and entity.valid then - entity.destroy() - end - end -end - -return Common diff --git a/exp_legacy/module/expcore/external.lua b/exp_legacy/module/expcore/external.lua index 95375cbd..e5e7b6dc 100644 --- a/exp_legacy/module/expcore/external.lua +++ b/exp_legacy/module/expcore/external.lua @@ -129,7 +129,7 @@ end --[[-- Connect a player to the given server @tparam LuaPlayer player The player that you want to request to join a different server @tparam string server_id The internal id of the server to connect to, can also be any address but this will show Unknown Server -@tparam[opt=false] boolean self_requested If the player requested the join them selfs, this will hide the message about being asked to switch +@tparam[opt=false] boolean self_requested If the player requested the join themself, this will hide the message about being asked to switch @usage-- Request that a player joins a different server External.request_connection(player, 'eu-01') diff --git a/exp_legacy/module/expcore/gui/_require.lua b/exp_legacy/module/expcore/gui/_require.lua index 1b0c47af..3bf672ea 100644 --- a/exp_legacy/module/expcore/gui/_require.lua +++ b/exp_legacy/module/expcore/gui/_require.lua @@ -121,6 +121,7 @@ end) ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui.prototype") require("modules.exp_legacy.expcore.gui.helper_functions") require("modules.exp_legacy.expcore.gui.core_defines") @@ -128,8 +129,8 @@ require("modules.exp_legacy.expcore.gui.top_flow") require("modules.exp_legacy.expcore.gui.left_flow") require("modules.exp_legacy.expcore.gui.defines") -local Roles = _C.opt_require("modules.exp_legacy.expcore.roles") -local Event = _C.opt_require("modules/exp_legacy/utils/event") +local Roles = ExpUtil.optional_require("modules.exp_legacy.expcore.roles") +local Event = ExpUtil.optional_require("modules/exp_legacy/utils/event") if Roles and Event then Event.add(Roles.events.on_role_assigned, function(e) diff --git a/exp_legacy/module/expcore/gui/left_flow.lua b/exp_legacy/module/expcore/gui/left_flow.lua index 460c5ef3..e292b427 100644 --- a/exp_legacy/module/expcore/gui/left_flow.lua +++ b/exp_legacy/module/expcore/gui/left_flow.lua @@ -3,6 +3,7 @@ @module Gui ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui.prototype") local mod_gui = require "mod-gui" @@ -38,7 +39,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() if not self.name then error("Elements for the top flow must have a static name") end self.open_on_join = open_on_join or false table.insert(Gui.left_elements, self) diff --git a/exp_legacy/module/expcore/gui/prototype.lua b/exp_legacy/module/expcore/gui/prototype.lua index 0f4e3936..596a9157 100644 --- a/exp_legacy/module/expcore/gui/prototype.lua +++ b/exp_legacy/module/expcore/gui/prototype.lua @@ -3,6 +3,7 @@ @module Gui ]] +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Gui = { @@ -107,7 +108,7 @@ end) ]] function Gui.element(element_define) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() -- Set the metatable to allow access to register events local element = setmetatable({}, Gui._mt_element) @@ -182,7 +183,7 @@ end) ]] function Gui._prototype_element:style(style_define) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() -- Add the definition function if type(style_define) == "table" then Gui.debug_info[self.uid].style = style_define @@ -205,7 +206,7 @@ end @treturn table the element define is returned to allow for event handlers to be registered ]] function Gui._prototype_element:static_name(name) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() if name == Gui.unique_static_name then self.name = "ExpGui_" .. tostring(self.uid) else @@ -255,7 +256,7 @@ end) ]] function Gui._prototype_element:on_event(event_name, handler) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() table.insert(Gui.debug_info[self.uid].events, event_name) Gui.events[event_name] = event_name self[event_name] = handler diff --git a/exp_legacy/module/expcore/gui/top_flow.lua b/exp_legacy/module/expcore/gui/top_flow.lua index c6284f12..04109616 100644 --- a/exp_legacy/module/expcore/gui/top_flow.lua +++ b/exp_legacy/module/expcore/gui/top_flow.lua @@ -3,6 +3,7 @@ @module Gui ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui.prototype") local mod_gui = require "mod-gui" --- @dep mod-gui @@ -75,7 +76,7 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() if not self.name then error("Elements for the top flow must have a static name") end self.authenticator = authenticator or true table.insert(Gui.top_elements, self) diff --git a/exp_legacy/module/expcore/permission_groups.lua b/exp_legacy/module/expcore/permission_groups.lua index fd74fc6f..9181e614 100644 --- a/exp_legacy/module/expcore/permission_groups.lua +++ b/exp_legacy/module/expcore/permission_groups.lua @@ -23,8 +23,7 @@ Permission_Groups.new_group('Restricted') -- this defines a new group called "Re ]] -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game -local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event +local Event = require("modules/exp_legacy/utils/event") local Async = require("modules/exp_util/async") local PermissionsGroups = { @@ -91,8 +90,6 @@ local group = Groups.get_group_from_player(game.player) ]] function PermissionsGroups.get_group_from_player(player) - player = Game.get_player_from_any(player) - if not player then return end local group = player.permission_group if group then return PermissionsGroups.groups[group.name] @@ -125,7 +122,6 @@ Groups.set_player_group(game.player, 'Admin') ]] function PermissionsGroups.set_player_group(player, group) - player = Game.get_player_from_any(player) group = PermissionsGroups.get_group_by_name(group) if not group or not player then return false end group:add_player(player) @@ -285,7 +281,6 @@ group:add_player(game.player) ]] function PermissionsGroups._prototype:add_player(player) - player = Game.get_player_from_any(player) local group = self:get_raw() if not group or not player then return false end add_to_permission_group_async(group, player) @@ -301,7 +296,6 @@ group:remove_player(game.player) ]] function PermissionsGroups._prototype:remove_player(player) - player = Game.get_player_from_any(player) local group = self:get_raw() if not group or not player then return false end remove_from_permission_group_async(group, player) diff --git a/exp_legacy/module/expcore/roles.lua b/exp_legacy/module/expcore/roles.lua index 0f0a4c26..a0e235a7 100644 --- a/exp_legacy/module/expcore/roles.lua +++ b/exp_legacy/module/expcore/roles.lua @@ -108,13 +108,14 @@ Roles.define_role_order{ ]] +local ExpUtil = require("modules/exp_util") local Async = require("modules/exp_util/async") local Storage = require("modules/exp_util/storage") -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game -local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event -local Groups = require("modules.exp_legacy.expcore.permission_groups") --- @dep expcore.permission_groups -local Colours = require("modules/exp_util/include/color") -local write_json = _C.write_json --- @dep expcore.common +local Event = require("modules/exp_legacy/utils/event") +local Groups = require("modules.exp_legacy.expcore.permission_groups") + +local Colours = ExpUtil.color +local write_json = ExpUtil.write_json local Roles = { _prototype = {}, @@ -319,7 +320,6 @@ local roles = Roles.get_player_roles(game.player) ]] function Roles.get_player_roles(player) - player = Game.get_player_from_any(player) if not player then return { Roles.config.roles[Roles.config.internal.root] } end local roles = Roles.config.players[player.name] or {} local default = Roles.config.roles[Roles.config.internal.default] @@ -370,9 +370,8 @@ Roles.assign_player('Cooldude2606', 'Moderator', nil, true) ]] function Roles.assign_player(player, roles, by_player_name, skip_checks, silent) - local valid_player = Game.get_player_from_any(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) if not skip_checks and not valid_player then return end - if not player then return end -- Convert the roles into a table (allows for optional array) if type(roles) ~= "table" or roles.name then @@ -387,7 +386,7 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent) end -- If the player has a role that needs to defer the role changes, save the roles that need to be assigned later into a table - if valid_player and Roles.player_has_flag(player, "defer_role_changes") then + if valid_player and Roles.player_has_flag(valid_player, "defer_role_changes") 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] @@ -432,7 +431,7 @@ Roles.unassign_player('Cooldude2606', 'Moderator', nil, true) ]] function Roles.unassign_player(player, roles, by_player_name, skip_checks, silent) - local valid_player = Game.get_player_from_any(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) if not skip_checks and not valid_player then return end if not player then return end @@ -626,7 +625,7 @@ Roles.define_role_order{ ]] function Roles.define_role_order(order) -- Clears and then rebuilds the order table - _C.error_if_runtime() + ExpUtil.assert_not_runtime() Roles.config.order = {} local done = {} for index, role in ipairs(order) do @@ -711,7 +710,7 @@ local role = Roles.new_role('Moderator', 'Mod') ]] function Roles.new_role(name, short_hand) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() if Roles.config.roles[name] then return error("Role name is non unique") end local role = setmetatable({ name = name, @@ -885,7 +884,7 @@ role:set_permission_group('Admin') ]] function Roles._prototype:set_permission_group(name, use_factorio_api) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() if use_factorio_api then self.permission_group = { true, name } else @@ -906,7 +905,7 @@ role:set_parent('Guest') ]] function Roles._prototype:set_parent(role) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() self.parent = role role = Roles.get_role_from_any(role) if not role then return self end @@ -926,7 +925,7 @@ end) ]] function Roles._prototype:set_auto_assign_condition(callback) - _C.error_if_runtime() + ExpUtil.assert_not_runtime() self.auto_assign_condition = true Roles.config.auto_assign[self.name] = callback return self @@ -972,7 +971,7 @@ role:add_player(game.player) ]] function Roles._prototype:add_player(player, skip_check, skip_event) - local valid_player = Game.get_player_from_any(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) -- Default role cant have players added or removed if self.name == Roles.config.internal.default then return end -- Check the player is valid, can be skipped but a name must be given @@ -1013,7 +1012,7 @@ role:remove_player(game.player) ]] function Roles._prototype:remove_player(player, skip_check, skip_event) - local valid_player = Game.get_player_from_any(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) -- Default role cant have players added or removed if self.name == Roles.config.internal.default then return end -- Check the player is valid, can be skipped but a name must be given diff --git a/exp_legacy/module/modules/addons/chat-popups.lua b/exp_legacy/module/modules/addons/chat-popups.lua index f636993d..ef771697 100644 --- a/exp_legacy/module/modules/addons/chat-popups.lua +++ b/exp_legacy/module/modules/addons/chat-popups.lua @@ -2,12 +2,10 @@ -- also displays a ping above users who are named in the message -- @addon Chat-Popups -local FloatingText = require("modules/exp_util/floating_text") +local FlyingText = require("modules/exp_util/flying_text") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.popup_messages") --- @dep config.popup_messages -local send_text = FloatingText.print_as_player -- (player, text) - Event.add(defines.events.on_console_chat, function(event) if not event.player_index or event.player_index < 1 then return end local player = game.players[event.player_index] @@ -18,7 +16,10 @@ Event.add(defines.events.on_console_chat, function(event) -- Sends the message as text above them if config.show_player_messages then - send_text(player, { "chat-popup.message", player.name, event.message }) + FlyingText.create_as_player{ + target_player = player, + text = { "chat-popup.message", player.name, event.message }, + } end if not config.show_player_mentions then return end @@ -30,7 +31,10 @@ Event.add(defines.events.on_console_chat, function(event) for _, mentioned_player in pairs(game.connected_players) do if mentioned_player.index ~= player.index then if search_string:find(mentioned_player.name:lower(), 1, true) then - send_text(mentioned_player, { "chat-popup.ping", player.name }) + FlyingText.create_as_player{ + target_player = mentioned_player, + text = { "chat-popup.ping", player.name }, + } end end end diff --git a/exp_legacy/module/modules/addons/damage-popups.lua b/exp_legacy/module/modules/addons/damage-popups.lua index cdc430c6..4201900d 100644 --- a/exp_legacy/module/modules/addons/damage-popups.lua +++ b/exp_legacy/module/modules/addons/damage-popups.lua @@ -2,7 +2,7 @@ -- also shows player health when a player is attacked -- @addon Damage-Popups -local FloatingText = require("modules/exp_util/floating_text") +local FlyingText = require("modules/exp_util/flying_text") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.popup_messages") --- @dep config.popup_messages @@ -31,11 +31,10 @@ Event.add(defines.events.on_entity_damaged, function(event) -- Outputs the message as floating text if message then - FloatingText.print( - entity.surface, - position, - message, - text_colour - ) + FlyingText.create{ + text = message, + position = position, + color = text_colour, + } end end) diff --git a/exp_legacy/module/modules/addons/death-logger.lua b/exp_legacy/module/modules/addons/death-logger.lua index 94baec8d..f5458be7 100644 --- a/exp_legacy/module/modules/addons/death-logger.lua +++ b/exp_legacy/module/modules/addons/death-logger.lua @@ -1,10 +1,10 @@ --- Makes markers on the map where places have died and reclaims items if not recovered -- @addon Death-Logger +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Storage = require("modules/exp_util/storage") local config = require("modules.exp_legacy.config.death_logger") --- @dep config.death_logger -local format_time, move_items = _C.format_time, _C.move_items_stack --- @dep expcore.common -- Max amount of ticks a corpse can be alive local corpse_lifetime = 60 * 60 * 15 @@ -17,12 +17,14 @@ Storage.register(deaths, function(tbl) deaths = tbl end) +local map_tag_time_format = ExpUtil.format_time_factory{ format = "short", hours = true, minutes = true } + --- Creates a new death marker and saves it to the given death local function create_map_tag(death) local player = game.players[death.player_name] local message = player.name .. " died" if config.include_time_of_death then - local time = format_time(death.time_of_death, { hours = true, minutes = true, string = true }) + local time = map_tag_time_format(death.time_of_death) message = message .. " at " .. time end death.tag = player.force.add_chart_tag(player.surface, { @@ -60,14 +62,21 @@ local function check_map_tags() end -- when a player dies a new death is added to the records and a map marker is made +--- @param event EventData.on_player_died Event.add(defines.events.on_player_died, function(event) local player = game.players[event.player_index] local corpse = player.surface.find_entity("character-corpse", player.position) if not corpse or not corpse.valid then return end if config.use_chests_as_bodies then - local items = corpse.get_inventory(defines.inventory.character_corpse) - local chest = move_items(items, corpse.surface, corpse.position) - chest.destructible = false + local inventory = assert(corpse.get_inventory(defines.inventory.character_corpse)) + local chest = ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = corpse.surface, + position = corpse.position, + name = "iron-chest", + allow_creation = true, + } + corpse.destroy() corpse = chest end @@ -139,10 +148,16 @@ if config.show_map_markers then end if config.auto_collect_bodies then + --- @param event EventData.on_character_corpse_expired Event.add(defines.events.on_character_corpse_expired, function(event) local corpse = event.corpse - local items = corpse.get_inventory(defines.inventory.character_corpse) - move_items(items, corpse.surface, { x = 0, y = 0 }) + local inventory = assert(corpse.get_inventory(defines.inventory.character_corpse)) + ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = corpse.surface, + name = "iron-chest", + allow_creation = true, + } end) end diff --git a/exp_legacy/module/modules/addons/deconlog.lua b/exp_legacy/module/modules/addons/deconlog.lua index 2f78ca0e..c47f6b43 100644 --- a/exp_legacy/module/modules/addons/deconlog.lua +++ b/exp_legacy/module/modules/addons/deconlog.lua @@ -1,20 +1,21 @@ --- Log certain actions into a file when events are triggered -- @addon Deconlog +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles -local format_time = _C.format_time --- @dep expcore.common local format_number = require("util").format_number --- @dep util local config = require("modules.exp_legacy.config.deconlog") --- @dep config.deconlog local filepath = "log/decon.log" +local seconds_time_format = ExpUtil.format_time_factory{ format = "short", hours = true, minutes = true, seconds = true } local function add_log(data) game.write_file(filepath, data .. "\n", true, 0) -- write data end local function get_secs() - return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true }) + return seconds_time_format(game.tick) end local function pos_to_string(pos) diff --git a/exp_legacy/module/modules/addons/discord-alerts.lua b/exp_legacy/module/modules/addons/discord-alerts.lua index 75e50976..23bde648 100644 --- a/exp_legacy/module/modules/addons/discord-alerts.lua +++ b/exp_legacy/module/modules/addons/discord-alerts.lua @@ -1,12 +1,14 @@ --- Sends alert messages to our discord server when certain events are triggered -- @addon Discord-Alerts +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Colors = require("modules/exp_util/include/color") -local write_json, format_time = _C.write_json, _C.format_time --- @dep expcore.common local config = require("modules.exp_legacy.config.discord_alerts") --- @dep config.discord_alerts +local write_json = ExpUtil.write_json -local playtime_format = { hours = true, minutes = true, short = true, string = true } +local playtime_format = ExpUtil.format_time_factory{ format = "short", hours = true, minutes = true, seconds = true } +local emit_event_time_format = ExpUtil.format_time_factory{ format = "short", hours = true, minutes = true } local function append_playtime(player_name) if not config.show_playtime then @@ -19,7 +21,7 @@ local function append_playtime(player_name) return player_name end - return player.name .. " (" .. format_time(player.online_time, playtime_format) .. ")" + return player.name .. " (" .. playtime_format(player.online_time) .. ")" end local function get_player_name(event) @@ -48,7 +50,7 @@ local function emit_event(args) end local tick = args.tick or game.tick - local tick_formatted = format_time(tick, { days = false, hours = true, minutes = true, short = true, string = true }) + local tick_formatted = emit_event_time_format(tick) local players_online = 0 local admins_online = 0 diff --git a/exp_legacy/module/modules/addons/inventory-clear.lua b/exp_legacy/module/modules/addons/inventory-clear.lua index 79a469fc..60c11e90 100644 --- a/exp_legacy/module/modules/addons/inventory-clear.lua +++ b/exp_legacy/module/modules/addons/inventory-clear.lua @@ -1,15 +1,19 @@ --- Will move players items to spawn when they are banned or kicked, option to clear on leave -- @addon Inventory-Clear +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local events = require("modules.exp_legacy.config.inventory_clear") --- @dep config.inventory_clear -local move_items_stack = _C.move_items_stack --- @dep expcore.common local function clear_items(event) local player = game.players[event.player_index] - local inv = player.get_main_inventory() --- @cast inv -nil - move_items_stack(inv) - inv.clear() + local inventory = assert(player.get_main_inventory()) + ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = game.surfaces[1], + name = "iron-chest", + allow_creation = true, + } end for _, event_name in ipairs(events) do Event.add(event_name, clear_items) end diff --git a/exp_legacy/module/modules/addons/miner.lua b/exp_legacy/module/modules/addons/miner.lua index a691e473..3b18a35f 100644 --- a/exp_legacy/module/modules/addons/miner.lua +++ b/exp_legacy/module/modules/addons/miner.lua @@ -110,7 +110,7 @@ local function miner_check(entity) local entities = es.find_entities_filtered{ area = { { ep.x - r, ep.y - r }, { ep.x + r, ep.y + r } }, type = { "mining-drill", "pipe", "pipe-to-ground" } } local entities_t = es.find_entities_filtered{ area = { { ep.x - r, ep.y - r }, { ep.x + r, ep.y + r } }, ghost_type = { "pipe", "pipe-to-ground" } } - table.array_insert(entities, entities_t) + table.insert_array(entities, entities_t) for _, e in pairs(entities) do if (e.position.x > ep.x) and (e.position.y == ep.y) then diff --git a/exp_legacy/module/modules/addons/nukeprotect.lua b/exp_legacy/module/modules/addons/nukeprotect.lua index e1ed1b6e..b820a63f 100644 --- a/exp_legacy/module/modules/addons/nukeprotect.lua +++ b/exp_legacy/module/modules/addons/nukeprotect.lua @@ -1,26 +1,36 @@ --- Disable new players from having certain items in their inventory, most commonly nukes -- @addon Nukeprotect +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local config = require("modules.exp_legacy.config.nukeprotect") --- @dep config.nukeprotect -local move_items_stack = _C.move_items_stack --- @dep expcore.common +--- Check all items in the given inventory +---@param player LuaPlayer +---@param type defines.inventory local function check_items(player, type) -- if the player has perms to be ignored, then they should be if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end -- if the players if config.ignore_admins and player.admin then return end - local inventory = player.get_inventory(type) + local items = {} --- @type LuaItemStack[] + local inventory = assert(player.get_inventory(type)) for i = 1, #inventory do local item = inventory[i] if item.valid and item.valid_for_read and config[tostring(type)][item.name] then player.print{ "nukeprotect.found", { "item-name." .. item.name } } - -- insert the items into the table so all items are transferred at once - move_items_stack{ item } + items[#items + 1] = item end end + + ExpUtil.move_items_to_surface{ + items = items, + surface = player.surface, + allow_creation = true, + name = "iron-chest", + } end for _, inventory in ipairs(config.inventories) do diff --git a/exp_legacy/module/modules/addons/protection-jail.lua b/exp_legacy/module/modules/addons/protection-jail.lua index 8e9fec80..7af19afe 100644 --- a/exp_legacy/module/modules/addons/protection-jail.lua +++ b/exp_legacy/module/modules/addons/protection-jail.lua @@ -1,11 +1,12 @@ --- When a player triggers protection multiple times they are automatically jailed -- @addon protection-jail +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Storage = require("modules/exp_util/storage") --- @dep utils.global local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail local Protection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common --- Stores how many times the repeat violation was triggered local repeat_count = {} @@ -29,7 +30,7 @@ Event.add(Protection.events.on_repeat_violation, function(event) return end - local player_name_color = format_chat_player_name(player) + local player_name_color = format_player_name(player) Jail.jail_player(player, "", "Removed too many protected entities, please wait for a moderator.") game.print{ "protection-jail.jail", player_name_color } end) diff --git a/exp_legacy/module/modules/addons/report-jail.lua b/exp_legacy/module/modules/addons/report-jail.lua index e0fc4ca8..91312264 100644 --- a/exp_legacy/module/modules/addons/report-jail.lua +++ b/exp_legacy/module/modules/addons/report-jail.lua @@ -1,10 +1,11 @@ --- When a player is reported, the player is automatically jailed if the combined playtime of the reporters exceeds the reported player -- @addon report-jail +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common --- Returns the playtime of the reporter. Used when calculating the total playtime of all reporters local function reporter_playtime(_, by_player_name, _) @@ -21,7 +22,7 @@ Event.add(Reports.events.on_player_reported, function(event) -- player less than 30 min if (Reports.count_reports(player) > 1) and (total_playtime > math.max(player.online_time * 2, 108000)) then - local player_name_color = format_chat_player_name(player) + local player_name_color = format_player_name(player) Jail.jail_player(player, "", "Reported by too many players, please wait for a moderator.") game.print{ "report-jail.jail", player_name_color } end diff --git a/exp_legacy/module/modules/addons/scorched-earth.lua b/exp_legacy/module/modules/addons/scorched-earth.lua index 231d2d29..d4568152 100644 --- a/exp_legacy/module/modules/addons/scorched-earth.lua +++ b/exp_legacy/module/modules/addons/scorched-earth.lua @@ -2,8 +2,6 @@ -- @addon Scorched-Earth local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event -local Storage = require("modules/exp_util/storage") -local print_grid_value, clear_flying_text = _C.print_grid_value, _C.clear_flying_text --- @dep expcore.common local config = require("modules.exp_legacy.config.scorched_earth") --- @dep config.scorched_earth -- Loops over the config and finds the wile which has the highest value for strength @@ -14,12 +12,6 @@ for _, strength in pairs(config.strengths) do end end --- Used for debugging the degrade chances -local debug_players = {} -Storage.register(debug_players, function(tbl) - debug_players = tbl -end) - -- Will degrade a tile down to the next tile when called local function degrade(surface, position) local tile = surface.get_tile(position) @@ -80,19 +72,6 @@ local function get_tile_strength(surface, position) return strength / 9 end --- Same as get_tile_strength but returns to a in game text rather than as a value -local function debug_get_tile_strength(surface, position) - for x = -3, 3 do -- x loop - local px = position.x + x - for y = -3, 3 do -- y loop - local p = { x = px, y = position.y + y } - local strength = get_tile_strength(surface, p) or 0 - local tile = surface.get_tile(p) - print_grid_value(get_probability(strength) * config.weakness_value, surface, tile.position) - end - end -end - -- When the player changes position the tile will have a chance to downgrade, debug check is here Event.add(defines.events.on_player_changed_position, function(event) local player = game.players[event.player_index] @@ -103,9 +82,6 @@ Event.add(defines.events.on_player_changed_position, function(event) if get_probability(strength) > math.random() then degrade(surface, position) end - if debug_players[player.name] then - debug_get_tile_strength(surface, position) - end end) -- When an entity is build there is a much higher chance that the tiles will degrade @@ -131,10 +107,3 @@ Event.add(defines.events.on_robot_built_entity, function(event) degrade_entity(entity) end end) - --- Used as a way to access the global table -return function(player_name, state) - local player = game.players[player_name] - clear_flying_text(player.surface) - debug_players[player_name] = state -end diff --git a/exp_legacy/module/modules/commands/admin-chat.lua b/exp_legacy/module/modules/commands/admin-chat.lua index ff988e8c..fa866aaa 100644 --- a/exp_legacy/module/modules/commands/admin-chat.lua +++ b/exp_legacy/module/modules/commands/admin-chat.lua @@ -3,8 +3,9 @@ @commands Admin-Chat ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_general_parse") --- Sends a message in chat that only admins can see @@ -16,7 +17,7 @@ Commands.new_command("admin-chat", { "expcom-admin-chat.description" }, "Sends a :set_flag("admin_only") :add_alias("ac") :register(function(player, message) - local player_name_colour = format_chat_player_name(player) + local player_name_colour = format_player_name(player) for _, return_player in pairs(game.connected_players) do if return_player.admin then return_player.print{ "expcom-admin-chat.format", player_name_colour, message } diff --git a/exp_legacy/module/modules/commands/clear-inventory.lua b/exp_legacy/module/modules/commands/clear-inventory.lua index f364f54a..25d0de04 100644 --- a/exp_legacy/module/modules/commands/clear-inventory.lua +++ b/exp_legacy/module/modules/commands/clear-inventory.lua @@ -3,21 +3,26 @@ @commands Clear-Inventory ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -local move_items_stack = _C.move_items_stack --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_role_parse") --- Clears a players inventory -- @command clear-inventory -- @tparam LuaPlayer player the player to clear the inventory of Commands.new_command("clear-inventory", { "expcom-clr-inv.description" }, "Clears a players inventory") - :add_param("player", false, "player-role") - :add_alias("clear-inv", "move-inventory", "move-inv") - :register(function(_, player) - local inv = player.get_main_inventory() - if not inv then - return Commands.error{ "expcore-commands.reject-player-alive" } - end - move_items_stack(inv) - inv.clear() - end) + :add_param("player", false, "player-role") + :add_alias("clear-inv", "move-inventory", "move-inv") + :register(function(_, player) + local inventory = player.get_main_inventory() + if not inventory then + return Commands.error{ "expcore-commands.reject-player-alive" } + end + + ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = player.surface, + name = "iron-chest", + allow_creation = true, + } + end) diff --git a/exp_legacy/module/modules/commands/interface.lua b/exp_legacy/module/modules/commands/interface.lua index f75cd947..59929b40 100644 --- a/exp_legacy/module/modules/commands/interface.lua +++ b/exp_legacy/module/modules/commands/interface.lua @@ -3,13 +3,14 @@ @commands Interface ]] -local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands +local ExpUtil = require("modules/exp_util") local Storage = require("modules/exp_util/storage") +local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -- modules that are loaded into the interface env to be accessed local interface_modules = { ["Commands"] = Commands, - ["output"] = _C.player_return, + ["output"] = Commands.print, ["Group"] = "expcore.permission_groups", ["Roles"] = "expcore.roles", ["Gui"] = "expcore.gui", @@ -20,7 +21,7 @@ local interface_modules = { -- loads all the modules given in the above table for key, value in pairs(interface_modules) do if type(value) == "string" then - interface_modules[key] = _C.opt_require(value) + interface_modules[key] = ExpUtil.optional_require(value) end end diff --git a/exp_legacy/module/modules/commands/jail.lua b/exp_legacy/module/modules/commands/jail.lua index bacd2efb..c7e66f83 100644 --- a/exp_legacy/module/modules/commands/jail.lua +++ b/exp_legacy/module/modules/commands/jail.lua @@ -3,9 +3,10 @@ @commands Jail ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_role_parse") --- Puts a player into jail and removes all other roles. @@ -18,8 +19,8 @@ Commands.new_command("jail", { "expcom-jail.description-jail" }, "Puts a player :enable_auto_concat() :register(function(player, action_player, reason) reason = reason or "Non Given." - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) local player_name = player and player.name or "" if Jail.jail_player(action_player, player_name, reason) then game.print{ "expcom-jail.give", action_player_name_color, by_player_name_color, reason } @@ -36,8 +37,8 @@ Commands.new_command("unjail", { "expcom-jail.description-unjail" }, "Removes a :add_alias("clear-jail", "remove-jail") :enable_auto_concat() :register(function(player, action_player) - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) local player_name = player and player.name or "" if Jail.unjail_player(action_player, player_name) then game.print{ "expcom-jail.remove", action_player_name_color, by_player_name_color } diff --git a/exp_legacy/module/modules/commands/last-location.lua b/exp_legacy/module/modules/commands/last-location.lua index 26fb8d91..e761bf05 100644 --- a/exp_legacy/module/modules/commands/last-location.lua +++ b/exp_legacy/module/modules/commands/last-location.lua @@ -3,8 +3,9 @@ @commands LastLocation ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_general_parse") --- Get the last location of a player. @@ -14,6 +15,6 @@ Commands.new_command("last-location", { "expcom-lastlocation.description" }, "Se :add_alias("location") :add_param("player", false, "player") :register(function(_, action_player) - local action_player_name_color = format_chat_player_name(action_player) + local action_player_name_color = format_player_name(action_player) return Commands.success{ "expcom-lastlocation.response", action_player_name_color, string.format("%.1f", action_player.position.x), string.format("%.1f", action_player.position.y) } end) diff --git a/exp_legacy/module/modules/commands/protection.lua b/exp_legacy/module/modules/commands/protection.lua index 6602d97c..ca85750c 100644 --- a/exp_legacy/module/modules/commands/protection.lua +++ b/exp_legacy/module/modules/commands/protection.lua @@ -3,11 +3,12 @@ @commands Protection ]] +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Storage = require("modules/exp_util/storage") local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common local EntityProtection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection @@ -215,6 +216,6 @@ end) --- When there is a repeat offence print it in chat Event.add(EntityProtection.events.on_repeat_violation, function(event) - local player_name = format_chat_player_name(event.player_index) + local player_name = format_player_name(event.player_index) Roles.print_to_roles_higher("Regular", { "expcom-protection.repeat-offence", player_name, event.entity.localised_name, event.entity.position.x, event.entity.position.y }) end) diff --git a/exp_legacy/module/modules/commands/rainbow.lua b/exp_legacy/module/modules/commands/rainbow.lua index 7fd81dfd..adad6c11 100644 --- a/exp_legacy/module/modules/commands/rainbow.lua +++ b/exp_legacy/module/modules/commands/rainbow.lua @@ -3,8 +3,9 @@ @commands Rainbow ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands -local format_chat_colour = _C.format_chat_colour --- @dep expcore.common +local format_chat_colour = ExpUtil.format_rich_text_color --- @dep expcore.common local function step_component(c1, c2) if c1 < 0 then diff --git a/exp_legacy/module/modules/commands/reports.lua b/exp_legacy/module/modules/commands/reports.lua index 2ec9cf34..5078039d 100644 --- a/exp_legacy/module/modules/commands/reports.lua +++ b/exp_legacy/module/modules/commands/reports.lua @@ -3,10 +3,11 @@ @commands Reports ]] +local ExpUtil = require("modules/exp_util") local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common require("modules.exp_legacy.config.expcore.command_general_parse") --- Print a message to all players who match the value of admin @@ -38,8 +39,8 @@ Commands.new_command("report", { "expcom-report.description-report" }, "Reports :add_alias("report-player") :enable_auto_concat() :register(function(player, action_player, reason) - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) if Reports.report_player(action_player, player.name, reason) then print_to_players(false, { "expcom-report.non-admin", action_player_name_color, reason }) print_to_players(true, { "expcom-report.admin", action_player_name_color, by_player_name_color, reason }) @@ -58,17 +59,17 @@ Commands.new_command("get-reports", { "expcom-report.description-get-reports" }, :register(function(_, player) if player then local reports = Reports.get_reports(player) - local player_name_color = format_chat_player_name(player) + local player_name_color = format_player_name(player) Commands.print{ "expcom-report.player-report-title", player_name_color } for player_name, reason in pairs(reports) do - local by_player_name_color = format_chat_player_name(player_name) + local by_player_name_color = format_player_name(player_name) Commands.print{ "expcom-report.list", by_player_name_color, reason } end else local user_reports = Reports.user_reports Commands.print{ "expcom-report.player-count-title" } for player_name in pairs(user_reports) do - local player_name_color = format_chat_player_name(player_name) + local player_name_color = format_player_name(player_name) local report_count = Reports.count_reports(player_name) Commands.print{ "expcom-report.list", player_name_color, report_count } end @@ -92,7 +93,7 @@ Commands.new_command("clear-reports", { "expcom-report.description-clear-reports return Commands.error{ "expcom-report.not-reported" } end end - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-report.removed", action_player_name_color, by_player_name_color } end) diff --git a/exp_legacy/module/modules/commands/roles.lua b/exp_legacy/module/modules/commands/roles.lua index a02f5475..78937fe5 100644 --- a/exp_legacy/module/modules/commands/roles.lua +++ b/exp_legacy/module/modules/commands/roles.lua @@ -3,10 +3,11 @@ @commands Roles ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Colours = require("modules/exp_util/include/color") -local format_chat_player_name, format_chat_colour_localized = _C.format_chat_player_name, _C.format_chat_colour_localized +local format_player_name, format_color = ExpUtil.format_player_name_locale, ExpUtil.format_rich_text_color --- Assigns a role to a player -- @command assign-role @@ -63,11 +64,11 @@ Commands.new_command("list-roles", { "expcom-roles.description-list-roles" }, "L for index, role in pairs(roles) do role = Roles.get_role_from_any(role) local colour = role.custom_color or Colours.white - local role_name = format_chat_colour_localized(role.name, colour) + local role_name = format_color(role.name, colour) if index == 1 then message = { "expcom-roles.list", role_name } if player then - local player_name_colour = format_chat_player_name(player) + local player_name_colour = format_player_name(player) message = { "expcom-roles.list-player", player_name_colour, role_name } end else diff --git a/exp_legacy/module/modules/commands/search.lua b/exp_legacy/module/modules/commands/search.lua index 933871f5..36a7a724 100644 --- a/exp_legacy/module/modules/commands/search.lua +++ b/exp_legacy/module/modules/commands/search.lua @@ -3,10 +3,10 @@ @commands InventorySearch ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local format_number = require("util").format_number --- @dep util -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common -local format_time = _C.format_time +local format_player_name = ExpUtil.format_player_name_locale require("modules.exp_legacy.config.expcore.command_general_parse") --- Input parse for items by name @@ -85,13 +85,15 @@ local function sort_players(players, func) return sorted end +local display_players_time_format = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true } + --- Display to the player the top players which were found local function display_players(player, players, item) player.print{ "expcom-inv-search.results-heading", item.name } for index, data in ipairs(players) do - local player_name_color = format_chat_player_name(data.player) + local player_name_color = format_player_name(data.player) local amount = format_number(data.count) - local time = format_time(data.online_time) + local time = display_players_time_format(data.online_time) player.print{ "expcom-inv-search.results-item", index, player_name_color, amount, time } end end diff --git a/exp_legacy/module/modules/commands/surface-clearing.lua b/exp_legacy/module/modules/commands/surface-clearing.lua index e85005ae..b859a40d 100644 --- a/exp_legacy/module/modules/commands/surface-clearing.lua +++ b/exp_legacy/module/modules/commands/surface-clearing.lua @@ -3,22 +3,28 @@ @commands Clear Item On Ground ]] -local copy_items_stack = _C.copy_items_stack --- @dep expcore.common +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands require("modules.exp_legacy.config.expcore.command_general_parse") Commands.new_command("clear-item-on-ground", { "expcom-surface-clearing.description-ci" }, "Clear Item On Ground") :add_param("range", false, "integer-range", 1, 1000) :register(function(player, range) - for _, e in pairs(player.surface.find_entities_filtered{ position = player.position, radius = range, name = "item-on-ground" }) do + local items = {} --- @type LuaItemStack[] + local entities = player.surface.find_entities_filtered{ position = player.position, radius = range, name = "item-on-ground" } + for _, e in pairs(entities) do if e.stack then - -- calling move_items_stack(e.stack) will crash to desktop - -- https://forums.factorio.com/viewtopic.php?f=7&t=110322 - copy_items_stack{ e.stack } - e.stack.clear() + items[#items + 1] = e.stack end end + ExpUtil.move_items_to_surface{ + items = items, + surface = player.surface, + allow_creation = true, + name = "iron-chest", + } + return Commands.success end) diff --git a/exp_legacy/module/modules/commands/warnings.lua b/exp_legacy/module/modules/commands/warnings.lua index f81e7034..b2f9dd16 100644 --- a/exp_legacy/module/modules/commands/warnings.lua +++ b/exp_legacy/module/modules/commands/warnings.lua @@ -3,9 +3,10 @@ @commands Warnings ]] +local ExpUtil = require("modules/exp_util") local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local Warnings = require("modules.exp_legacy.modules.control.warnings") --- @dep modules.control.warnings -local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +local format_player_name = ExpUtil.format_player_name_locale local config = require("modules.exp_legacy.config.warnings") --- @dep config.warnings require("modules.exp_legacy.config.expcore.command_role_parse") @@ -20,8 +21,8 @@ Commands.new_command("give-warning", { "expcom-warnings.description-give" }, "Gi :enable_auto_concat() :register(function(player, action_player, reason) Warnings.add_warning(action_player, player.name, reason) - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-warnings.received", action_player_name_color, by_player_name_color, reason } end) @@ -35,10 +36,10 @@ Commands.new_command("get-warnings", { "expcom-warnings.description-get" }, "Get if player then local warnings = Warnings.get_warnings(player) local script_warnings = Warnings.get_script_warnings(player) - local player_name_color = format_chat_player_name(player) + local player_name_color = format_player_name(player) Commands.print{ "expcom-warnings.player", player_name_color, #warnings, #script_warnings, config.temp_warning_limit } for _, warning in ipairs(warnings) do - Commands.print{ "expcom-warnings.player-detail", format_chat_player_name(warning.by_player_name), warning.reason } + Commands.print{ "expcom-warnings.player-detail", format_player_name(warning.by_player_name), warning.reason } end else local rtn = {} @@ -56,7 +57,7 @@ Commands.new_command("get-warnings", { "expcom-warnings.description-get" }, "Get Commands.print{ "expcom-warnings.list-title" } for player_name, warnings in pairs(rtn) do - local player_name_color = format_chat_player_name(player_name) + local player_name_color = format_player_name(player_name) Commands.print{ "expcom-warnings.list", player_name_color, warnings[1], warnings[2], config.temp_warning_limit } end end @@ -70,7 +71,7 @@ Commands.new_command("clear-warnings", { "expcom-warnings.description-clear" }, :register(function(player, action_player) Warnings.clear_warnings(action_player, player.name) Warnings.clear_script_warnings(action_player) - local action_player_name_color = format_chat_player_name(action_player) - local by_player_name_color = format_chat_player_name(player) + local action_player_name_color = format_player_name(action_player) + local by_player_name_color = format_player_name(player) game.print{ "expcom-warnings.cleared", action_player_name_color, by_player_name_color } end) diff --git a/exp_legacy/module/modules/control/jail.lua b/exp_legacy/module/modules/control/jail.lua index d44da3d9..a60f7ab4 100644 --- a/exp_legacy/module/modules/control/jail.lua +++ b/exp_legacy/module/modules/control/jail.lua @@ -16,10 +16,9 @@ Jail.unjail_player('MrBiter', 'Cooldude2606') ]] -local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game +local Roles = require("modules.exp_legacy.expcore.roles") -local valid_player = Game.get_player_from_any +local valid_player = function(p) return type(p) == "userdata" and p or game.get_player(p) end local assign_roles = Roles.assign_player local unassign_roles = Roles.unassign_player local has_role = Roles.player_has_role @@ -65,7 +64,7 @@ end -- @tparam LuaPlayer player the player to check if they are in jail -- @treturn boolean whether the player is currently in jail function Jail.is_jailed(player) - return has_role(player, "Jail") + return has_role(valid_player(player), "Jail") end --- Moves a player to jail and removes all other roles diff --git a/exp_legacy/module/modules/control/reports.lua b/exp_legacy/module/modules/control/reports.lua index 10dbeaa3..bb103ba6 100644 --- a/exp_legacy/module/modules/control/reports.lua +++ b/exp_legacy/module/modules/control/reports.lua @@ -24,10 +24,9 @@ ]] -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game local Storage = require("modules/exp_util/storage") -local valid_player = Game.get_player_from_any +local valid_player = function(p) return type(p) == "userdata" and p or game.get_player(p) end local Reports = { user_reports = {}, -- stores all user reports, global table diff --git a/exp_legacy/module/modules/control/vlayer.lua b/exp_legacy/module/modules/control/vlayer.lua index 757aee69..6533a17b 100644 --- a/exp_legacy/module/modules/control/vlayer.lua +++ b/exp_legacy/module/modules/control/vlayer.lua @@ -4,10 +4,10 @@ @alias vlayer ]] +local ExpUtil = require("modules/exp_util") local Storage = require("modules/exp_util/storage") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.vlayer") --- @dep config.vlayer -local move_items_stack = _C.move_items_stack local mega = 1000000 @@ -682,13 +682,25 @@ function vlayer.remove_interface(surface, position) -- Return the type of interface removed and do some clean up if name == "logistic-chest-storage" then - move_items_stack(interface.get_inventory(defines.inventory.chest).get_contents()) + local inventory = assert(interface.get_inventory(defines.inventory.chest)) + ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = interface.surface, + name = "iron-chest", + allow_creation = true, + } table.remove_element(vlayer_data.entity_interfaces.storage_input, interface) interface.destroy() return "storage-input", pos elseif name == "logistic-chest-requester" then - move_items_stack(interface.get_inventory(defines.inventory.chest).get_contents()) + local inventory = assert(interface.get_inventory(defines.inventory.chest)) + ExpUtil.transfer_inventory_to_surface{ + inventory = inventory, + surface = interface.surface, + name = "iron-chest", + allow_creation = true, + } table.remove_element(vlayer_data.entity_interfaces.storage_output, interface) interface.destroy() diff --git a/exp_legacy/module/modules/control/warnings.lua b/exp_legacy/module/modules/control/warnings.lua index 53f467ad..628fc8d0 100644 --- a/exp_legacy/module/modules/control/warnings.lua +++ b/exp_legacy/module/modules/control/warnings.lua @@ -21,12 +21,11 @@ Warnings.clear_warnings('MrBiter', 'Cooldude2606') ]] -local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event -local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game +local Event = require("modules/exp_legacy/utils/event") local Storage = require("modules/exp_util/storage") -local config = require("modules.exp_legacy.config.warnings") --- @dep config.warnings +local config = require("modules.exp_legacy.config.warnings") -local valid_player = Game.get_player_from_any +local valid_player = function(p) return type(p) == "userdata" and p or game.get_player(p) end --- Stores the quickbar filters for a player local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data diff --git a/exp_legacy/module/modules/control/warps.lua b/exp_legacy/module/modules/control/warps.lua index 9ada9f1d..45006ae0 100644 --- a/exp_legacy/module/modules/control/warps.lua +++ b/exp_legacy/module/modules/control/warps.lua @@ -70,7 +70,7 @@ WrapData:on_update(function(warp_id, warp, old_warp) end -- Sort the warp names in alphabetical order - local new_warp_ids = table.get_values(table.keysort(warp_names)) + local new_warp_ids = table.get_values(table.key_sort(warp_names)) table.insert(new_warp_ids, 1, spawn_id) new_warp_ids.spawn = spawn_id force_warps[force_name] = new_warp_ids diff --git a/exp_legacy/module/modules/data/player-colours.lua b/exp_legacy/module/modules/data/player-colours.lua index 6aa3540c..15417845 100644 --- a/exp_legacy/module/modules/data/player-colours.lua +++ b/exp_legacy/module/modules/data/player-colours.lua @@ -40,7 +40,7 @@ PlayerColours:on_load(function(player_name, player_colour) else local colour_name = "white" while config.disallow[colour_name] do - colour_name = table.get_random_dictionary_entry(Colours, true) + colour_name = table.get_random(Colours, true) end player_colour = { Colours[colour_name], lighten(Colours[colour_name]) } diff --git a/exp_legacy/module/modules/data/statistics.lua b/exp_legacy/module/modules/data/statistics.lua index 8ceb5b2a..b0a5c38e 100644 --- a/exp_legacy/module/modules/data/statistics.lua +++ b/exp_legacy/module/modules/data/statistics.lua @@ -1,7 +1,7 @@ +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Storage = require("modules/exp_util/storage") --- @dep utils.global local config = require("modules.exp_legacy.config.statistics") --- @dep config.statistics -local format_time = _C.format_time local floor = math.floor local afk_required = 5 * 3600 -- 5 minutes @@ -46,25 +46,8 @@ Statistics:on_load(function(player_name, player_statistics) return player_statistics end) ---- Used to format time in minute format -local function format_minutes(value) - return format_time(value * 3600, { - long = true, - hours = true, - minutes = true, - }) -end - ---- Used to format time into a clock -local function format_clock(value) - return format_time(value * 3600, { - hours = true, - minutes = true, - seconds = false, - time = false, - string = true, - }) -end +local long_time_format = ExpUtil.format_time_factory_locale{ format = "long", coefficient = 3600, hours = true, minutes = true } +local short_time_format = ExpUtil.format_time_factory_locale{ format = "short", coefficient = 3600, hours = true, minutes = true } --- Add MapsPlayed if it is enabled if config.MapsPlayed then @@ -80,11 +63,11 @@ if config.Playtime or config.AfkTime then local playtime, afk_time if config.Playtime then playtime = Statistics:combine("Playtime") - playtime:set_metadata{ stringify = format_minutes, stringify_short = format_clock } + playtime:set_metadata{ stringify = long_time_format, stringify_short = short_time_format } end if config.AfkTime then afk_time = Statistics:combine("AfkTime") - afk_time:set_metadata{ stringify = format_minutes, stringify_short = format_clock } + afk_time:set_metadata{ stringify = long_time_format, stringify_short = short_time_format } end Event.on_nth_tick(3600, function() if game.tick == 0 then return end diff --git a/exp_legacy/module/modules/factorio-control.lua b/exp_legacy/module/modules/factorio-control.lua index 009a9d7d..6b99a579 100644 --- a/exp_legacy/module/modules/factorio-control.lua +++ b/exp_legacy/module/modules/factorio-control.lua @@ -6,119 +6,119 @@ local use_silo_script = not config.disable_base_game_silo_script local util = require("util") local silo_script if use_silo_script then - silo_script = require("silo-script") + silo_script = require("silo-script") end local global = {} Storage.register(global, function(tbl) - global = tbl + global = tbl end) local created_items = function() - return - { - ["iron-plate"] = 8, - ["wood"] = 1, - ["pistol"] = 1, - ["firearm-magazine"] = 10, - ["burner-mining-drill"] = 1, - ["stone-furnace"] = 1, - } + return + { + ["iron-plate"] = 8, + ["wood"] = 1, + ["pistol"] = 1, + ["firearm-magazine"] = 10, + ["burner-mining-drill"] = 1, + ["stone-furnace"] = 1, + } end local respawn_items = function() - return - { - ["pistol"] = 1, - ["firearm-magazine"] = 10, - } + return + { + ["pistol"] = 1, + ["firearm-magazine"] = 10, + } end if use_silo_script then - for k, v in pairs(silo_script.get_events()) do - Event.add(k, v) - end + for k, v in pairs(silo_script.get_events()) do + Event.add(k, v) + end end Event.add(defines.events.on_player_created, function(event) - local player = game.players[event.player_index] - util.insert_safe(player, global.created_items) + local player = game.players[event.player_index] + util.insert_safe(player, global.created_items) - local r = global.chart_distance or 200 - player.force.chart(player.surface, { { player.position.x - r, player.position.y - r }, { player.position.x + r, player.position.y + r } }) + local r = global.chart_distance or 200 + player.force.chart(player.surface, { { player.position.x - r, player.position.y - r }, { player.position.x + r, player.position.y + r } }) - if not global.skip_intro then - if game.is_multiplayer() then - player.print{ "msg-intro" } - else - game.show_message_dialog{ text = { "msg-intro" } } + if not global.skip_intro then + if game.is_multiplayer() then + player.print{ "msg-intro" } + else + game.show_message_dialog{ text = { "msg-intro" } } + end end - end - if use_silo_script then - silo_script.on_event(event) - end + if use_silo_script then + silo_script.on_event(event) + end end) Event.add(defines.events.on_player_respawned, function(event) - local player = game.players[event.player_index] - util.insert_safe(player, global.respawn_items) - if use_silo_script then - silo_script.on_event(event) - end + local player = game.players[event.player_index] + util.insert_safe(player, global.respawn_items) + if use_silo_script then + silo_script.on_event(event) + end end) if use_silo_script then - Event.on_load(function() - silo_script.on_load() - end) + Event.on_load(function() + silo_script.on_load() + end) end Event.on_init(function() - global.created_items = created_items() - global.respawn_items = respawn_items() - if use_silo_script then - silo_script.on_init() - end + global.created_items = created_items() + global.respawn_items = respawn_items() + if use_silo_script then + silo_script.on_init() + end end) if use_silo_script then - silo_script.add_remote_interface() - silo_script.add_commands() + silo_script.add_remote_interface() + silo_script.add_commands() end remote.add_interface("freeplay", - { - get_created_items = function() - return global.created_items - end, - set_created_items = function(map) - global.created_items = map - end, - get_respawn_items = function() - return global.respawn_items - end, - set_respawn_items = function(map) - global.respawn_items = map - end, - set_skip_intro = function(bool) - global.skip_intro = bool - end, - set_chart_distance = function(value) - global.chart_distance = tonumber(value) - end, - set_disable_crashsite = function() - end, - get_ship_items = function() - return {} - end, - set_ship_items = function() - return - end, - get_debris_items = function() - return {} - end, - set_debris_items = function() - return - end, - }) + { + get_created_items = function() + return global.created_items + end, + set_created_items = function(map) + global.created_items = map + end, + get_respawn_items = function() + return global.respawn_items + end, + set_respawn_items = function(map) + global.respawn_items = map + end, + set_skip_intro = function(bool) + global.skip_intro = bool + end, + set_chart_distance = function(value) + global.chart_distance = tonumber(value) + end, + set_disable_crashsite = function() + end, + get_ship_items = function() + return {} + end, + set_ship_items = function() + return + end, + get_debris_items = function() + return {} + end, + set_debris_items = function() + return + end, + }) diff --git a/exp_legacy/module/modules/gui/autofill.lua b/exp_legacy/module/modules/gui/autofill.lua index 46dcfb99..ccb1c00d 100644 --- a/exp_legacy/module/modules/gui/autofill.lua +++ b/exp_legacy/module/modules/gui/autofill.lua @@ -4,7 +4,7 @@ @alias autofill ]] -local FloatingText = require("modules/exp_util/floating_text") +local FlyingText = require("modules/exp_util/flying_text") local Gui = require("modules.exp_legacy.expcore.gui") -- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") -- @dep expcore.gui local Storage = require("modules/exp_util/storage") -- @dep utils.global @@ -12,8 +12,6 @@ local config = require("modules.exp_legacy.config.gui.autofill") -- @dep config. local Event = require("modules/exp_legacy/utils/event") -- @dep utils.event local table = require("modules.exp_legacy.overrides.table") -- @dep overrides.table -local print_text = FloatingText.print -- (surface, position, text, color) - --- Table that stores if autofill is enabled or not local autofill_player_settings = {} Storage.register(autofill_player_settings, function(tbl) @@ -324,7 +322,6 @@ local function entity_build(event) -- Get the inventory of the player local player_inventory = player.get_main_inventory() --- @cast player_inventory -nil - local text_position = { x = entity.position.x, y = entity.position.y } -- Loop over all possible items to insert into the entity for _, item in pairs(entity_settings.items) do -- Check if the item is enabled or goto next item @@ -338,7 +335,6 @@ local function entity_build(event) local item_amount = player_inventory.get_item_count(item.name) if item_amount ~= 0 then local inserted - text_position.y = text_position.y - 0.5 local color = { r = 0, g = 255, b = 0, a = 1 } if item_amount >= preferd_amount then -- Can item be inserted? no, goto next item! @@ -351,7 +347,12 @@ local function entity_build(event) color = { r = 255, g = 165, b = 0, a = 1 } end player_inventory.remove{ name = item.name, count = inserted } - print_text(entity.surface, text_position, { "autofill.inserted", inserted, rich_img("item", item.name), rich_img("entity", entity.name) }, color) + FlyingText.create_above_entity{ + target_entity = entity, + text = { "autofill.inserted", inserted, rich_img("item", item.name), rich_img("entity", entity.name) }, + player = player, + color = color, + } end ::end_item:: end diff --git a/exp_legacy/module/modules/gui/debug/expcore_datastore_view.lua b/exp_legacy/module/modules/gui/debug/expcore_datastore_view.lua index e28f4784..97b9e4f0 100644 --- a/exp_legacy/module/modules/gui/debug/expcore_datastore_view.lua +++ b/exp_legacy/module/modules/gui/debug/expcore_datastore_view.lua @@ -23,7 +23,7 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - for name in pairs(table.keysort(Datastore.debug())) do + for name in pairs(table.key_sort(Datastore.debug())) do local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = name } Gui.set_data(header, name) end @@ -69,7 +69,7 @@ Gui.on_click( header_name, function(event) local element = event.element - local tableName = Gui.get_data(element) + local table_name = Gui.get_data(element) local left_panel = element.parent.parent local data = Gui.get_data(left_panel) @@ -84,10 +84,10 @@ Gui.on_click( element.style.font_color = Color.orange data.selected_header = element - input_text_box.text = tableName + input_text_box.text = table_name input_text_box.style.font_color = Color.black - local content = Datastore.debug(tableName) + local content = Datastore.debug(table_name) local content_string = {} for key, value in pairs(content) do content_string[#content_string + 1] = key:gsub("^%l", string.upper) .. " = " .. dump(value) diff --git a/exp_legacy/module/modules/gui/player-list.lua b/exp_legacy/module/modules/gui/player-list.lua index 72dc8a18..55d3e1d4 100644 --- a/exp_legacy/module/modules/gui/player-list.lua +++ b/exp_legacy/module/modules/gui/player-list.lua @@ -5,13 +5,12 @@ ]] -- luacheck:ignore 211/Colors +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.gui.player_list_actions") --- @dep config.gui.player_list_actions -local Colors = require("modules/exp_util/include/color") -local format_time = _C.format_time --- @dep expcore.common --- Stores all data for the warp gui local PlayerListData = Datastore.connect("PlayerListData") @@ -261,12 +260,15 @@ Gui.left_toolbar_button("entity/character", { "player-list.main-tooltip" }, play return Roles.player_allowed(player, "gui/player-list") end) +local online_time_format = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true } +local afk_time_format = ExpUtil.format_time_factory_locale{ format = "long", minutes = true } + -- Get caption and tooltip format for a player local function get_time_formats(online_time, afk_time) local tick = game.tick > 0 and game.tick or 1 local percent = math.round(online_time / tick, 3) * 100 - local caption = format_time(online_time) - local tooltip = { "player-list.afk-time", percent, format_time(afk_time, { minutes = true, long = true }) } + local caption = online_time_format(online_time) + local tooltip = { "player-list.afk-time", percent, afk_time_format(afk_time) } return caption, tooltip end @@ -333,7 +335,7 @@ local function get_player_list_order() index=0-i, tag='', role_name = 'Fake Player', - chat_color = table.get_random_dictionary_entry(Colors), + chat_color = table.get_random(Colors), caption = caption, tooltip = tooltip } diff --git a/exp_legacy/module/modules/gui/playerdata.lua b/exp_legacy/module/modules/gui/playerdata.lua index 62969f39..46abcdf9 100644 --- a/exp_legacy/module/modules/gui/playerdata.lua +++ b/exp_legacy/module/modules/gui/playerdata.lua @@ -1,12 +1,12 @@ ---- module pd -- @gui PlayerData +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data require("modules.exp_legacy.modules.data.statistics") -local format_time = _C.format_time --- @dep expcore.common local format_number = require("util").format_number --- @dep util local pd_container @@ -16,66 +16,60 @@ local label_width = { ["total"] = 480, } -local function format_time_short(value) - return format_time(value * 3600, { - hours = true, - minutes = true, - seconds = false, - }) -end +local short_time_format = ExpUtil.format_time_factory_locale{ format = "short", coefficient = 3600, hours = true, minutes = true } local function format_number_n(n) return format_number(math.floor(n)) .. string.format("%.2f", n % 1):sub(2) end -local playerStats = PlayerData.Statistics +local PlayerStats = PlayerData.Statistics local computed_stats = { DamageDeathRatio = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["DamageDealt"]:get(player_name, 0) / playerStats["Deaths"]:get(player_name, 1)) + return format_number_n(PlayerStats["DamageDealt"]:get(player_name, 0) / PlayerStats["Deaths"]:get(player_name, 1)) end, }, KillDeathRatio = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["Kills"]:get(player_name, 0) / playerStats["Deaths"]:get(player_name, 1)) + return format_number_n(PlayerStats["Kills"]:get(player_name, 0) / PlayerStats["Deaths"]:get(player_name, 1)) end, }, SessionTime = { - default = format_time_short(0), + default = short_time_format(0), calculate = function(player_name) - return format_time_short((playerStats["Playtime"]:get(player_name, 0) - playerStats["AfkTime"]:get(player_name, 0)) / playerStats["JoinCount"]:get(player_name, 1)) + return short_time_format((PlayerStats["Playtime"]:get(player_name, 0) - PlayerStats["AfkTime"]:get(player_name, 0)) / PlayerStats["JoinCount"]:get(player_name, 1)) end, }, BuildRatio = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["MachinesBuilt"]:get(player_name, 0) / playerStats["MachinesRemoved"]:get(player_name, 1)) + return format_number_n(PlayerStats["MachinesBuilt"]:get(player_name, 0) / PlayerStats["MachinesRemoved"]:get(player_name, 1)) end, }, RocketPerHour = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["RocketsLaunched"]:get(player_name, 0) * 60 / playerStats["Playtime"]:get(player_name, 1)) + return format_number_n(PlayerStats["RocketsLaunched"]:get(player_name, 0) * 60 / PlayerStats["Playtime"]:get(player_name, 1)) end, }, TreeKillPerMinute = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["TreesDestroyed"]:get(player_name, 0) / playerStats["Playtime"]:get(player_name, 1)) + return format_number_n(PlayerStats["TreesDestroyed"]:get(player_name, 0) / PlayerStats["Playtime"]:get(player_name, 1)) end, }, NetPlayTime = { - default = format_time_short(0), + default = short_time_format(0), calculate = function(player_name) - return format_time_short((playerStats["Playtime"]:get(player_name, 0) - playerStats["AfkTime"]:get(player_name, 0))) + return short_time_format((PlayerStats["Playtime"]:get(player_name, 0) - PlayerStats["AfkTime"]:get(player_name, 0))) end, }, AFKTimeRatio = { default = format_number_n(0), calculate = function(player_name) - return format_number_n(playerStats["AfkTime"]:get(player_name, 0) * 100 / playerStats["Playtime"]:get(player_name, 1)) + return format_number_n(PlayerStats["AfkTime"]:get(player_name, 0) * 100 / PlayerStats["Playtime"]:get(player_name, 1)) end, }, } diff --git a/exp_legacy/module/modules/gui/readme.lua b/exp_legacy/module/modules/gui/readme.lua index 9892735a..e48c7e89 100644 --- a/exp_legacy/module/modules/gui/readme.lua +++ b/exp_legacy/module/modules/gui/readme.lua @@ -4,13 +4,13 @@ @alias readme ]] +local ExpUtil = require("modules/exp_util") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external -local format_time = _C.format_time --- @dep expcore.common local format_number = require("util").format_number --- @dep util local tabs = {} @@ -109,6 +109,8 @@ local join_server = External.request_connection(player, server_id, true) end) +local welcome_time_format = ExpUtil.format_time_factory_locale{ format = "long", days = true, hours = true, minutes = true } + --- Content area for the welcome tab -- @element welcome_content define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, @@ -139,7 +141,7 @@ define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, -- Add the other information to the gui container.add{ type = "flow" }.style.height = 4 - local online_time = format_time(game.tick, { days = true, hours = true, minutes = true, long = true }) + local online_time = welcome_time_format(game.tick) Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-general", server_details.reset_time, online_time }) Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-roles", table.concat(role_names, ", ") }) Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" }) diff --git a/exp_legacy/module/modules/gui/research.lua b/exp_legacy/module/modules/gui/research.lua index 4a1aa26d..7df7fc3f 100644 --- a/exp_legacy/module/modules/gui/research.lua +++ b/exp_legacy/module/modules/gui/research.lua @@ -1,12 +1,12 @@ --- research gui -- @gui Research +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Storage = require("modules/exp_util/storage") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local config = require("modules.exp_legacy.config.research") --- @dep config.research -local format_time = _C.format_time --- @dep expcore.common local research = {} Storage.register(research, function(tbl) @@ -16,22 +16,8 @@ end) research.time = {} research.res_queue_enable = false -local research_time_format = { - hours = true, - minutes = true, - seconds = true, - time = true, - string = true, -} - -local empty_time = format_time(0, { - hours = true, - minutes = true, - seconds = true, - time = true, - string = true, - null = true, -}) +local research_time_format = ExpUtil.format_time_factory{ format = "clock", hours = true, minutes = true, seconds = true } +local empty_time = research_time_format(nil) local font_color = { -- positive @@ -57,7 +43,7 @@ do res["disp"][i] = { raw_name = k, target = res_total, - target_disp = format_time(res_total, research_time_format), + target_disp = research_time_format(res_total), } i = i + 1 @@ -118,12 +104,12 @@ local function research_notification(event) end else if not (event.by_script) then - game.print{ "expcom-res.inf", format_time(game.tick, research_time_format), event.research.name, event.research.level - 1 } + game.print{ "expcom-res.inf", research_time_format(game.tick), event.research.name, event.research.level - 1 } end end else if not (event.by_script) then - game.print{ "expcom-res.msg", format_time(game.tick, research_time_format), event.research.name } + game.print{ "expcom-res.msg", research_time_format(game.tick), event.research.name } end if config.bonus_inventory.enabled then @@ -159,13 +145,13 @@ local function research_gui_update() res_disp[i]["difference_color"] = font_color[1] else res_disp[i]["target"] = res["disp"][res_i].target_disp - res_disp[i]["attempt"] = format_time(research.time[res_i], research_time_format) + res_disp[i]["attempt"] = research_time_format(research.time[res_i]) if research.time[res_i] < res["disp"][res_i].target then - res_disp[i]["difference"] = "-" .. format_time(res["disp"][res_i].target - research.time[res_i], research_time_format) + res_disp[i]["difference"] = "-" .. research_time_format(res["disp"][res_i].target - research.time[res_i]) res_disp[i]["difference_color"] = font_color[1] else - res_disp[i]["difference"] = format_time(research.time[res_i] - res["disp"][res_i].target, research_time_format) + res_disp[i]["difference"] = research_time_format(research.time[res_i] - res["disp"][res_i].target) res_disp[i]["difference_color"] = font_color[2] end end @@ -313,7 +299,7 @@ Event.add(defines.events.on_research_finished, function(event) end) Event.on_nth_tick(60, function() - local current_time = format_time(game.tick, research_time_format) + local current_time = research_time_format(game.tick) for _, player in pairs(game.connected_players) do local frame = Gui.get_left_element(player, research_container) diff --git a/exp_legacy/module/modules/gui/rocket-info.lua b/exp_legacy/module/modules/gui/rocket-info.lua index c16951d3..84c63fb7 100644 --- a/exp_legacy/module/modules/gui/rocket-info.lua +++ b/exp_legacy/module/modules/gui/rocket-info.lua @@ -4,19 +4,19 @@ @alias rocket_info ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.gui.rockets") --- @dep config.gui.rockets local Colors = require("modules/exp_util/include/color") local Rockets = require("modules.exp_legacy.modules.control.rockets") --- @dep modules.control.rockets -local format_time = _C.format_time --- @dep expcore.common local time_formats = { - caption = function(value) return format_time(value, { minutes = true, seconds = true }) end, - caption_hours = function(value) return format_time(value) end, - tooltip = function(value) return format_time(value, { minutes = true, seconds = true, long = true }) end, - tooltip_hours = function(value) return format_time(value, { hours = true, minutes = true, seconds = true, long = true }) end, + caption = ExpUtil.format_time_factory_locale{ format = "short", minutes = true, seconds = true }, + caption_hours = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true }, + tooltip = ExpUtil.format_time_factory_locale{ format = "long", minutes = true, seconds = true }, + tooltip_hours = ExpUtil.format_time_factory_locale{ format = "long", hours = true, minutes = true, seconds = true }, } --- Check if a player is allowed to use certain interactions diff --git a/exp_legacy/module/modules/gui/science-info.lua b/exp_legacy/module/modules/gui/science-info.lua index 58f02a47..807f39ac 100644 --- a/exp_legacy/module/modules/gui/science-info.lua +++ b/exp_legacy/module/modules/gui/science-info.lua @@ -4,15 +4,18 @@ @alias science_info ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.gui local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.gui.science") --- @dep config.gui.science local Production = require("modules.exp_legacy.modules.control.production") --- @dep modules.control.production -local format_time = _C.format_time --- @dep expcore.common -local null_time_short = { "science-info.eta-time", format_time(0, { hours = true, minutes = true, seconds = true, time = true, null = true }) } -local null_time_long = format_time(0, { hours = true, minutes = true, seconds = true, long = true, null = true }) +local clock_time_format = ExpUtil.format_time_factory_locale{ format = "clock", hours = true, minutes = true, seconds = true } +local long_time_format = ExpUtil.format_time_factory_locale{ format = "long", hours = true, minutes = true, seconds = true } + +local null_time_clock = { "science-info.eta-time", clock_time_format(nil) } +local null_time_long = long_time_format(nil) --- Data label that contains the value and the surfix -- @element production_label @@ -235,16 +238,18 @@ local function get_eta_label_data(player) -- Return the caption and tooltip return limit and limit > 0 and { research = true, - caption = format_time(limit, { hours = true, minutes = true, seconds = true, time = true }), - tooltip = format_time(limit, { hours = true, minutes = true, seconds = true, long = true }), - } or { research = false } + caption = clock_time_format(limit), + tooltip = long_time_format(limit), + } or { + research = false + } end -- Updates the eta label local function update_eta_label(element, eta_label_data) -- If no research selected show null if not eta_label_data.research then - element.caption = null_time_short + element.caption = null_time_clock element.tooltip = null_time_long return end @@ -293,7 +298,7 @@ local science_info_container = footer.add{ name = "label", type = "label", - caption = null_time_short, + caption = null_time_clock, tooltip = null_time_long, style = "frame_title", } diff --git a/exp_legacy/module/modules/gui/task-list.lua b/exp_legacy/module/modules/gui/task-list.lua index fb0ba461..525a9e82 100644 --- a/exp_legacy/module/modules/gui/task-list.lua +++ b/exp_legacy/module/modules/gui/task-list.lua @@ -3,13 +3,16 @@ @gui Task-List @alias task_list ]] + +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore local config = require("modules.exp_legacy.config.gui.tasks") --- @dep config.gui.tasks local Tasks = require("modules.exp_legacy.modules.control.tasks") --- @dep modules.control.tasks -local format_time = _C.format_time --- @dep expcore.common + +local format_time = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true } --- Stores all data for the task gui by player local TaskGuiData = Datastore.connect("TaskGuiData") diff --git a/exp_legacy/module/modules/gui/warp-list.lua b/exp_legacy/module/modules/gui/warp-list.lua index 146a0e35..d086ff1a 100644 --- a/exp_legacy/module/modules/gui/warp-list.lua +++ b/exp_legacy/module/modules/gui/warp-list.lua @@ -4,6 +4,7 @@ @alias warp_list ]] +local ExpUtil = require("modules/exp_util") local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore local Storage = require("modules/exp_util/storage") @@ -12,7 +13,8 @@ local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Colors = require("modules/exp_util/include/color") local config = require("modules.exp_legacy.config.gui.warps") --- @dep config.gui.warps local Warps = require("modules.exp_legacy.modules.control.warps") --- @dep modules.control.warps -local format_time, player_return = _C.format_time, _C.player_return --- @dep expcore.common + +local format_time = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true } --- Stores all data for the warp gui local WrapGuiData = Datastore.connect("WrapGuiData") @@ -94,7 +96,10 @@ local add_new_warp = -- Check if the warp is too close to water local water_tiles = surface.find_tiles_filtered{ collision_mask = "water-tile", radius = config.standard_proximity_radius + 1, position = position } if #water_tiles > 0 then - player_return({ "expcore-commands.command-fail", { "warp-list.too-close-to-water", config.standard_proximity_radius + 1 } }, "orange_red", player) + player.print( + { "expcore-commands.command-fail", { "warp-list.too-close-to-water", config.standard_proximity_radius + 1 } }, + { color = Colors.orange_red } + ) if game.player then game.player.play_sound{ path = "utility/wire_pickup" } end for _, tile in pairs(water_tiles) do rendering.draw_sprite{ @@ -121,7 +126,10 @@ local add_new_warp = } -- Remove 1 because that is the current player if #entities > 1 then - player_return({ "expcore-commands.command-fail", { "warp-list.too-close-to-entities", config.standard_proximity_radius + 2.5 } }, "orange_red", player) + player.print( + { "expcore-commands.command-fail", { "warp-list.too-close-to-entities", config.standard_proximity_radius + 2.5 } }, + { color = Colors.orange_red } + ) if game.player then game.player.play_sound{ path = "utility/wire_pickup" } end local character = player.character for _, entity in pairs(entities) do diff --git a/exp_legacy/module/overrides/table.lua b/exp_legacy/module/overrides/table.lua deleted file mode 100644 index f4266773..00000000 --- a/exp_legacy/module/overrides/table.lua +++ /dev/null @@ -1,448 +0,0 @@ ----@diagnostic disable: duplicate-set-field --- luacheck:ignore global table -local random = math.random -local floor = math.floor -local remove = table.remove -local tonumber = tonumber -local pairs = pairs -local table_size = table_size - ---- Searches a table to remove a specific element without an index --- @param t to search --- @param table element to search for -function table.remove_element(t, element) - for k, v in pairs(t) do - if v == element then - remove(t, k) - break - end - end -end - ---- Removes an item from an array in O(1) time. --- The catch is that fast_remove doesn't guarantee to maintain the order of items in the array. --- @param tbl
arrayed table --- @param index Must be >= 0. The case where index > #tbl is handled. -function table.remove_index(tbl, index) - local count = #tbl - if index > count then - return - elseif index < count then - tbl[index] = tbl[count] - end - - tbl[count] = nil -end - ---- Adds the contents of table t2 to table t1 --- @param t1
to insert into --- @param t2
to insert from -function table.merge_table(t1, t2) - for k, v in pairs(t2) do - if tonumber(k) then - t1[#t1 + 1] = v - else - t1[k] = v - end - end -end - ---[[-- Much faster method for inserting items into an array -@tparam table tbl the table that will have the values added to it -@tparam[opt] number start_index the index at which values will be added, nil means end of the array -@tparam table values the new values that will be added to the table -@treturn table the table that was passed as the first argument -@usage-- Adding 1000 values into the middle of the array -local tbl = {} -local values = {} -for i = 1, 1000 do tbl[i] = i values[i] = i end -table.array_insert(tbl, 500, values) -- around 0.4ms -]] -function table.array_insert(tbl, start_index, values) - if not values then - values = start_index - start_index = nil - end - - if start_index then - local starting_length = #tbl - local adding_length = #values - local move_to = start_index + adding_length + 1 - for offset = starting_length - start_index, 0, -1 do - tbl[move_to + offset] = tbl[starting_length + offset] - end - - start_index = start_index - 1 - else - start_index = #tbl - end - - for offset, item in ipairs(values) do - tbl[start_index + offset] = item - end - - return tbl -end - ---[[-- Much faster method for inserting keys into a table -@tparam table tbl the table that will have keys added to it -@tparam[opt] number start_index the index at which values will be added, nil means end of the array, numbered indexs only -@tparam table tbl2 the table that may contain both string and numbered keys -@treturn table the table passed as the first argument -@usage-- Merging two tables -local tbl = {} -local tbl2 = {} -for i = 1, 100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end -table.table_insert(tbl, 50, tbl2) -]] -function table.table_insert(tbl, start_index, tbl2) - if not tbl2 then - tbl2 = start_index - start_index = nil - end - - table.array_insert(tbl, start_index, tbl2) - for key, value in pairs(tbl2) do - if not tonumber(key) then - tbl[key] = value - end - end - - return tbl -end - ---- Checks if a table contains an element --- @param t
--- @param e table element --- @return the index of the element or nil -function table.get_key(t, e) - for k, v in pairs(t) do - if v == e then - return k - end - end - - return nil -end - ---- Checks if the arrayed portion of a table contains an element --- @param t
--- @param e table element --- @return the index of the element or nil -function table.get_index(t, e) - for i = 1, #t do - if t[i] == e then - return i - end - end - - return nil -end - ---- Checks if a table contains an element --- @param t
--- @param e table element --- @return indicating success -function table.contains(t, e) - return table.get_key(t, e) and true or false -end - ---- Checks if the arrayed portion of a table contains an element --- @param t
--- @param e table element --- @return indicating success -function table.array_contains(t, e) - return table.get_index(t, e) and true or false -end - ---- Extracts certain keys from a table --- @usage local key_three, key_one = extract({key_one='foo', key_two='bar', key_three=true}, 'key_three', 'key_one') --- @tparam table tbl table the which contains the keys --- @tparam string ... the names of the keys you want extracted --- @return the keys in the order given -function table.extract_keys(tbl, ...) - local values = {} - for _, key in pairs{ ... } do - table.insert(values, tbl[key]) - end - - return table.unpack(values) -end - ---- Adds an element into a specific index position while shuffling the rest down --- @param t
to add into --- @param index the position in the table to add to --- @param element to add to the table -function table.set(t, index, element) - local i = 1 - for k in pairs(t) do - if i == index then - t[k] = element - return nil - end - i = i + 1 - end - - error("Index out of bounds", 2) -end - ---- Chooses a random entry from a table --- because this uses math.random, it cannot be used outside of events --- @param t
--- @param key to indicate whether to return the key or value --- @return a random element of table t -function table.get_random_dictionary_entry(t, key) - local target_index = random(1, table_size(t)) - local count = 1 - for k, v in pairs(t) do - if target_index == count then - if key then - return k - else - return v - end - end - count = count + 1 - end -end - ---- Chooses a random entry from a weighted table --- because this uses math.random, it cannot be used outside of events --- @param weighted_table
of tables with items and their weights --- @param item_index of the index of items, defaults to 1 --- @param weight_index of the index of the weights, defaults to 2 --- @return table element -function table.get_random_weighted(weighted_table, item_index, weight_index) - local total_weight = 0 - item_index = item_index or 1 - weight_index = weight_index or 2 - - for _, w in pairs(weighted_table) do - total_weight = total_weight + w[weight_index] - end - - local index = random() * total_weight - local weight_sum = 0 - for _, w in pairs(weighted_table) do - weight_sum = weight_sum + w[weight_index] - if weight_sum >= index then - return w[item_index] - end - end -end - ---- Clears all existing entries in a table --- @param t
to clear --- @param array to indicate whether the table is an array or not -function table.clear_table(t, array) - if array then - for i = 1, #t do - t[i] = nil - end - else - for i in pairs(t) do - t[i] = nil - end - end -end - ---- Creates a fisher-yates shuffle of a sequential number-indexed table --- because this uses math.random, it cannot be used outside of events if no rng is supplied --- from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items --- @param t
to shuffle --- @param rng to provide random numbers -function table.shuffle_table(t, rng) - local rand = rng or math.random - local iterations = #t - if iterations == 0 then - error("Not a sequential table") - return - end - local j - - for i = iterations, 2, -1 do - j = rand(i) - t[i], t[j] = t[j], t[i] - end -end - ---- Default table comparator sort function. --- @local --- @param x one comparator operand --- @param y the other comparator operand --- @return true if x logically comes before y in a list, false otherwise -local function sort_func(x, y) -- sorts tables with mixed index types. - local tx = type(x) - local ty = type(y) - if tx == ty then - if type(x) == "string" then - return string.lower(x) < string.lower(y) - else - return x < y - end - elseif tx == "number" then - return true -- only x is a number and goes first - else - return false -- only y is a number and goes first - end -end - ---- Returns a copy of all of the values in the table. --- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil --- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() --- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type --- @treturn array an array with a copy of all the values in the table -function table.get_values(tbl, sorted, as_string) - if not tbl then return {} end - local valueset = {} - local n = 0 - if as_string then -- checking as_string /before/ looping is faster - for _, v in pairs(tbl) do - n = n + 1 - valueset[n] = tostring(v) - end - else - for _, v in pairs(tbl) do - n = n + 1 - valueset[n] = v - end - end - if sorted then - table.sort(valueset, sort_func) - end - return valueset -end - ---- Returns a copy of all of the keys in the table. --- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil --- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() --- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type --- @treturn array an array with a copy of all the keys in the table -function table.get_keys(tbl, sorted, as_string) - if not tbl then return {} end - local keyset = {} - local n = 0 - if as_string then -- checking as_string /before/ looping is faster - for k, _ in pairs(tbl) do - n = n + 1 - keyset[n] = tostring(k) - end - else - for k, _ in pairs(tbl) do - n = n + 1 - keyset[n] = k - end - end - if sorted then - table.sort(keyset, sort_func) - end - return keyset -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function table.alphanumsort(tbl) - local o = table.get_keys(tbl) - local function padnum(d) - local dec, n = string.match(d, "(%.?)0*(.+)") - return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) - end - table.sort(o, function(a, b) - return tostring(a):gsub("%.?%d+", padnum) .. ("%3d"):format(#b) - < tostring(b):gsub("%.?%d+", padnum) .. ("%3d"):format(#a) - end) - local _tbl = {} - for _, k in pairs(o) do _tbl[k] = tbl[k] end - - return _tbl -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) (faster alternative than above) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function table.keysort(tbl) - local o = table.get_keys(tbl, true) - local _tbl = {} - for _, k in pairs(o) do _tbl[k] = tbl[k] end - - return _tbl -end - ---[[ - Returns the index where t[index] == target. - If there is no such index, returns a negative value such that bit32.bnot(value) is - the index that the value should be inserted to keep the list ordered. - t must be a list in ascending order for the return value to be valid. - - Usage example: - local t = {1, 3,5, 7,9} - local x = 5 - local index = table.binary_search(t, x) - if index < 0 then - game.print("value not found, smallest index where t[index] > x is: " .. bit32.bnot(index)) - else - game.print("value found at index: " .. index) - end -]] -function table.binary_search(t, target) - -- For some reason bit32.bnot doesn't return negative numbers so I'm using ~x = -1 - x instead. - - local lower = 1 - local upper = #t - - if upper == 0 then - return -2 -- ~1 - end - - repeat - local mid = floor((lower + upper) * 0.5) - local value = t[mid] - if value == target then - return mid - elseif value < target then - lower = mid + 1 - else - upper = mid - 1 - end - until lower > upper - - return -1 - lower -- ~lower -end - --- add table-related functions that exist in base factorio/util to the 'table' table -require("util") - ---- Similar to serpent.block, returns a string with a pretty representation of a table. --- Notice: This method is not appropriate for saving/restoring tables. It is meant to be used by the programmer mainly while debugging a program. --- @param table
the table to serialize --- @param options
options are depth, newline, indent, process --- depth sets the maximum depth that will be printed out. When the max depth is reached, inspect will stop parsing tables and just return {...} --- process is a function which allow altering the passed object before transforming it into a string. --- A typical way to use it would be to remove certain values so that they don't appear at all. --- return the prettied table -table.inspect = require("modules/exp_util/include/inspect") --- @dep overrides.inspect - ---- Takes a table and returns the number of entries in the table. (Slower than #table, faster than iterating via pairs) -table.size = table_size - ---- Creates a deepcopy of a table. Metatables and LuaObjects inside the table are shallow copies. --- Shallow copies meaning it copies the reference to the object instead of the object itself. --- @param object
the object to copy --- @return
the copied object -table.deep_copy = table.deepcopy - ---- Merges multiple tables. Tables later in the list will overwrite entries from tables earlier in the list. --- Ex. merge({{1, 2, 3}, {[2] = 0}, {[3] = 0}}) will return {1, 0, 0} --- @param tables
takes a table of tables to merge --- @return
a merged table -table.merge = util.merge - ---- Determines if two tables are structurally equal. --- Notice: tables that are LuaObjects or contain LuaObjects won't be compared correctly, use == operator for LuaObjects --- @param tbl1
--- @param tbl2
--- @return -table.equals = table.compare - -return table diff --git a/exp_legacy/module/overrides/version.lua b/exp_legacy/module/overrides/version.lua deleted file mode 100644 index 8f2b824c..00000000 --- a/exp_legacy/module/overrides/version.lua +++ /dev/null @@ -1,5 +0,0 @@ -return { - expgaming_lua = "6.2.0", - expgaming_api = "2.0.0", - redmew_lua = "2019-02-24-76871ee", -} diff --git a/exp_legacy/module/utils/game.lua b/exp_legacy/module/utils/game.lua deleted file mode 100644 index 62174cb5..00000000 --- a/exp_legacy/module/utils/game.lua +++ /dev/null @@ -1,40 +0,0 @@ -local Color = require("modules/exp_util/include/color") -local Game = {} - ---[[ Note to readers -Game.get_player_from_name was removed because game.players[name] works without any edge cases -always true: game.players[name].name == name - -Game.get_player_by_index was added originally as a workaround for the following edge case: -player with index of 5 and name of "Cooldude2606" -player with index of 10 and name of "5" -game.players[5].name == "5" - -Discovered the following logic: -all keys are first converted to string and search against player names -if this fails it attempts to convert it to a number and search against player indexes -sometimes fails: game.players[index].index == index - -Game.get_player_by_index was removed after the above logic was corrected to the following: -when a key is a number it is searched against player indexes, and only their indexes -when a key is a string it is searched against player names, and then against their indexes -always true: game.players[name].name == name; game.players[index].index == index - -]] - ---- Returns a valid LuaPlayer if given a number, string, or LuaPlayer. Returns nil otherwise. --- obj -function Game.get_player_from_any(obj) - local o_type, p = type(obj) - if o_type == "table" then - p = obj - elseif o_type == "string" or o_type == "number" then - p = game.players[obj] - end - - if p and p.valid and p.is_player() then - return p - end -end - -return Game diff --git a/exp_util/module/common.lua b/exp_util/module/common.lua index fe78b8f5..f48c0888 100644 --- a/exp_util/module/common.lua +++ b/exp_util/module/common.lua @@ -1,7 +1,5 @@ --[[-- Util Module - Common -- Adds some commonly used functions used in many modules -@core Common -@alias Common +Adds some commonly used functions used in many modules ]] local assert = assert @@ -35,6 +33,10 @@ end]] --- Check the type of a value, also considers LuaObject.object_name and metatable.__class --- Returns true when the check failed and an error should be raised +--- @param value any The value to check the type of +--- @param type_name string The type name the value should be +--- @return boolean failed True if the check failed and an error should be raised +--- @return string actual_type The actual type of the value local function check_type(value, type_name) local value_type = type(value) --[[@as string]] if value_type == "userdata" then @@ -56,9 +58,9 @@ end local assert_type_fmt = "%s expected to be of type %s but got %s" --- Raise an error if the type of a value is not as expected --- @param value The value to assert the type of --- @tparam string type_name The name of the type that value is expected to be --- @tparam[opt=Value] string value_name The name of the value being tested, this is included in the error message +--- @param value any The value to assert the type of +--- @param type_name string The name of the type that value is expected to be +--- @param value_name string? The name of the value being tested, this is included in the error message function Common.assert_type(value, type_name, value_name) local failed, actual_type = check_type(value, type_name) if failed then @@ -68,10 +70,10 @@ end local assert_argument_fmt = "Bad argument #%d to %s; %s expected to be of type %s but got %s" --- Raise an error if the type of any argument is not as expected, more performant than assert_argument_types, but requires more manual input --- @param arg_value The argument to assert the type of --- @tparam string type_name The name of the type that value is expected to be --- @tparam number arg_index The index of the argument being tested, this is included in the error message --- @tparam[opt=Argument] string arg_name The name of the argument being tested, this is included in the error message +--- @param arg_value any The argument to assert the type of +--- @param type_name string The name of the type that value is expected to be +--- @param arg_index number The index of the argument being tested, this is included in the error message +--- @param arg_name string? The name of the argument being tested, this is included in the error message function Common.assert_argument_type(arg_value, type_name, arg_index, arg_name) local failed, actual_type = check_type(arg_value, type_name) if failed then @@ -81,10 +83,11 @@ function Common.assert_argument_type(arg_value, type_name, arg_index, arg_name) end --- Write a luu table to a file as a json string, note the defaults are different to game.write_file --- @tparam string path The path to write the json to --- @tparam table value The table to write to file --- @tparam[opt=false] boolean overwrite When true the json replaces the full contents of the file --- @tparam[opt=0] number player_index The player's machine to write on, -1 means all, 0 means host only +--- @param path string The path to write the json to +--- @param tbl table The table to write to file +--- @param overwrite boolean? When true the json replaces the full contents of the file +--- @param player_index number? The player's machine to write on, -1 means all, 0 is default means host only +--- @return nil function Common.write_json(path, tbl, overwrite, player_index) if player_index == -1 then return game.write_file(path, game.table_to_json(tbl) .. "\n", not overwrite) @@ -93,8 +96,9 @@ function Common.write_json(path, tbl, overwrite, player_index) end --- Clear a file by replacing its contents with an empty string --- @tparam string path The path to clear the contents of --- @tparam[opt=0] number player_index The player's machine to write on, -1 means all, 0 means host only +--- @param path string The path to clear the contents of +--- @param player_index number? The player's machine to write on, -1 means all, 0 is default and means host only +--- @return nil function Common.clear_file(path, player_index) if player_index == -1 then return game.write_file(path, "", false) @@ -103,8 +107,9 @@ function Common.clear_file(path, player_index) end --- Same as require but will return nil if the module does not exist, all other errors will propagate to the caller --- @tparam string module_path The path to the module to require, same syntax as normal require --- @return The contents of the module, or nil if the module does not exist or did not return a value +--- @param module_path string The path to the module to require, same syntax as normal require +--- @return any # The contents of the module, or nil if the module does not exist or did not return a value +--- @deprecated function Common.optional_require(module_path) local success, rtn = xpcall(require, traceback, module_path) if success then return rtn end @@ -114,16 +119,16 @@ function Common.optional_require(module_path) end --- Returns a desync sale filepath for a given stack frame, default is the current file --- @tparam number level The level of the stack to get the file of, a value of 1 is the caller of this function --- @treturn string The relative filepath of the given stack frame +--- @param level number? The level of the stack to get the file of, a value of 1 is the caller of this function +--- @return string # The relative filepath of the given stack frame function Common.safe_file_path(level) level = level or 1 return getinfo(level + 1, "S").short_src:sub(10, -5) end --- Returns the name of your module, this assumes your module is stored within /modules (which it is for clustorio) --- @tparam[opt=1] number level The level of the stack to get the module of, a value of 1 is the caller of this function --- @treturn string The name of the module at the given stack frame +--- @param level number? The level of the stack to get the module of, a value of 1 is the caller of this function +--- @return string # The name of the module at the given stack frame function Common.get_module_name(level) local file_within_module = getinfo((level or 1) + 1, "S").short_src:sub(18, -5) local next_slash = file_within_module:find("/") @@ -135,9 +140,9 @@ function Common.get_module_name(level) end --- Returns the name of a function in a safe and consistent format --- @tparam number|function func The level of the stack to get the name of, a value of 1 is the caller of this function --- @tparam boolean raw When true there will not be any < > around the name --- @treturn string The name of the function at the given stack frame or provided as an argument +--- @param func number | function The level of the stack to get the name of, a value of 1 is the caller of this function +--- @param raw boolean When true there will not be any < > around the name +--- @return string # The name of the function at the given stack frame or provided as an argument function Common.get_function_name(func, raw) local debug_info = getinfo(func, "Sn") local safe_source = debug_info.source:find("__level__") @@ -148,11 +153,11 @@ function Common.get_function_name(func, raw) end --- Attempt a simple autocomplete search from a set of options --- @tparam table options The table representing the possible options which can be selected --- @tparam string input The user input string which should be matched to an option --- @tparam[opt=false] boolean use_key When true the keys will be searched, when false the values will be searched --- @tparam[opt=false] boolean rtn_key When true the selected key will be returned, when false the selected value will be returned --- @return The selected key or value which first matches the input text +--- @param options table The table representing the possible options which can be selected +--- @param input string The user input string which should be matched to an option +--- @param use_key boolean? When true the keys will be searched, when false the values will be searched +--- @param rtn_key boolean? When true the selected key will be returned, when false the selected value will be returned +--- @return any # The selected key or value which first matches the input text function Common.auto_complete(options, input, use_key, rtn_key) input = input:lower() if use_key then @@ -170,61 +175,71 @@ function Common.auto_complete(options, input, use_key, rtn_key) end end ---- Formats any value into a safe representation, useful with table.insert --- @param value The value to be formated --- @return The formated version of the value --- @return True if value is a locale string, nil otherwise +--- Formats any value into a safe representation, useful with table.inspect +--- @param value any The value to be formatted +--- @return string | LocalisedString # The formatted version of the value +--- @return boolean # True if value is a locale string, nil otherwise function Common.safe_value(value) - if type(value) == "table" or type(value) == "userdata" then - if type(value.__self) == "userdata" or type(value) == "userdata" then - local success, rtn = pcall(function() -- some userdata doesnt contain "valid" - if value.valid then -- userdata - return "" - else -- invalid userdata - return "" - end - end) - return success and rtn or "" - elseif type(value[1]) == "string" and string.find(value[1], ".+[.].+") and not string.find(value[1], "%s") then + if type(value) == "table" then + local v1 = value[1] + local str = tostring(value) + if type(v1) == "string" and not v1:find("%s") + and (v1 == "" or v1 == "?" or v1:find(".+[.].+")) then return value, true -- locale string - elseif tostring(value) ~= "table" then - return tostring(value) -- has __tostring metamethod + elseif str ~= "table" then + return str, false -- has __tostring metamethod else -- plain table - return value + return value, false end elseif type(value) == "function" then -- function - return "" - else -- not: table, userdata, or function - return tostring(value) + return "", false + else -- not: table or function + return tostring(value), false end end +--- @class Common.format_any_param +--- @field as_json boolean? If table values should be returned as json +--- @field max_line_count number? If table newline count exceeds provided then it will be inlined, if 0 then always inline +--- @field no_locale_strings boolean? If value is a locale string it will be treated like a normal table +--- @field depth number? The max depth to process tables to, the default is 5 + --- Formats any value to be presented in a safe and human readable format --- @param value The value to be formated --- @param[opt] tableAsJson If table values should be returned as json --- @param[opt] maxLineCount If table newline count exceeds provided then it will be inlined --- @return The formated version of the value -function Common.format_any(value, as_json, max_line_count) +--- @param value any The value to be formatted +--- @param options Common.format_any_param? Options for the formatter +--- @return string | LocalisedString # The formatted version of the value +function Common.format_any(value, options) + options = options or {} local formatted, is_locale_string = Common.safe_value(value) - if type(formatted) == "table" and not is_locale_string then - if as_json then + if type(formatted) == "table" and (not is_locale_string or options.no_locale_strings) then + if options.as_json then local success, rtn = pcall(game.table_to_json, value) if success then return rtn end end - local rtn = table.inspect(value, { depth = 5, indent = " ", newline = "\n", process = Common.safe_value }) - if max_line_count == nil or select(2, rtn:gsub("\n", "")) < max_line_count then return rtn end - return table.inspect(value, { depth = 5, indent = "", newline = "", process = Common.safe_value }) + if options.max_line_count ~= 0 then + local rtn = table.inspect(value, { depth = options.depth or 5, indent = " ", newline = "\n", process = Common.safe_value }) + if options.max_line_count == nil or select(2, rtn:gsub("\n", "")) < options.max_line_count then return rtn end + end + return table.inspect(value, { depth = options.depth or 5, indent = "", newline = "", process = Common.safe_value }) end return formatted end +--- @alias Common.format_time_param_format "short" | "long" | "clock" + +--- @class Common.format_time_param_units +--- @field days boolean? True if days are included +--- @field hours boolean? True if hours are included +--- @field minutes boolean? True if minutes are included +--- @field seconds boolean? True if seconds are included + --- Format a tick value into one of a selection of pre-defined formats (short, long, clock) --- @tparam number ticks The number of ticks which will be represented, can be any duration or time value --- @tparam string format The format to display, must be one of: short, long, clock --- @tparam[opt] table units A table selecting which units should be displayed, options are: days, hours, minutes, seconds --- @treturn string The ticks formatted into a string of the desired format +--- @param ticks number|nil The number of ticks which will be represented, can be any duration or time value +--- @param format Common.format_time_param_format format to display, must be one of: short, long, clock +--- @param units Common.format_time_param_units A table selecting which units should be displayed, options are: days, hours, minutes, seconds +--- @return string # The ticks formatted into a string of the desired format function Common.format_time(ticks, format, units) - units = units or { days = false, hours = true, minutes = true, seconds = false } + --- @type string | number, string | number, string | number, string | number local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = "--", "--", "--", "--" if ticks ~= nil then @@ -234,7 +249,6 @@ function Common.format_time(ticks, format, units) local minutes, seconds = max_minutes - floor(max_hours) * 60, max_seconds - floor(max_minutes) * 60 -- Calculate rhw units to be displayed - --- @diagnostic disable: cast-local-type rtn_days, rtn_hours, rtn_minutes, rtn_seconds = floor(days), floor(hours), floor(minutes), floor(seconds) if not units.days then rtn_hours = rtn_hours + rtn_days * 24 end if not units.hours then rtn_minutes = rtn_minutes + rtn_hours * 60 end @@ -269,12 +283,12 @@ function Common.format_time(ticks, format, units) end --- Format a tick value into one of a selection of pre-defined formats (short, long, clock) --- @tparam number ticks The number of ticks which will be represented, can be any duration or time value --- @tparam string format The format to display, must be one of: short, long, clock --- @tparam[opt] table units A table selecting which units should be displayed, options are: days, hours, minutes, seconds --- @treturn LocaleString The ticks formatted into a LocaleString of the desired format -function Common.format_locale_time(ticks, format, units) - units = units or { days = false, hours = true, minutes = true, seconds = false } +--- @param ticks number|nil The number of ticks which will be represented, can be any duration or time value +--- @param format Common.format_time_param_format format to display, must be one of: short, long, clock +--- @param units Common.format_time_param_units A table selecting which units should be displayed, options are: days, hours, minutes, seconds +--- @return LocalisedString # The ticks formatted into a string of the desired format +function Common.format_time_locale(ticks, format, units) + --- @type string | number, string | number, string | number, string | number local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = "--", "--", "--", "--" if ticks ~= nil then @@ -284,23 +298,20 @@ function Common.format_locale_time(ticks, format, units) local minutes, seconds = max_minutes - floor(max_hours) * 60, max_seconds - floor(max_minutes) * 60 -- Calculate rhw units to be displayed - --- @diagnostic disable: cast-local-type rtn_days, rtn_hours, rtn_minutes, rtn_seconds = floor(days), floor(hours), floor(minutes), floor(seconds) if not units.days then rtn_hours = rtn_hours + rtn_days * 24 end if not units.hours then rtn_minutes = rtn_minutes + rtn_hours * 60 end if not units.minutes then rtn_seconds = rtn_seconds + rtn_minutes * 60 end - --- @diagnostic enable: cast-local-type end local rtn = {} - local join = ", " + local join = ", " --- @type string | LocalisedString if format == "clock" then -- Example 12:34:56 or --:--:-- if units.days then rtn[#rtn + 1] = rtn_days end if units.hours then rtn[#rtn + 1] = rtn_hours end if units.minutes then rtn[#rtn + 1] = rtn_minutes end if units.seconds then rtn[#rtn + 1] = rtn_seconds end - --- @diagnostic disable-next-line: cast-local-type join = { "colon" } elseif format == "short" then -- Example 12d 34h 56m or --d --h --m @@ -318,81 +329,225 @@ function Common.format_locale_time(ticks, format, units) rtn[#rtn] = { "", { "and" }, " ", rtn[#rtn] } end - local joined = { "" } --[[@as any]] + --- @type LocalisedString + local joined = { "" } for k, v in ipairs(rtn) do joined[2 * k] = v - joined[2 * k + 1] = join --[[@as any]] + joined[2 * k + 1] = join end return joined end ---- Insert a copy of the given items into the found / created entities. If no entities are found then they will be created if possible. --- @tparam table items The items which are to be inserted into the entities, an array of LuaItemStack --- @tparam LuaSurface surface The surface which will be searched to find the entities --- @tparam table options A table of various optional options similar to find_entities_filtered --- position + radius or area can be used to define a search area on the surface --- type can be used to find all entities of a given type, such as a chest --- name can be used to further specify which entity to insert into, this field is required if entity creation is desired --- allow_creation is a boolean which when true will allow the function to create new entities in order to insert all items --- force is the force which new entities will be created to, the default is the neutral force --- @treturn LuaEntity the last entity that had items inserted into it -function Common.insert_item_stacks(items, surface, options) - local entities = surface.find_entities_filtered(options) - local count, current, last_entity = #entities, 0, nil +--- @class Common.format_time_factory_param: Common.format_time_param_units +--- @field format Common.format_time_param_format The format to use +--- @field coefficient number? If present will multiply the input by this amount before formatting - for _, item in ipairs(items) do - if item.valid_for_read then - local inserted = false +--- Create a formatter to format a tick value into one of a selection of pre-defined formats (short, long, clock) +--- @param options Common.format_time_factory_param +--- @return fun(ticks: number|nil): string +function Common.format_time_factory(options) + local formatter, format, coefficient = Common.format_time, options.format, options.coefficient + if coefficient then + return function(ticks) return formatter(ticks and ticks * coefficient or nil, format, options) end + end + return function(ticks) return formatter(ticks, format, options) end +end - -- Attempt to insert the items - for i = 1, count do - local entity = entities[((current + i - 1) % count) + 1] - if entity.can_insert(item) then - last_entity = entity - current = current + 1 - entity.insert(item) - inserted = true - end - end +--- Create a formatter to format a tick value into one of a selection of pre-defined formats (short, long, clock) +--- @param options Common.format_time_factory_param +--- @return fun(ticks: number|nil): LocalisedString +function Common.format_time_factory_locale(options) + local formatter, format, coefficient = Common.format_local_time, options.format, options.coefficient + if coefficient then + return function(ticks) return formatter(ticks and ticks * coefficient or nil, format, options) end + end + return function(ticks) return formatter(ticks, format, options) end +end - -- If it was not inserted then a new entity is needed - if not inserted then - if not options.allow_creation then error("Unable to insert items into a valid entity, consider enabling allow_creation") end - if options.name == nil then error("Name must be provided to allow creation of new entities") end +--- @class Common.get_or_create_storage_cache +--- @field entities LuaEntity[] Array of found entities matching the search +--- @field current number The current index within the entity array +--- @field count number The number of entities found - local position - if options.position then - position = surface.find_non_colliding_position(options.name, options.position, options.radius, 1, true) - elseif options.area then - position = surface.find_non_colliding_position_in_box(options.name, options.area, 1, true) - else - position = surface.find_non_colliding_position(options.name, { 0, 0 }, 0, 1, true) - end - last_entity = surface.create_entity{ name = options.name, position = position, force = options.force or "neutral" } +--- @class Common.get_or_create_storage_param: EntitySearchFilters +--- @field item ItemStackIdentification The item stack that must be insertable +--- @field surface LuaSurface The surface to search for targets on +--- @field allow_creation boolean? If new entities can be create to store the items +--- @field cache Common.get_or_create_storage_cache? Internal search cache passed between subsequent calls - count = count + 1 - entities[count] = last_entity - last_entity.insert(item) - end +--- Find, or optionally create, a storage entity which a stack can be inserted into +--- @param options Common.get_or_create_storage_param +--- @return LuaEntity +function Common.get_storage_for_stack(options) + local surface = assert(options.surface, "A surface must be provided") + local item = assert(options.item, "An item stack must be provided") + + -- Perform a search if on has not been done already + local cache = options.cache + if cache then + local entities = surface.find_entities_filtered(options) + cache = { + entities = entities, + count = #entities, + current = 0, + } + options.cache = cache + end + --- @cast cache -nil + + -- Find a valid entity from the search results + local current, count, entities = cache.current, cache.count, cache.entities + for i = 1, cache.count do + local entity = entities[((current + i - 1) % count) + 1] + if entity.can_insert(item) then + cache.current = current + 1 + return entity end end - return last_entity + -- No entity was found so one needs to be created + assert(options.allow_creation, "Unable to find valid entity, consider enabling allow_creation") + assert(options.name, "Name must be provided to allow creation of new entities") + + local position + if options.position then + position = surface.find_non_colliding_position(options.name, options.position, options.radius or 0, 1, true) + elseif options.area then + position = surface.find_non_colliding_position_in_box(options.name, options.area, 1, true) + else + position = surface.find_non_colliding_position(options.name, { 0, 0 }, 0, 1, true) + end + assert(position, "Failed to find valid location") + + local entity = surface.create_entity{ name = options.name, position = position, force = options.force or "neutral" } + assert(entity, "Failed to create a new entity") + + cache.count = count + 1 + entities[count] = entity + return entity end ---- Move the given items into the found / created entities. If no entities are found then they will be created if possible. --- @tparam table items The items which are to be inserted into the entities, an array of LuaItemStack --- @tparam LuaSurface surface The surface which will be searched to find the entities --- @tparam table options A table of various optional options similar to find_entities_filtered --- position + radius or area can be used to define a search area on the surface --- type can be used to find all entities of a given type, such as a chest --- name can be used to further specify which entity to insert into, this field is required if entity creation is desired --- allow_creation is a boolean which when true will allow the function to create new entities in order to insert all items --- @treturn LuaEntity the last entity that had items inserted into it -function Common.transfer_item_stacks(inventory, surface, options) - Common.insert_item_stacks(inventory, surface, options) - inventory.clear() +--- @class Common.copy_items_to_surface_param: Common.get_or_create_storage_param +--- @field items ItemStackIdentification[] | LuaInventory The item stacks to copy + +--- Insert a copy of the given items into the found entities. If no entities are found then they will be created if possible. +--- @param options Common.copy_items_to_surface_param +--- @return LuaEntity # The last entity inserted into +function Common.copy_items_to_surface(options) + local entity + for item_index = 1, #options.items do + options.item = options.items[item_index] + entity = Common.get_storage_for_stack(options) + entity.insert(options.item) + end + return entity +end + +--- @class Common.move_items_to_surface_param: Common.get_or_create_storage_param +--- @field items LuaItemStack[] The item stacks to move + +--- Insert a copy of the given items into the found entities. If no entities are found then they will be created if possible. +--- @param options Common.move_items_to_surface_param +--- @return LuaEntity # The last entity inserted into +function Common.move_items_to_surface(options) + local entity + for item_index = 1, #options.items do + options.item = options.items[item_index] + entity = Common.get_storage_for_stack(options) + entity.insert(options.item) + options.item.clear() + end + return entity +end + +--- @class Common.transfer_inventory_to_surface_param: Common.copy_items_to_surface_param +--- @field inventory LuaInventory The inventory to transfer + +--- Move the given inventory into the found entities. If no entities are found then they will be created if possible. +--- @param options Common.transfer_inventory_to_surface_param +--- @return LuaEntity # The last entity inserted into +function Common.transfer_inventory_to_surface(options) + options.items = options.inventory + local entity = Common.copy_items_to_surface(options) + options.inventory.clear() + return entity +end + +--- Create an enum table from a set of strings, can use custom indexes to change base +--- @param values { [number]: string } +--- @return { [string | number]: string | number } +function Common.enum(values) + local enum = {} + + local index = 0 -- Real index within values + local offset = 0 -- Offset from base for next index + local base = 0 -- Start point for offset + for k, v in pairs(values) do + index = index + 1 + if k ~= index then + offset = 0 + base = k + end + enum[base + offset] = v + offset = offset + 1 + end + + for k, v in pairs(enum) do + if type(k) == "number" then + enum[v] = k + end + end + + return enum +end + +--- Returns a string for a number with comma separators +--- @param n number +--- @return string +function Common.comma_value(n) -- credit http://richard.warburton.it + local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$") + return left .. (num:reverse():gsub("(%d%d%d)", "%1, "):reverse()) .. right +end + +--- Returns a message formatted for game chat using rich text colour tags +--- @param message string +--- @param color Color | string +--- @return string +function Common.format_rich_text_color(message, color) + color = color or Common.color.white + local color_tag = "[color=" .. math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3) .. "]" + return string.format("%s%s[/color]", color_tag, message) +end + +--- Returns a message formatted for game chat using rich text colour tags +--- @param message string +--- @param color Color | string +--- @return LocalisedString +function Common.format_rich_text_color_locale(message, color) + color = color or Common.color.white + color = math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3) + return { "color-tag", color, message } +end + +--- Formats a players name using rich text color +--- @param player LuaPlayer +--- @return string +function Common.format_player_name(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) + local player_name = valid_player and valid_player.name or "" + local player_chat_colour = valid_player and valid_player.chat_color or Common.color.white + return Common.format_rich_text_color(player_name, player_chat_colour) +end + +--- Formats a players name using rich text color +--- @param player LuaPlayer +--- @return LocalisedString +function Common.format_player_name_locale(player) + local valid_player = type(player) == "userdata" and player or game.get_player(player) + local player_name = valid_player and valid_player.name or "" + local player_chat_colour = valid_player and valid_player.chat_color or Common.color.white + return Common.format_rich_text_color_locale(player_name, player_chat_colour) end return Common diff --git a/exp_util/module/floating_text.lua b/exp_util/module/floating_text.lua deleted file mode 100644 index d278e1fe..00000000 --- a/exp_util/module/floating_text.lua +++ /dev/null @@ -1,180 +0,0 @@ ---[[-- Util Module - FloatingText -- Provides a method of creating floating text and tags in the world -@core FloatingText -@alias FloatingText - -@usage-- Show player chat message in world -local function on_console_chat(event) - local player = game.players[event.player_index] - FloatingText.print_as_player(player, event.message) -end - -@usage-- Show player tags above their characters -local function on_player_respawned(event) - local player = game.players[event.player_index] - FloatingText.create_tag_as_player(player, player.tag) -end - -@usage-- Show placed an entity in alt mode -local function on_built_entity(event) - local entity = event.created_entity - local player = game.players[event.player_index] - FloatingText.create_tag_above_entity(entity, player.name, player.color, true) -end - -]] - -local FloatingText = {} -FloatingText.color = require("modules/exp_util/include/color") - ---- Print Messages. --- Short lived messages that last at most a few seconds --- @section floating-text_print - ---- Print floating text at the given position on the given surface --- @tparam LuaSurface surface The surface where the floating text will be created --- @tparam MapPosition position The position to create the floating text at --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.print(surface, position, text, color) - return surface.create_entity{ - text = text, - name = "tutorial-flying-text", - color = color or FloatingText.color.white, - position = position, - } -end - ---- Print floating text above the given entity --- @tparam LuaEntity The entity to create the text above --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.print_above_entity(entity, text, color) - local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y - return entity.surface.create_entity{ - text = text, - name = "tutorial-flying-text", - color = color or FloatingText.color.white, - position = { - x = entity.position.x, - y = entity.position.y - size_y * 0.25, - }, - } -end - ---- Print floating text above the given player --- @tparam LuaPlayer The player to create the text above --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.print_above_player(player, text, color) - return player.surface.create_entity{ - text = text, - name = "tutorial-flying-text", - color = color or FloatingText.color.white, - position = { - x = player.position.x, - y = player.position.y - 1.5, - }, - } -end - ---- Print floating text above the given player in their chat color --- @tparam LuaPlayer The player to create the text above --- @tparam string text The text which will be printed --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.print_as_player(player, text) - return player.surface.create_entity{ - text = text, - name = "tutorial-flying-text", - color = player.chat_color, - position = { - x = player.position.x, - y = player.position.y - 1.5, - }, - } -end - ---- Tag Messages. --- Long lived messages that last until their are removed --- @section floating-text_tags - ---- Create floating text at the given position on the given surface --- @tparam LuaSurface surface The surface where the floating text will be created --- @tparam MapPosition position The position to create the floating text at --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @tparam[opt=false] boolean alt_mode When true, the text will only appear when a player is in alt mode --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.create_tag(surface, position, text, color, alt_mode) - return rendering.draw_text{ - text = text, - surface = surface, - color = color or FloatingText.color.white, - only_in_alt_mode = alt_mode, - target = position, - } -end - ---- Create floating text above the given entity --- @tparam LuaEntity The entity to create the text above --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @tparam[opt=false] boolean alt_mode When true, the text will only appear when a player is in alt mode --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.create_tag_above_entity(entity, text, color, alt_mode) - return rendering.draw_text{ - text = text, - surface = entity.surface, - color = color or FloatingText.color.white, - only_in_alt_mode = alt_mode, - target = entity, - target_offset = { - x = 0, - y = (entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y) * -0.25, - }, - } -end - ---- Create floating text above the given player --- @tparam LuaPlayer The player to create the text above --- @tparam string text The text which will be printed --- @tparam[opt=FloatingText.color.white] Color color The colour to print the text in --- @tparam[opt=false] boolean alt_mode When true, the text will only appear when a player is in alt mode --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.create_tag_above_player(player, text, color, alt_mode) - return rendering.draw_text{ - text = text, - surface = player.surface, - color = color or FloatingText.color.white, - only_in_alt_mode = alt_mode, - target = player.character, - target_offset = { - x = 0, - y = -1.5, - }, - } -end - ---- Create floating text above the given player in their character color --- @tparam LuaPlayer The player to create the text above --- @tparam string text The text which will be printed --- @tparam[opt=false] boolean alt_mode When true, the text will only appear when a player is in alt mode --- @treturn LuaEntity The floating text entity which was created for the message -function FloatingText.create_tag_as_player(player, text, alt_mode) - return rendering.draw_text{ - text = text, - surface = player.surface, - color = player.color, - only_in_alt_mode = alt_mode, - target = player.character, - target_offset = { - x = 0, - y = -1.5, - }, - } -end - -return FloatingText diff --git a/exp_util/module/flying_text.lua b/exp_util/module/flying_text.lua new file mode 100644 index 00000000..1dd59989 --- /dev/null +++ b/exp_util/module/flying_text.lua @@ -0,0 +1,89 @@ +--[[-- Util Module - FlyingText +Provides a method of creating floating text and tags in the world +]] + +local FlyingText = {} +FlyingText.color = require("modules/exp_util/include/color") + +--- @class FlyingText.create_param:LuaPlayer.create_local_flying_text_param +--- @field player? LuaPlayer The player to create the text for +--- @field surface? LuaSurface The surface to create the text for +--- @field force? LuaForce The force to create the text for + +--- Create flying text for a player, force, or surface; default is all online players +--- @param options FlyingText.create_param +function FlyingText.create(options) + if options.player then + options.player.create_local_flying_text(options) + elseif options.force then + for _, player in pairs(options.force.connected_players) do + player.create_local_flying_text(options) + end + elseif options.surface then + for _, player in pairs(game.connected_players) do + if player.surface == options.surface then + player.create_local_flying_text(options) + end + end + else + for _, player in pairs(game.connected_players) do + player.create_local_flying_text(options) + end + end +end + +--- @class FlyingText.create_above_entity_param:FlyingText.create_param +--- @field target_entity? LuaEntity The entity to create the text above + +--- Create flying above an entity, overrides the position option of FlyingText.create +--- @param options FlyingText.create_above_entity_param +function FlyingText.create_above_entity(options) + local entity = assert(options.target_entity, "A target entity is required") + local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y + + options.position = { + x = entity.position.x, + y = entity.position.y - size_y * 0.25, + } + + FlyingText.create(options) +end + +--- @class FlyingText.create_above_player_param:FlyingText.create_param +--- @field target_player? LuaPlayer The player to create the text above + +--- Create flying above a player, overrides the position option of FlyingText.create +--- @param options FlyingText.create_above_player_param +function FlyingText.create_above_player(options) + local player = assert(options.target_player, "A target entity is required") + local entity = player.character; if not entity then return end + local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y + + options.position = { + x = entity.position.x, + y = entity.position.y - size_y * 0.25, + } + + FlyingText.create(options) +end + +--- @class FlyingText.create_as_player_param:FlyingText.create_param +--- @field target_player? LuaPlayer The player to create the text above + +--- Create flying above a player, overrides the position and color option of FlyingText.create +--- @param options FlyingText.create_as_player_param +function FlyingText.create_as_player(options) + local player = assert(options.target_player, "A target entity is required") + local entity = player.character; if not entity then return end + local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y + + options.color = player.chat_color + options.position = { + x = entity.position.x, + y = entity.position.y - size_y * 0.25, + } + + FlyingText.create(options) +end + +return FlyingText diff --git a/exp_util/module/include/table.lua b/exp_util/module/include/table.lua index 6e3a1a0c..4ef72595 100644 --- a/exp_util/module/include/table.lua +++ b/exp_util/module/include/table.lua @@ -32,9 +32,9 @@ end local tbl = {} local values = {} for i = 1, 1000 do tbl[i] = i values[i] = i end -table.array_insert(tbl, 500, values) -- around 0.4ms +table.insert_array(tbl, 500, values) -- around 0.4ms ]] -function table.array_insert(tbl, start_index, values) +function table.insert_array(tbl, start_index, values) if not values then values = start_index start_index = nil @@ -69,15 +69,15 @@ end local tbl = {} local tbl2 = {} for i = 1, 100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end -table.table_insert(tbl, 50, tbl2) +table.insert_table(tbl, 50, tbl2) ]] -function table.table_insert(tbl, start_index, tbl2) +function table.insert_table(tbl, start_index, tbl2) if not tbl2 then tbl2 = start_index start_index = nil end - table.array_insert(tbl, start_index, tbl2) + table.insert_array(tbl, start_index, tbl2) for key, value in pairs(tbl2) do if not tonumber(key) then tbl[key] = value @@ -112,11 +112,6 @@ function table.remove_index(tbl, index) tbl[count] = nil end ---- Removes an item from an array in O(1) time. Does not guarantee the order of elements. --- @tparam table tbl The array to remove the element from --- @tparam number index Must be >= 0. The case where index > #tbl is handled. -table.fast_remove = table.remove_index - --- Return the key which holds this element element -- @tparam table tbl The table to search -- @param element The element to find @@ -428,7 +423,6 @@ table.deep_copy = table.deepcopy -- added by util table.deep_merge = util.merge --- Determines if two tables are structurally equal. --- Notice: tables that are LuaObjects or contain LuaObjects won't be compared correctly, use == operator for LuaObjects -- @tparam table tbl1 The first table -- @tparam table tbl2 The second table -- @treturn boolean True if the tables are equal