mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Merge Game, FlyingText, Common and table
This commit is contained in:
26
.luarc.json
26
.luarc.json
@@ -1,9 +1,8 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
"completion.requireSeparator": "/",
|
"completion.requireSeparator": "/",
|
||||||
"doc.privateName": [ "__" ],
|
"doc.privateName": [ "__(\\w+)" ],
|
||||||
"doc.protectedName": [ "_" ],
|
"doc.protectedName": [ "_(\\w+)" ],
|
||||||
"runtime.version": "Lua 5.2",
|
|
||||||
"runtime.pluginArgs": [
|
"runtime.pluginArgs": [
|
||||||
"--clusterio-modules"
|
"--clusterio-modules"
|
||||||
],
|
],
|
||||||
@@ -40,7 +39,15 @@
|
|||||||
"type" : "pattern",
|
"type" : "pattern",
|
||||||
"param": "_?_?(\\w+)",
|
"param": "_?_?(\\w+)",
|
||||||
"$1": "snake_case"
|
"$1": "snake_case"
|
||||||
}, "pascal_case"],
|
}, {
|
||||||
|
"type" : "pattern",
|
||||||
|
"param": "_?_?(\\w+)",
|
||||||
|
"$1": "upper_snake_case"
|
||||||
|
}, {
|
||||||
|
"type" : "pattern",
|
||||||
|
"param": "_?_?(\\w+)",
|
||||||
|
"$1": "pascal_case"
|
||||||
|
}],
|
||||||
"function_param_name_style": [{
|
"function_param_name_style": [{
|
||||||
"type" : "pattern",
|
"type" : "pattern",
|
||||||
"param": "_?_?(\\w+)?",
|
"param": "_?_?(\\w+)?",
|
||||||
@@ -62,9 +69,14 @@
|
|||||||
"$1": "snake_case"
|
"$1": "snake_case"
|
||||||
}],
|
}],
|
||||||
"global_variable_name_style": [{
|
"global_variable_name_style": [{
|
||||||
"type": "ignore",
|
"type" : "pattern",
|
||||||
"param": ["_VERSION"]
|
"param": "_?_?(\\w+)",
|
||||||
}, "snake_case", "upper_snake_case" ],
|
"$1": "snake_case"
|
||||||
|
}, {
|
||||||
|
"type" : "pattern",
|
||||||
|
"param": "_?_?(\\w+)",
|
||||||
|
"$1": "upper_snake_case"
|
||||||
|
}],
|
||||||
"module_name_style": [ "pascal_case", "snake_case" ],
|
"module_name_style": [ "pascal_case", "snake_case" ],
|
||||||
"require_module_name_style": [ "pascal_case", "snake_case" ],
|
"require_module_name_style": [ "pascal_case", "snake_case" ],
|
||||||
"class_name_style": "pascal_case",
|
"class_name_style": "pascal_case",
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ setmetatable(rcon_statics, { __index = _G })
|
|||||||
setmetatable(rcon_env, { __index = rcon_statics })
|
setmetatable(rcon_env, { __index = rcon_statics })
|
||||||
|
|
||||||
--- Some common static values which can be added now
|
--- Some common static values which can be added now
|
||||||
|
--- @diagnostic disable: name-style-check
|
||||||
rcon_statics.Async = Async
|
rcon_statics.Async = Async
|
||||||
rcon_statics.ExpUtil = ExpUtil
|
rcon_statics.ExpUtil = ExpUtil
|
||||||
rcon_statics.Commands = Commands
|
rcon_statics.Commands = Commands
|
||||||
rcon_statics.Clustorio = Clustorio
|
rcon_statics.Clustorio = Clustorio
|
||||||
rcon_statics.output = Commands.print
|
rcon_statics.output = Commands.print
|
||||||
rcon_statics.ipc = Clustorio.send_json
|
rcon_statics.ipc = Clustorio.send_json
|
||||||
|
--- @diagnostic enable: name-style-check
|
||||||
|
|
||||||
--- Some common callback values which are useful when a player uses the command
|
--- Some common callback values which are useful when a player uses the command
|
||||||
function rcon_callbacks.player(player) return player end
|
function rcon_callbacks.player(player) return player end
|
||||||
|
|||||||
@@ -364,9 +364,11 @@ function Commands.print(message, color, sound)
|
|||||||
if not player then
|
if not player then
|
||||||
rcon.print(ExpUtil.format_any(message))
|
rcon.print(ExpUtil.format_any(message))
|
||||||
else
|
else
|
||||||
local formatted = ExpUtil.format_any(message, nil, 20)
|
local formatted = ExpUtil.format_any(message, { max_line_count = 20 })
|
||||||
player.print(formatted, color or Color.white)
|
player.print(formatted, {
|
||||||
player.play_sound{ path = sound or "utility/scenario_message" }
|
color = color or Color.white,
|
||||||
|
sound_path = sound or "utility/scenario_message",
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
0
exp_legacy/module/async.lua
Normal file
0
exp_legacy/module/async.lua
Normal file
@@ -47,7 +47,7 @@ return {
|
|||||||
end
|
end
|
||||||
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,
|
end,
|
||||||
["players"] = function(_player, _is_command)
|
["players"] = function(_player, _is_command)
|
||||||
return { "chat-bot.players", #game.players }
|
return { "chat-bot.players", #game.players }
|
||||||
@@ -70,7 +70,7 @@ return {
|
|||||||
names[#names + 1] = next_player.name
|
names[#names + 1] = next_player.name
|
||||||
end
|
end
|
||||||
|
|
||||||
return { "chat-bot.blame", table.get_random_dictionary_entry(names) }
|
return { "chat-bot.blame", table.get_random(names) }
|
||||||
end,
|
end,
|
||||||
["magic"] = { "chat-bot.magic" },
|
["magic"] = { "chat-bot.magic" },
|
||||||
["aids"] = { "chat-bot.aids" },
|
["aids"] = { "chat-bot.aids" },
|
||||||
@@ -78,7 +78,7 @@ return {
|
|||||||
["lenny"] = { "chat-bot.lenny" },
|
["lenny"] = { "chat-bot.lenny" },
|
||||||
["hodor"] = function(_player, _is_command)
|
["hodor"] = function(_player, _is_command)
|
||||||
local options = { "?", ".", "!", "!!!" }
|
local options = { "?", ".", "!", "!!!" }
|
||||||
return { "chat-bot.hodor", table.get_random_dictionary_entry(options) }
|
return { "chat-bot.hodor", table.get_random(options) }
|
||||||
end,
|
end,
|
||||||
["evolution"] = function(_player, _is_command)
|
["evolution"] = function(_player, _is_command)
|
||||||
return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].evolution_factor) }
|
return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].evolution_factor) }
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ see ./expcore/commands.lua for more details
|
|||||||
surface
|
surface
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
||||||
|
|
||||||
-- luacheck:ignore 212/player
|
-- luacheck:ignore 212/player
|
||||||
@@ -37,7 +38,7 @@ end)
|
|||||||
|
|
||||||
Commands.add_parse("string-options", function(input, player, reject, options)
|
Commands.add_parse("string-options", function(input, player, reject, options)
|
||||||
if not input then return end -- nil check
|
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, ", ") }
|
return option or reject{ "expcore-commands.reject-string-options", table.concat(options, ", ") }
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
player-role-alive
|
player-role-alive
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
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")
|
require("modules.exp_legacy.config.expcore.command_general_parse")
|
||||||
|
|
||||||
-- luacheck:ignore 212/player
|
-- luacheck:ignore 212/player
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
-- the key used for the name of the button is the permission name used by the role system;
|
-- the key used for the name of the button is the permission name used by the role system;
|
||||||
-- @config Player-List
|
-- @config Player-List
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
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 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 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 Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
|
||||||
local Colors = require("modules/exp_util/include/color")
|
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 SelectedPlayer, SelectedAction
|
||||||
local function set_datastores(player, action)
|
local function set_datastores(player, action)
|
||||||
@@ -31,7 +32,7 @@ end
|
|||||||
local function get_action_player_name(player)
|
local function get_action_player_name(player)
|
||||||
local selected_player_name = SelectedPlayer:get(player)
|
local selected_player_name = SelectedPlayer:get(player)
|
||||||
local selected_player = game.players[selected_player_name]
|
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
|
return selected_player_name, selected_player_color
|
||||||
end
|
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 function report_player_callback(player, reason)
|
||||||
local selected_player_name, selected_player_color = get_action_player_name(player)
|
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 }
|
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 })
|
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)
|
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 function warn_player_callback(player, reason)
|
||||||
local selected_player_name, selected_player_color = get_action_player_name(player)
|
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 }
|
game.print{ "expcom-warnings.received", selected_player_color, by_player_name_color, reason }
|
||||||
Warnings.add_warning(selected_player_name, player.name, reason)
|
Warnings.add_warning(selected_player_name, player.name, reason)
|
||||||
end
|
end
|
||||||
@@ -132,7 +133,7 @@ local jail_player = new_button("utility/multiplayer_waiting_icon", { "player-lis
|
|||||||
|
|
||||||
local function jail_player_callback(player, reason)
|
local function jail_player_callback(player, reason)
|
||||||
local selected_player_name, selected_player_color = get_action_player_name(player)
|
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 }
|
game.print{ "expcom-jail.give", selected_player_color, by_player_name_color, reason }
|
||||||
Jail.jail_player(selected_player_name, player.name, reason)
|
Jail.jail_player(selected_player_name, player.name, reason)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,12 +15,6 @@ end
|
|||||||
log("[START] -----| Explosive Gaming Scenario Loader |-----")
|
log("[START] -----| Explosive Gaming Scenario Loader |-----")
|
||||||
log("[INFO] Setting up lua environment")
|
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
|
-- Please go to config/file_loader.lua to edit the files that are loaded
|
||||||
log("[INFO] Reading loader config")
|
log("[INFO] Reading loader config")
|
||||||
local files = require("modules.exp_legacy.config._file_loader")
|
local files = require("modules.exp_legacy.config._file_loader")
|
||||||
|
|||||||
@@ -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 trace = debug.traceback
|
||||||
|
|
||||||
local Commands = {
|
local Commands = {
|
||||||
@@ -203,12 +204,29 @@ local Commands = {
|
|||||||
authenticators = {},
|
authenticators = {},
|
||||||
--- Used to store default functions which are common parse function such as player or number in range
|
--- Used to store default functions which are common parse function such as player or number in range
|
||||||
parsers = {},
|
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
|
--- The command prototype which stores all command defining functions
|
||||||
_prototype = {},
|
_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.
|
--- Authentication.
|
||||||
-- Functions that control who can use commands
|
-- Functions that control who can use commands
|
||||||
-- @section auth
|
-- @section auth
|
||||||
@@ -658,8 +676,8 @@ return 'Your message has been printed'
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Commands.success(value)
|
function Commands.success(value)
|
||||||
if value ~= nil then player_return(value) end
|
if value ~= nil then Commands.print(value) end
|
||||||
player_return({ "expcore-commands.command-ran" }, "cyan")
|
Commands.print({ "expcore-commands.command-ran" }, "cyan")
|
||||||
return Commands.defines.success
|
return Commands.defines.success
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -685,7 +703,7 @@ return Commands.error('The player you selected is offline')
|
|||||||
]]
|
]]
|
||||||
function Commands.error(error_message, play_sound)
|
function Commands.error(error_message, play_sound)
|
||||||
error_message = error_message or ""
|
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
|
if play_sound ~= false then
|
||||||
play_sound = play_sound or "utility/wire_pickup"
|
play_sound = play_sound or "utility/wire_pickup"
|
||||||
if game.player then game.player.play_sound{ path = play_sound } end
|
if game.player then game.player.play_sound{ path = play_sound } end
|
||||||
|
|||||||
@@ -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 "<anon>"; argument is of type string expected number"
|
|
||||||
validate_argument_type(value, 'number', 2)
|
|
||||||
|
|
||||||
@usage-- Output: "Bad argument #2 to "<anon>"; "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 "<anon>"
|
|
||||||
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 "<anon>"; argument is of type number expected string or table"
|
|
||||||
validate_argument_type(value, {'string', 'table'}, 2)
|
|
||||||
|
|
||||||
@usage-- Output: "Bad argument #2 to "<anon>"; "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 "<anon>"
|
|
||||||
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 "<anon>"
|
|
||||||
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 "<server>"
|
|
||||||
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 "<Server>"
|
|
||||||
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
|
|
||||||
@@ -129,7 +129,7 @@ end
|
|||||||
--[[-- Connect a player to the given server
|
--[[-- Connect a player to the given server
|
||||||
@tparam LuaPlayer player The player that you want to request to join a different 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 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
|
@usage-- Request that a player joins a different server
|
||||||
External.request_connection(player, 'eu-01')
|
External.request_connection(player, 'eu-01')
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||||
require("modules.exp_legacy.expcore.gui.helper_functions")
|
require("modules.exp_legacy.expcore.gui.helper_functions")
|
||||||
require("modules.exp_legacy.expcore.gui.core_defines")
|
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.left_flow")
|
||||||
require("modules.exp_legacy.expcore.gui.defines")
|
require("modules.exp_legacy.expcore.gui.defines")
|
||||||
|
|
||||||
local Roles = _C.opt_require("modules.exp_legacy.expcore.roles")
|
local Roles = ExpUtil.optional_require("modules.exp_legacy.expcore.roles")
|
||||||
local Event = _C.opt_require("modules/exp_legacy/utils/event")
|
local Event = ExpUtil.optional_require("modules/exp_legacy/utils/event")
|
||||||
|
|
||||||
if Roles and Event then
|
if Roles and Event then
|
||||||
Event.add(Roles.events.on_role_assigned, function(e)
|
Event.add(Roles.events.on_role_assigned, function(e)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@module Gui
|
@module Gui
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||||
local mod_gui = require "mod-gui"
|
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)
|
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
|
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
|
self.open_on_join = open_on_join or false
|
||||||
table.insert(Gui.left_elements, self)
|
table.insert(Gui.left_elements, self)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@module Gui
|
@module Gui
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
|
|
||||||
local Gui = {
|
local Gui = {
|
||||||
@@ -107,7 +108,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Gui.element(element_define)
|
function Gui.element(element_define)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
-- Set the metatable to allow access to register events
|
-- Set the metatable to allow access to register events
|
||||||
local element = setmetatable({}, Gui._mt_element)
|
local element = setmetatable({}, Gui._mt_element)
|
||||||
|
|
||||||
@@ -182,7 +183,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Gui._prototype_element:style(style_define)
|
function Gui._prototype_element:style(style_define)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
-- Add the definition function
|
-- Add the definition function
|
||||||
if type(style_define) == "table" then
|
if type(style_define) == "table" then
|
||||||
Gui.debug_info[self.uid].style = style_define
|
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
|
@treturn table the element define is returned to allow for event handlers to be registered
|
||||||
]]
|
]]
|
||||||
function Gui._prototype_element:static_name(name)
|
function Gui._prototype_element:static_name(name)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
if name == Gui.unique_static_name then
|
if name == Gui.unique_static_name then
|
||||||
self.name = "ExpGui_" .. tostring(self.uid)
|
self.name = "ExpGui_" .. tostring(self.uid)
|
||||||
else
|
else
|
||||||
@@ -255,7 +256,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Gui._prototype_element:on_event(event_name, handler)
|
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)
|
table.insert(Gui.debug_info[self.uid].events, event_name)
|
||||||
Gui.events[event_name] = event_name
|
Gui.events[event_name] = event_name
|
||||||
self[event_name] = handler
|
self[event_name] = handler
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@module Gui
|
@module Gui
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||||
local mod_gui = require "mod-gui" --- @dep mod-gui
|
local mod_gui = require "mod-gui" --- @dep mod-gui
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Gui._prototype_element:add_to_top_flow(authenticator)
|
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
|
if not self.name then error("Elements for the top flow must have a static name") end
|
||||||
self.authenticator = authenticator or true
|
self.authenticator = authenticator or true
|
||||||
table.insert(Gui.top_elements, self)
|
table.insert(Gui.top_elements, self)
|
||||||
|
|||||||
@@ -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")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
||||||
local Async = require("modules/exp_util/async")
|
local Async = require("modules/exp_util/async")
|
||||||
|
|
||||||
local PermissionsGroups = {
|
local PermissionsGroups = {
|
||||||
@@ -91,8 +90,6 @@ local group = Groups.get_group_from_player(game.player)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function PermissionsGroups.get_group_from_player(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
|
local group = player.permission_group
|
||||||
if group then
|
if group then
|
||||||
return PermissionsGroups.groups[group.name]
|
return PermissionsGroups.groups[group.name]
|
||||||
@@ -125,7 +122,6 @@ Groups.set_player_group(game.player, 'Admin')
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function PermissionsGroups.set_player_group(player, group)
|
function PermissionsGroups.set_player_group(player, group)
|
||||||
player = Game.get_player_from_any(player)
|
|
||||||
group = PermissionsGroups.get_group_by_name(group)
|
group = PermissionsGroups.get_group_by_name(group)
|
||||||
if not group or not player then return false end
|
if not group or not player then return false end
|
||||||
group:add_player(player)
|
group:add_player(player)
|
||||||
@@ -285,7 +281,6 @@ group:add_player(game.player)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function PermissionsGroups._prototype:add_player(player)
|
function PermissionsGroups._prototype:add_player(player)
|
||||||
player = Game.get_player_from_any(player)
|
|
||||||
local group = self:get_raw()
|
local group = self:get_raw()
|
||||||
if not group or not player then return false end
|
if not group or not player then return false end
|
||||||
add_to_permission_group_async(group, player)
|
add_to_permission_group_async(group, player)
|
||||||
@@ -301,7 +296,6 @@ group:remove_player(game.player)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function PermissionsGroups._prototype:remove_player(player)
|
function PermissionsGroups._prototype:remove_player(player)
|
||||||
player = Game.get_player_from_any(player)
|
|
||||||
local group = self:get_raw()
|
local group = self:get_raw()
|
||||||
if not group or not player then return false end
|
if not group or not player then return false end
|
||||||
remove_from_permission_group_async(group, player)
|
remove_from_permission_group_async(group, player)
|
||||||
|
|||||||
@@ -108,13 +108,14 @@ Roles.define_role_order{
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Async = require("modules/exp_util/async")
|
local Async = require("modules/exp_util/async")
|
||||||
local Storage = require("modules/exp_util/storage")
|
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")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Groups = require("modules.exp_legacy.expcore.permission_groups")
|
||||||
local Groups = require("modules.exp_legacy.expcore.permission_groups") --- @dep expcore.permission_groups
|
|
||||||
local Colours = require("modules/exp_util/include/color")
|
local Colours = ExpUtil.color
|
||||||
local write_json = _C.write_json --- @dep expcore.common
|
local write_json = ExpUtil.write_json
|
||||||
|
|
||||||
local Roles = {
|
local Roles = {
|
||||||
_prototype = {},
|
_prototype = {},
|
||||||
@@ -319,7 +320,6 @@ local roles = Roles.get_player_roles(game.player)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Roles.get_player_roles(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
|
if not player then return { Roles.config.roles[Roles.config.internal.root] } end
|
||||||
local roles = Roles.config.players[player.name] or {}
|
local roles = Roles.config.players[player.name] or {}
|
||||||
local default = Roles.config.roles[Roles.config.internal.default]
|
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)
|
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 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)
|
-- Convert the roles into a table (allows for optional array)
|
||||||
if type(roles) ~= "table" or roles.name then
|
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
|
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 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 {}
|
local assign_later = Roles.config.deferred_roles[valid_player.name] or {}
|
||||||
for _, role in ipairs(role_objects) do
|
for _, role in ipairs(role_objects) do
|
||||||
local role_change = assign_later[role.name]
|
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)
|
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 skip_checks and not valid_player then return end
|
||||||
if not player then return end
|
if not player then return end
|
||||||
|
|
||||||
@@ -626,7 +625,7 @@ Roles.define_role_order{
|
|||||||
]]
|
]]
|
||||||
function Roles.define_role_order(order)
|
function Roles.define_role_order(order)
|
||||||
-- Clears and then rebuilds the order table
|
-- Clears and then rebuilds the order table
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
Roles.config.order = {}
|
Roles.config.order = {}
|
||||||
local done = {}
|
local done = {}
|
||||||
for index, role in ipairs(order) do
|
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)
|
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
|
if Roles.config.roles[name] then return error("Role name is non unique") end
|
||||||
local role = setmetatable({
|
local role = setmetatable({
|
||||||
name = name,
|
name = name,
|
||||||
@@ -885,7 +884,7 @@ role:set_permission_group('Admin')
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Roles._prototype:set_permission_group(name, use_factorio_api)
|
function Roles._prototype:set_permission_group(name, use_factorio_api)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
if use_factorio_api then
|
if use_factorio_api then
|
||||||
self.permission_group = { true, name }
|
self.permission_group = { true, name }
|
||||||
else
|
else
|
||||||
@@ -906,7 +905,7 @@ role:set_parent('Guest')
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Roles._prototype:set_parent(role)
|
function Roles._prototype:set_parent(role)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
self.parent = role
|
self.parent = role
|
||||||
role = Roles.get_role_from_any(role)
|
role = Roles.get_role_from_any(role)
|
||||||
if not role then return self end
|
if not role then return self end
|
||||||
@@ -926,7 +925,7 @@ end)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Roles._prototype:set_auto_assign_condition(callback)
|
function Roles._prototype:set_auto_assign_condition(callback)
|
||||||
_C.error_if_runtime()
|
ExpUtil.assert_not_runtime()
|
||||||
self.auto_assign_condition = true
|
self.auto_assign_condition = true
|
||||||
Roles.config.auto_assign[self.name] = callback
|
Roles.config.auto_assign[self.name] = callback
|
||||||
return self
|
return self
|
||||||
@@ -972,7 +971,7 @@ role:add_player(game.player)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
function Roles._prototype:add_player(player, skip_check, skip_event)
|
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
|
-- Default role cant have players added or removed
|
||||||
if self.name == Roles.config.internal.default then return end
|
if self.name == Roles.config.internal.default then return end
|
||||||
-- Check the player is valid, can be skipped but a name must be given
|
-- 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)
|
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
|
-- Default role cant have players added or removed
|
||||||
if self.name == Roles.config.internal.default then return end
|
if self.name == Roles.config.internal.default then return end
|
||||||
-- Check the player is valid, can be skipped but a name must be given
|
-- Check the player is valid, can be skipped but a name must be given
|
||||||
|
|||||||
@@ -2,12 +2,10 @@
|
|||||||
-- also displays a ping above users who are named in the message
|
-- also displays a ping above users who are named in the message
|
||||||
-- @addon Chat-Popups
|
-- @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 Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local config = require("modules.exp_legacy.config.popup_messages") --- @dep config.popup_messages
|
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)
|
Event.add(defines.events.on_console_chat, function(event)
|
||||||
if not event.player_index or event.player_index < 1 then return end
|
if not event.player_index or event.player_index < 1 then return end
|
||||||
local player = game.players[event.player_index]
|
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
|
-- Sends the message as text above them
|
||||||
if config.show_player_messages then
|
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
|
end
|
||||||
|
|
||||||
if not config.show_player_mentions then return 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
|
for _, mentioned_player in pairs(game.connected_players) do
|
||||||
if mentioned_player.index ~= player.index then
|
if mentioned_player.index ~= player.index then
|
||||||
if search_string:find(mentioned_player.name:lower(), 1, true) 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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
-- also shows player health when a player is attacked
|
-- also shows player health when a player is attacked
|
||||||
-- @addon Damage-Popups
|
-- @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 Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local config = require("modules.exp_legacy.config.popup_messages") --- @dep config.popup_messages
|
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
|
-- Outputs the message as floating text
|
||||||
if message then
|
if message then
|
||||||
FloatingText.print(
|
FlyingText.create{
|
||||||
entity.surface,
|
text = message,
|
||||||
position,
|
position = position,
|
||||||
message,
|
color = text_colour,
|
||||||
text_colour
|
}
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
--- Makes markers on the map where places have died and reclaims items if not recovered
|
--- Makes markers on the map where places have died and reclaims items if not recovered
|
||||||
-- @addon Death-Logger
|
-- @addon Death-Logger
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Storage = require("modules/exp_util/storage")
|
local Storage = require("modules/exp_util/storage")
|
||||||
local config = require("modules.exp_legacy.config.death_logger") --- @dep config.death_logger
|
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
|
-- Max amount of ticks a corpse can be alive
|
||||||
local corpse_lifetime = 60 * 60 * 15
|
local corpse_lifetime = 60 * 60 * 15
|
||||||
@@ -17,12 +17,14 @@ Storage.register(deaths, function(tbl)
|
|||||||
deaths = tbl
|
deaths = tbl
|
||||||
end)
|
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
|
--- Creates a new death marker and saves it to the given death
|
||||||
local function create_map_tag(death)
|
local function create_map_tag(death)
|
||||||
local player = game.players[death.player_name]
|
local player = game.players[death.player_name]
|
||||||
local message = player.name .. " died"
|
local message = player.name .. " died"
|
||||||
if config.include_time_of_death then
|
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
|
message = message .. " at " .. time
|
||||||
end
|
end
|
||||||
death.tag = player.force.add_chart_tag(player.surface, {
|
death.tag = player.force.add_chart_tag(player.surface, {
|
||||||
@@ -60,14 +62,21 @@ local function check_map_tags()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- when a player dies a new death is added to the records and a map marker is made
|
-- 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)
|
Event.add(defines.events.on_player_died, function(event)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
local corpse = player.surface.find_entity("character-corpse", player.position)
|
local corpse = player.surface.find_entity("character-corpse", player.position)
|
||||||
if not corpse or not corpse.valid then return end
|
if not corpse or not corpse.valid then return end
|
||||||
if config.use_chests_as_bodies then
|
if config.use_chests_as_bodies then
|
||||||
local items = corpse.get_inventory(defines.inventory.character_corpse)
|
local inventory = assert(corpse.get_inventory(defines.inventory.character_corpse))
|
||||||
local chest = move_items(items, corpse.surface, corpse.position)
|
local chest = ExpUtil.transfer_inventory_to_surface{
|
||||||
chest.destructible = false
|
inventory = inventory,
|
||||||
|
surface = corpse.surface,
|
||||||
|
position = corpse.position,
|
||||||
|
name = "iron-chest",
|
||||||
|
allow_creation = true,
|
||||||
|
}
|
||||||
|
|
||||||
corpse.destroy()
|
corpse.destroy()
|
||||||
corpse = chest
|
corpse = chest
|
||||||
end
|
end
|
||||||
@@ -139,10 +148,16 @@ if config.show_map_markers then
|
|||||||
end
|
end
|
||||||
|
|
||||||
if config.auto_collect_bodies then
|
if config.auto_collect_bodies then
|
||||||
|
--- @param event EventData.on_character_corpse_expired
|
||||||
Event.add(defines.events.on_character_corpse_expired, function(event)
|
Event.add(defines.events.on_character_corpse_expired, function(event)
|
||||||
local corpse = event.corpse
|
local corpse = event.corpse
|
||||||
local items = corpse.get_inventory(defines.inventory.character_corpse)
|
local inventory = assert(corpse.get_inventory(defines.inventory.character_corpse))
|
||||||
move_items(items, corpse.surface, { x = 0, y = 0 })
|
ExpUtil.transfer_inventory_to_surface{
|
||||||
|
inventory = inventory,
|
||||||
|
surface = corpse.surface,
|
||||||
|
name = "iron-chest",
|
||||||
|
allow_creation = true,
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
--- Log certain actions into a file when events are triggered
|
--- Log certain actions into a file when events are triggered
|
||||||
-- @addon Deconlog
|
-- @addon Deconlog
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
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 format_number = require("util").format_number --- @dep util
|
||||||
local config = require("modules.exp_legacy.config.deconlog") --- @dep config.deconlog
|
local config = require("modules.exp_legacy.config.deconlog") --- @dep config.deconlog
|
||||||
|
|
||||||
local filepath = "log/decon.log"
|
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)
|
local function add_log(data)
|
||||||
game.write_file(filepath, data .. "\n", true, 0) -- write data
|
game.write_file(filepath, data .. "\n", true, 0) -- write data
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_secs()
|
local function get_secs()
|
||||||
return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true })
|
return seconds_time_format(game.tick)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function pos_to_string(pos)
|
local function pos_to_string(pos)
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
--- Sends alert messages to our discord server when certain events are triggered
|
--- Sends alert messages to our discord server when certain events are triggered
|
||||||
-- @addon Discord-Alerts
|
-- @addon Discord-Alerts
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Colors = require("modules/exp_util/include/color")
|
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 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)
|
local function append_playtime(player_name)
|
||||||
if not config.show_playtime then
|
if not config.show_playtime then
|
||||||
@@ -19,7 +21,7 @@ local function append_playtime(player_name)
|
|||||||
return player_name
|
return player_name
|
||||||
end
|
end
|
||||||
|
|
||||||
return player.name .. " (" .. format_time(player.online_time, playtime_format) .. ")"
|
return player.name .. " (" .. playtime_format(player.online_time) .. ")"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_player_name(event)
|
local function get_player_name(event)
|
||||||
@@ -48,7 +50,7 @@ local function emit_event(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local tick = args.tick or game.tick
|
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 players_online = 0
|
||||||
local admins_online = 0
|
local admins_online = 0
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
--- Will move players items to spawn when they are banned or kicked, option to clear on leave
|
--- Will move players items to spawn when they are banned or kicked, option to clear on leave
|
||||||
-- @addon Inventory-Clear
|
-- @addon Inventory-Clear
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
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 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 function clear_items(event)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
local inv = player.get_main_inventory() --- @cast inv -nil
|
local inventory = assert(player.get_main_inventory())
|
||||||
move_items_stack(inv)
|
ExpUtil.transfer_inventory_to_surface{
|
||||||
inv.clear()
|
inventory = inventory,
|
||||||
|
surface = game.surfaces[1],
|
||||||
|
name = "iron-chest",
|
||||||
|
allow_creation = true,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, event_name in ipairs(events) do Event.add(event_name, clear_items) end
|
for _, event_name in ipairs(events) do Event.add(event_name, clear_items) end
|
||||||
|
|||||||
@@ -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 = 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" } }
|
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
|
for _, e in pairs(entities) do
|
||||||
if (e.position.x > ep.x) and (e.position.y == ep.y) then
|
if (e.position.x > ep.x) and (e.position.y == ep.y) then
|
||||||
|
|||||||
@@ -1,26 +1,36 @@
|
|||||||
--- Disable new players from having certain items in their inventory, most commonly nukes
|
--- Disable new players from having certain items in their inventory, most commonly nukes
|
||||||
-- @addon Nukeprotect
|
-- @addon Nukeprotect
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local config = require("modules.exp_legacy.config.nukeprotect") --- @dep config.nukeprotect
|
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)
|
local function check_items(player, type)
|
||||||
-- if the player has perms to be ignored, then they should be
|
-- 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 config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end
|
||||||
-- if the players
|
-- if the players
|
||||||
if config.ignore_admins and player.admin then return end
|
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
|
for i = 1, #inventory do
|
||||||
local item = inventory[i]
|
local item = inventory[i]
|
||||||
if item.valid and item.valid_for_read and config[tostring(type)][item.name] then
|
if item.valid and item.valid_for_read and config[tostring(type)][item.name] then
|
||||||
player.print{ "nukeprotect.found", { "item-name." .. item.name } }
|
player.print{ "nukeprotect.found", { "item-name." .. item.name } }
|
||||||
-- insert the items into the table so all items are transferred at once
|
items[#items + 1] = item
|
||||||
move_items_stack{ item }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ExpUtil.move_items_to_surface{
|
||||||
|
items = items,
|
||||||
|
surface = player.surface,
|
||||||
|
allow_creation = true,
|
||||||
|
name = "iron-chest",
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, inventory in ipairs(config.inventories) do
|
for _, inventory in ipairs(config.inventories) do
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
--- When a player triggers protection multiple times they are automatically jailed
|
--- When a player triggers protection multiple times they are automatically jailed
|
||||||
-- @addon protection-jail
|
-- @addon protection-jail
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Storage = require("modules/exp_util/storage") --- @dep utils.global
|
local Storage = require("modules/exp_util/storage") --- @dep utils.global
|
||||||
local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
|
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 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
|
--- Stores how many times the repeat violation was triggered
|
||||||
local repeat_count = {}
|
local repeat_count = {}
|
||||||
@@ -29,7 +30,7 @@ Event.add(Protection.events.on_repeat_violation, function(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local player_name_color = format_chat_player_name(player)
|
local player_name_color = format_player_name(player)
|
||||||
Jail.jail_player(player, "<protection>", "Removed too many protected entities, please wait for a moderator.")
|
Jail.jail_player(player, "<protection>", "Removed too many protected entities, please wait for a moderator.")
|
||||||
game.print{ "protection-jail.jail", player_name_color }
|
game.print{ "protection-jail.jail", player_name_color }
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -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
|
--- When a player is reported, the player is automatically jailed if the combined playtime of the reporters exceeds the reported player
|
||||||
-- @addon report-jail
|
-- @addon report-jail
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
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 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 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
|
--- Returns the playtime of the reporter. Used when calculating the total playtime of all reporters
|
||||||
local function reporter_playtime(_, by_player_name, _)
|
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
|
-- player less than 30 min
|
||||||
if (Reports.count_reports(player) > 1) and (total_playtime > math.max(player.online_time * 2, 108000)) then
|
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, "<reports>", "Reported by too many players, please wait for a moderator.")
|
Jail.jail_player(player, "<reports>", "Reported by too many players, please wait for a moderator.")
|
||||||
game.print{ "report-jail.jail", player_name_color }
|
game.print{ "report-jail.jail", player_name_color }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
-- @addon Scorched-Earth
|
-- @addon Scorched-Earth
|
||||||
|
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
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
|
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
|
-- 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
|
||||||
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
|
-- Will degrade a tile down to the next tile when called
|
||||||
local function degrade(surface, position)
|
local function degrade(surface, position)
|
||||||
local tile = surface.get_tile(position)
|
local tile = surface.get_tile(position)
|
||||||
@@ -80,19 +72,6 @@ local function get_tile_strength(surface, position)
|
|||||||
return strength / 9
|
return strength / 9
|
||||||
end
|
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
|
-- 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)
|
Event.add(defines.events.on_player_changed_position, function(event)
|
||||||
local player = game.players[event.player_index]
|
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
|
if get_probability(strength) > math.random() then
|
||||||
degrade(surface, position)
|
degrade(surface, position)
|
||||||
end
|
end
|
||||||
if debug_players[player.name] then
|
|
||||||
debug_get_tile_strength(surface, position)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- When an entity is build there is a much higher chance that the tiles will degrade
|
-- 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)
|
degrade_entity(entity)
|
||||||
end
|
end
|
||||||
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
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
@commands Admin-Chat
|
@commands Admin-Chat
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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")
|
require("modules.exp_legacy.config.expcore.command_general_parse")
|
||||||
|
|
||||||
--- Sends a message in chat that only admins can see
|
--- 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")
|
:set_flag("admin_only")
|
||||||
:add_alias("ac")
|
:add_alias("ac")
|
||||||
:register(function(player, message)
|
: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
|
for _, return_player in pairs(game.connected_players) do
|
||||||
if return_player.admin then
|
if return_player.admin then
|
||||||
return_player.print{ "expcom-admin-chat.format", player_name_colour, message }
|
return_player.print{ "expcom-admin-chat.format", player_name_colour, message }
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
@commands Clear-Inventory
|
@commands Clear-Inventory
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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")
|
require("modules.exp_legacy.config.expcore.command_role_parse")
|
||||||
|
|
||||||
--- Clears a players inventory
|
--- Clears a players inventory
|
||||||
@@ -14,10 +14,15 @@ Commands.new_command("clear-inventory", { "expcom-clr-inv.description" }, "Clear
|
|||||||
:add_param("player", false, "player-role")
|
:add_param("player", false, "player-role")
|
||||||
:add_alias("clear-inv", "move-inventory", "move-inv")
|
:add_alias("clear-inv", "move-inventory", "move-inv")
|
||||||
:register(function(_, player)
|
:register(function(_, player)
|
||||||
local inv = player.get_main_inventory()
|
local inventory = player.get_main_inventory()
|
||||||
if not inv then
|
if not inventory then
|
||||||
return Commands.error{ "expcore-commands.reject-player-alive" }
|
return Commands.error{ "expcore-commands.reject-player-alive" }
|
||||||
end
|
end
|
||||||
move_items_stack(inv)
|
|
||||||
inv.clear()
|
ExpUtil.transfer_inventory_to_surface{
|
||||||
|
inventory = inventory,
|
||||||
|
surface = player.surface,
|
||||||
|
name = "iron-chest",
|
||||||
|
allow_creation = true,
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
@commands Interface
|
@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 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
|
-- modules that are loaded into the interface env to be accessed
|
||||||
local interface_modules = {
|
local interface_modules = {
|
||||||
["Commands"] = Commands,
|
["Commands"] = Commands,
|
||||||
["output"] = _C.player_return,
|
["output"] = Commands.print,
|
||||||
["Group"] = "expcore.permission_groups",
|
["Group"] = "expcore.permission_groups",
|
||||||
["Roles"] = "expcore.roles",
|
["Roles"] = "expcore.roles",
|
||||||
["Gui"] = "expcore.gui",
|
["Gui"] = "expcore.gui",
|
||||||
@@ -20,7 +21,7 @@ local interface_modules = {
|
|||||||
-- loads all the modules given in the above table
|
-- loads all the modules given in the above table
|
||||||
for key, value in pairs(interface_modules) do
|
for key, value in pairs(interface_modules) do
|
||||||
if type(value) == "string" then
|
if type(value) == "string" then
|
||||||
interface_modules[key] = _C.opt_require(value)
|
interface_modules[key] = ExpUtil.optional_require(value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
@commands Jail
|
@commands Jail
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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 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")
|
require("modules.exp_legacy.config.expcore.command_role_parse")
|
||||||
|
|
||||||
--- Puts a player into jail and removes all other roles.
|
--- 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()
|
:enable_auto_concat()
|
||||||
:register(function(player, action_player, reason)
|
:register(function(player, action_player, reason)
|
||||||
reason = reason or "Non Given."
|
reason = reason or "Non Given."
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_player)
|
||||||
local by_player_name_color = format_chat_player_name(player)
|
local by_player_name_color = format_player_name(player)
|
||||||
local player_name = player and player.name or "<server>"
|
local player_name = player and player.name or "<server>"
|
||||||
if Jail.jail_player(action_player, player_name, reason) then
|
if Jail.jail_player(action_player, player_name, reason) then
|
||||||
game.print{ "expcom-jail.give", action_player_name_color, by_player_name_color, reason }
|
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")
|
:add_alias("clear-jail", "remove-jail")
|
||||||
:enable_auto_concat()
|
:enable_auto_concat()
|
||||||
:register(function(player, action_player)
|
:register(function(player, action_player)
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_player)
|
||||||
local by_player_name_color = format_chat_player_name(player)
|
local by_player_name_color = format_player_name(player)
|
||||||
local player_name = player and player.name or "<server>"
|
local player_name = player and player.name or "<server>"
|
||||||
if Jail.unjail_player(action_player, player_name) then
|
if Jail.unjail_player(action_player, player_name) then
|
||||||
game.print{ "expcom-jail.remove", action_player_name_color, by_player_name_color }
|
game.print{ "expcom-jail.remove", action_player_name_color, by_player_name_color }
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
@commands LastLocation
|
@commands LastLocation
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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")
|
require("modules.exp_legacy.config.expcore.command_general_parse")
|
||||||
|
|
||||||
--- Get the last location of a player.
|
--- Get the last location of a player.
|
||||||
@@ -14,6 +15,6 @@ Commands.new_command("last-location", { "expcom-lastlocation.description" }, "Se
|
|||||||
:add_alias("location")
|
:add_alias("location")
|
||||||
:add_param("player", false, "player")
|
:add_param("player", false, "player")
|
||||||
:register(function(_, action_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) }
|
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)
|
end)
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
@commands Protection
|
@commands Protection
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Storage = require("modules/exp_util/storage")
|
local Storage = require("modules/exp_util/storage")
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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 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
|
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
|
--- When there is a repeat offence print it in chat
|
||||||
Event.add(EntityProtection.events.on_repeat_violation, function(event)
|
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 })
|
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)
|
end)
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
@commands Rainbow
|
@commands Rainbow
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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)
|
local function step_component(c1, c2)
|
||||||
if c1 < 0 then
|
if c1 < 0 then
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
@commands Reports
|
@commands Reports
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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 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")
|
require("modules.exp_legacy.config.expcore.command_general_parse")
|
||||||
|
|
||||||
--- Print a message to all players who match the value of admin
|
--- 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")
|
:add_alias("report-player")
|
||||||
:enable_auto_concat()
|
:enable_auto_concat()
|
||||||
:register(function(player, action_player, reason)
|
:register(function(player, action_player, reason)
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_player)
|
||||||
local by_player_name_color = format_chat_player_name(player)
|
local by_player_name_color = format_player_name(player)
|
||||||
if Reports.report_player(action_player, player.name, reason) then
|
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(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 })
|
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)
|
:register(function(_, player)
|
||||||
if player then
|
if player then
|
||||||
local reports = Reports.get_reports(player)
|
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 }
|
Commands.print{ "expcom-report.player-report-title", player_name_color }
|
||||||
for player_name, reason in pairs(reports) do
|
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 }
|
Commands.print{ "expcom-report.list", by_player_name_color, reason }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local user_reports = Reports.user_reports
|
local user_reports = Reports.user_reports
|
||||||
Commands.print{ "expcom-report.player-count-title" }
|
Commands.print{ "expcom-report.player-count-title" }
|
||||||
for player_name in pairs(user_reports) do
|
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)
|
local report_count = Reports.count_reports(player_name)
|
||||||
Commands.print{ "expcom-report.list", player_name_color, report_count }
|
Commands.print{ "expcom-report.list", player_name_color, report_count }
|
||||||
end
|
end
|
||||||
@@ -92,7 +93,7 @@ Commands.new_command("clear-reports", { "expcom-report.description-clear-reports
|
|||||||
return Commands.error{ "expcom-report.not-reported" }
|
return Commands.error{ "expcom-report.not-reported" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_player)
|
||||||
local by_player_name_color = format_chat_player_name(player)
|
local by_player_name_color = format_player_name(player)
|
||||||
game.print{ "expcom-report.removed", action_player_name_color, by_player_name_color }
|
game.print{ "expcom-report.removed", action_player_name_color, by_player_name_color }
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
@commands Roles
|
@commands Roles
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Colours = require("modules/exp_util/include/color")
|
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
|
--- Assigns a role to a player
|
||||||
-- @command assign-role
|
-- @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
|
for index, role in pairs(roles) do
|
||||||
role = Roles.get_role_from_any(role)
|
role = Roles.get_role_from_any(role)
|
||||||
local colour = role.custom_color or Colours.white
|
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
|
if index == 1 then
|
||||||
message = { "expcom-roles.list", role_name }
|
message = { "expcom-roles.list", role_name }
|
||||||
if player then
|
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 }
|
message = { "expcom-roles.list-player", player_name_colour, role_name }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
@commands InventorySearch
|
@commands InventorySearch
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
||||||
local format_number = require("util").format_number --- @dep util
|
local format_number = require("util").format_number --- @dep util
|
||||||
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
|
local format_player_name = ExpUtil.format_player_name_locale
|
||||||
local format_time = _C.format_time
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
require("modules.exp_legacy.config.expcore.command_general_parse")
|
||||||
|
|
||||||
--- Input parse for items by name
|
--- Input parse for items by name
|
||||||
@@ -85,13 +85,15 @@ local function sort_players(players, func)
|
|||||||
return sorted
|
return sorted
|
||||||
end
|
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
|
--- Display to the player the top players which were found
|
||||||
local function display_players(player, players, item)
|
local function display_players(player, players, item)
|
||||||
player.print{ "expcom-inv-search.results-heading", item.name }
|
player.print{ "expcom-inv-search.results-heading", item.name }
|
||||||
for index, data in ipairs(players) do
|
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 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 }
|
player.print{ "expcom-inv-search.results-item", index, player_name_color, amount, time }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,22 +3,28 @@
|
|||||||
@commands Clear Item On Ground
|
@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
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
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")
|
Commands.new_command("clear-item-on-ground", { "expcom-surface-clearing.description-ci" }, "Clear Item On Ground")
|
||||||
:add_param("range", false, "integer-range", 1, 1000)
|
:add_param("range", false, "integer-range", 1, 1000)
|
||||||
:register(function(player, range)
|
: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
|
if e.stack then
|
||||||
-- calling move_items_stack(e.stack) will crash to desktop
|
items[#items + 1] = e.stack
|
||||||
-- https://forums.factorio.com/viewtopic.php?f=7&t=110322
|
|
||||||
copy_items_stack{ e.stack }
|
|
||||||
e.stack.clear()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ExpUtil.move_items_to_surface{
|
||||||
|
items = items,
|
||||||
|
surface = player.surface,
|
||||||
|
allow_creation = true,
|
||||||
|
name = "iron-chest",
|
||||||
|
}
|
||||||
|
|
||||||
return Commands.success
|
return Commands.success
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
@commands Warnings
|
@commands Warnings
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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 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
|
local config = require("modules.exp_legacy.config.warnings") --- @dep config.warnings
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
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()
|
:enable_auto_concat()
|
||||||
:register(function(player, action_player, reason)
|
:register(function(player, action_player, reason)
|
||||||
Warnings.add_warning(action_player, player.name, reason)
|
Warnings.add_warning(action_player, player.name, reason)
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_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", action_player_name_color, by_player_name_color, reason }
|
game.print{ "expcom-warnings.received", action_player_name_color, by_player_name_color, reason }
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -35,10 +36,10 @@ Commands.new_command("get-warnings", { "expcom-warnings.description-get" }, "Get
|
|||||||
if player then
|
if player then
|
||||||
local warnings = Warnings.get_warnings(player)
|
local warnings = Warnings.get_warnings(player)
|
||||||
local script_warnings = Warnings.get_script_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 }
|
Commands.print{ "expcom-warnings.player", player_name_color, #warnings, #script_warnings, config.temp_warning_limit }
|
||||||
for _, warning in ipairs(warnings) do
|
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
|
end
|
||||||
else
|
else
|
||||||
local rtn = {}
|
local rtn = {}
|
||||||
@@ -56,7 +57,7 @@ Commands.new_command("get-warnings", { "expcom-warnings.description-get" }, "Get
|
|||||||
|
|
||||||
Commands.print{ "expcom-warnings.list-title" }
|
Commands.print{ "expcom-warnings.list-title" }
|
||||||
for player_name, warnings in pairs(rtn) do
|
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 }
|
Commands.print{ "expcom-warnings.list", player_name_color, warnings[1], warnings[2], config.temp_warning_limit }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -70,7 +71,7 @@ Commands.new_command("clear-warnings", { "expcom-warnings.description-clear" },
|
|||||||
:register(function(player, action_player)
|
:register(function(player, action_player)
|
||||||
Warnings.clear_warnings(action_player, player.name)
|
Warnings.clear_warnings(action_player, player.name)
|
||||||
Warnings.clear_script_warnings(action_player)
|
Warnings.clear_script_warnings(action_player)
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_player_name(action_player)
|
||||||
local by_player_name_color = format_chat_player_name(player)
|
local by_player_name_color = format_player_name(player)
|
||||||
game.print{ "expcom-warnings.cleared", action_player_name_color, by_player_name_color }
|
game.print{ "expcom-warnings.cleared", action_player_name_color, by_player_name_color }
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
Jail.unjail_player('MrBiter', 'Cooldude2606')
|
Jail.unjail_player('MrBiter', 'Cooldude2606')
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||||
local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game
|
|
||||||
|
|
||||||
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 assign_roles = Roles.assign_player
|
||||||
local unassign_roles = Roles.unassign_player
|
local unassign_roles = Roles.unassign_player
|
||||||
local has_role = Roles.player_has_role
|
local has_role = Roles.player_has_role
|
||||||
@@ -65,7 +64,7 @@ end
|
|||||||
-- @tparam LuaPlayer player the player to check if they are in jail
|
-- @tparam LuaPlayer player the player to check if they are in jail
|
||||||
-- @treturn boolean whether the player is currently in jail
|
-- @treturn boolean whether the player is currently in jail
|
||||||
function Jail.is_jailed(player)
|
function Jail.is_jailed(player)
|
||||||
return has_role(player, "Jail")
|
return has_role(valid_player(player), "Jail")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Moves a player to jail and removes all other roles
|
--- Moves a player to jail and removes all other roles
|
||||||
|
|||||||
@@ -24,10 +24,9 @@
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
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 = {
|
local Reports = {
|
||||||
user_reports = {}, -- stores all user reports, global table
|
user_reports = {}, -- stores all user reports, global table
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
@alias vlayer
|
@alias vlayer
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Storage = require("modules/exp_util/storage")
|
local Storage = require("modules/exp_util/storage")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local config = require("modules.exp_legacy.config.vlayer") --- @dep config.vlayer
|
local config = require("modules.exp_legacy.config.vlayer") --- @dep config.vlayer
|
||||||
local move_items_stack = _C.move_items_stack
|
|
||||||
|
|
||||||
local mega = 1000000
|
local mega = 1000000
|
||||||
|
|
||||||
@@ -682,13 +682,25 @@ function vlayer.remove_interface(surface, position)
|
|||||||
|
|
||||||
-- Return the type of interface removed and do some clean up
|
-- Return the type of interface removed and do some clean up
|
||||||
if name == "logistic-chest-storage" then
|
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)
|
table.remove_element(vlayer_data.entity_interfaces.storage_input, interface)
|
||||||
interface.destroy()
|
interface.destroy()
|
||||||
|
|
||||||
return "storage-input", pos
|
return "storage-input", pos
|
||||||
elseif name == "logistic-chest-requester" then
|
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)
|
table.remove_element(vlayer_data.entity_interfaces.storage_output, interface)
|
||||||
interface.destroy()
|
interface.destroy()
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,11 @@
|
|||||||
Warnings.clear_warnings('MrBiter', 'Cooldude2606')
|
Warnings.clear_warnings('MrBiter', 'Cooldude2606')
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event")
|
||||||
local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
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
|
--- Stores the quickbar filters for a player
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ WrapData:on_update(function(warp_id, warp, old_warp)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Sort the warp names in alphabetical order
|
-- 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)
|
table.insert(new_warp_ids, 1, spawn_id)
|
||||||
new_warp_ids.spawn = spawn_id
|
new_warp_ids.spawn = spawn_id
|
||||||
force_warps[force_name] = new_warp_ids
|
force_warps[force_name] = new_warp_ids
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ PlayerColours:on_load(function(player_name, player_colour)
|
|||||||
else
|
else
|
||||||
local colour_name = "white"
|
local colour_name = "white"
|
||||||
while config.disallow[colour_name] do
|
while config.disallow[colour_name] do
|
||||||
colour_name = table.get_random_dictionary_entry(Colours, true)
|
colour_name = table.get_random(Colours, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
player_colour = { Colours[colour_name], lighten(Colours[colour_name]) }
|
player_colour = { Colours[colour_name], lighten(Colours[colour_name]) }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Storage = require("modules/exp_util/storage") --- @dep utils.global
|
local Storage = require("modules/exp_util/storage") --- @dep utils.global
|
||||||
local config = require("modules.exp_legacy.config.statistics") --- @dep config.statistics
|
local config = require("modules.exp_legacy.config.statistics") --- @dep config.statistics
|
||||||
local format_time = _C.format_time
|
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
local afk_required = 5 * 3600 -- 5 minutes
|
local afk_required = 5 * 3600 -- 5 minutes
|
||||||
|
|
||||||
@@ -46,25 +46,8 @@ Statistics:on_load(function(player_name, player_statistics)
|
|||||||
return player_statistics
|
return player_statistics
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Used to format time in minute format
|
local long_time_format = ExpUtil.format_time_factory_locale{ format = "long", coefficient = 3600, hours = true, minutes = true }
|
||||||
local function format_minutes(value)
|
local short_time_format = ExpUtil.format_time_factory_locale{ format = "short", coefficient = 3600, hours = true, minutes = true }
|
||||||
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
|
|
||||||
|
|
||||||
--- Add MapsPlayed if it is enabled
|
--- Add MapsPlayed if it is enabled
|
||||||
if config.MapsPlayed then
|
if config.MapsPlayed then
|
||||||
@@ -80,11 +63,11 @@ if config.Playtime or config.AfkTime then
|
|||||||
local playtime, afk_time
|
local playtime, afk_time
|
||||||
if config.Playtime then
|
if config.Playtime then
|
||||||
playtime = Statistics:combine("Playtime")
|
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
|
end
|
||||||
if config.AfkTime then
|
if config.AfkTime then
|
||||||
afk_time = Statistics:combine("AfkTime")
|
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
|
end
|
||||||
Event.on_nth_tick(3600, function()
|
Event.on_nth_tick(3600, function()
|
||||||
if game.tick == 0 then return end
|
if game.tick == 0 then return end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@alias autofill
|
@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 Gui = require("modules.exp_legacy.expcore.gui") -- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") -- @dep expcore.gui
|
local Roles = require("modules.exp_legacy.expcore.roles") -- @dep expcore.gui
|
||||||
local Storage = require("modules/exp_util/storage") -- @dep utils.global
|
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 Event = require("modules/exp_legacy/utils/event") -- @dep utils.event
|
||||||
local table = require("modules.exp_legacy.overrides.table") -- @dep overrides.table
|
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
|
--- Table that stores if autofill is enabled or not
|
||||||
local autofill_player_settings = {}
|
local autofill_player_settings = {}
|
||||||
Storage.register(autofill_player_settings, function(tbl)
|
Storage.register(autofill_player_settings, function(tbl)
|
||||||
@@ -324,7 +322,6 @@ local function entity_build(event)
|
|||||||
-- Get the inventory of the player
|
-- Get the inventory of the player
|
||||||
local player_inventory = player.get_main_inventory() --- @cast player_inventory -nil
|
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
|
-- Loop over all possible items to insert into the entity
|
||||||
for _, item in pairs(entity_settings.items) do
|
for _, item in pairs(entity_settings.items) do
|
||||||
-- Check if the item is enabled or goto next item
|
-- 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)
|
local item_amount = player_inventory.get_item_count(item.name)
|
||||||
if item_amount ~= 0 then
|
if item_amount ~= 0 then
|
||||||
local inserted
|
local inserted
|
||||||
text_position.y = text_position.y - 0.5
|
|
||||||
local color = { r = 0, g = 255, b = 0, a = 1 }
|
local color = { r = 0, g = 255, b = 0, a = 1 }
|
||||||
if item_amount >= preferd_amount then
|
if item_amount >= preferd_amount then
|
||||||
-- Can item be inserted? no, goto next item!
|
-- 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 }
|
color = { r = 255, g = 165, b = 0, a = 1 }
|
||||||
end
|
end
|
||||||
player_inventory.remove{ name = item.name, count = inserted }
|
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
|
||||||
::end_item::
|
::end_item::
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function Public.show(container)
|
|||||||
local left_panel_style = left_panel.style
|
local left_panel_style = left_panel.style
|
||||||
left_panel_style.width = 300
|
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 }
|
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = name }
|
||||||
Gui.set_data(header, name)
|
Gui.set_data(header, name)
|
||||||
end
|
end
|
||||||
@@ -69,7 +69,7 @@ Gui.on_click(
|
|||||||
header_name,
|
header_name,
|
||||||
function(event)
|
function(event)
|
||||||
local element = event.element
|
local element = event.element
|
||||||
local tableName = Gui.get_data(element)
|
local table_name = Gui.get_data(element)
|
||||||
|
|
||||||
local left_panel = element.parent.parent
|
local left_panel = element.parent.parent
|
||||||
local data = Gui.get_data(left_panel)
|
local data = Gui.get_data(left_panel)
|
||||||
@@ -84,10 +84,10 @@ Gui.on_click(
|
|||||||
element.style.font_color = Color.orange
|
element.style.font_color = Color.orange
|
||||||
data.selected_header = element
|
data.selected_header = element
|
||||||
|
|
||||||
input_text_box.text = tableName
|
input_text_box.text = table_name
|
||||||
input_text_box.style.font_color = Color.black
|
input_text_box.style.font_color = Color.black
|
||||||
|
|
||||||
local content = Datastore.debug(tableName)
|
local content = Datastore.debug(table_name)
|
||||||
local content_string = {}
|
local content_string = {}
|
||||||
for key, value in pairs(content) do
|
for key, value in pairs(content) do
|
||||||
content_string[#content_string + 1] = key:gsub("^%l", string.upper) .. " = " .. dump(value)
|
content_string[#content_string + 1] = key:gsub("^%l", string.upper) .. " = " .. dump(value)
|
||||||
|
|||||||
@@ -5,13 +5,12 @@
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
-- luacheck:ignore 211/Colors
|
-- luacheck:ignore 211/Colors
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
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 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
|
--- Stores all data for the warp gui
|
||||||
local PlayerListData = Datastore.connect("PlayerListData")
|
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")
|
return Roles.player_allowed(player, "gui/player-list")
|
||||||
end)
|
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
|
-- Get caption and tooltip format for a player
|
||||||
local function get_time_formats(online_time, afk_time)
|
local function get_time_formats(online_time, afk_time)
|
||||||
local tick = game.tick > 0 and game.tick or 1
|
local tick = game.tick > 0 and game.tick or 1
|
||||||
local percent = math.round(online_time / tick, 3) * 100
|
local percent = math.round(online_time / tick, 3) * 100
|
||||||
local caption = format_time(online_time)
|
local caption = online_time_format(online_time)
|
||||||
local tooltip = { "player-list.afk-time", percent, format_time(afk_time, { minutes = true, long = true }) }
|
local tooltip = { "player-list.afk-time", percent, afk_time_format(afk_time) }
|
||||||
return caption, tooltip
|
return caption, tooltip
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -333,7 +335,7 @@ local function get_player_list_order()
|
|||||||
index=0-i,
|
index=0-i,
|
||||||
tag='',
|
tag='',
|
||||||
role_name = 'Fake Player',
|
role_name = 'Fake Player',
|
||||||
chat_color = table.get_random_dictionary_entry(Colors),
|
chat_color = table.get_random(Colors),
|
||||||
caption = caption,
|
caption = caption,
|
||||||
tooltip = tooltip
|
tooltip = tooltip
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
---- module pd
|
---- module pd
|
||||||
-- @gui PlayerData
|
-- @gui PlayerData
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
require("modules.exp_legacy.modules.data.statistics")
|
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 format_number = require("util").format_number --- @dep util
|
||||||
|
|
||||||
local pd_container
|
local pd_container
|
||||||
@@ -16,66 +16,60 @@ local label_width = {
|
|||||||
["total"] = 480,
|
["total"] = 480,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function format_time_short(value)
|
local short_time_format = ExpUtil.format_time_factory_locale{ format = "short", coefficient = 3600, hours = true, minutes = true }
|
||||||
return format_time(value * 3600, {
|
|
||||||
hours = true,
|
|
||||||
minutes = true,
|
|
||||||
seconds = false,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function format_number_n(n)
|
local function format_number_n(n)
|
||||||
return format_number(math.floor(n)) .. string.format("%.2f", n % 1):sub(2)
|
return format_number(math.floor(n)) .. string.format("%.2f", n % 1):sub(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local playerStats = PlayerData.Statistics
|
local PlayerStats = PlayerData.Statistics
|
||||||
local computed_stats = {
|
local computed_stats = {
|
||||||
DamageDeathRatio = {
|
DamageDeathRatio = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
KillDeathRatio = {
|
KillDeathRatio = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
SessionTime = {
|
SessionTime = {
|
||||||
default = format_time_short(0),
|
default = short_time_format(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
BuildRatio = {
|
BuildRatio = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
RocketPerHour = {
|
RocketPerHour = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
TreeKillPerMinute = {
|
TreeKillPerMinute = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
NetPlayTime = {
|
NetPlayTime = {
|
||||||
default = format_time_short(0),
|
default = short_time_format(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
AFKTimeRatio = {
|
AFKTimeRatio = {
|
||||||
default = format_number_n(0),
|
default = format_number_n(0),
|
||||||
calculate = function(player_name)
|
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,
|
end,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
@alias readme
|
@alias readme
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
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 PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
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 format_number = require("util").format_number --- @dep util
|
||||||
|
|
||||||
local tabs = {}
|
local tabs = {}
|
||||||
@@ -109,6 +109,8 @@ local join_server =
|
|||||||
External.request_connection(player, server_id, true)
|
External.request_connection(player, server_id, true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local welcome_time_format = ExpUtil.format_time_factory_locale{ format = "long", days = true, hours = true, minutes = true }
|
||||||
|
|
||||||
--- Content area for the welcome tab
|
--- Content area for the welcome tab
|
||||||
-- @element welcome_content
|
-- @element welcome_content
|
||||||
define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" },
|
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
|
-- Add the other information to the gui
|
||||||
container.add{ type = "flow" }.style.height = 4
|
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-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-roles", table.concat(role_names, ", ") })
|
||||||
Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" })
|
Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" })
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
--- research gui
|
--- research gui
|
||||||
-- @gui Research
|
-- @gui Research
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Storage = require("modules/exp_util/storage")
|
local Storage = require("modules/exp_util/storage")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local config = require("modules.exp_legacy.config.research") --- @dep config.research
|
local config = require("modules.exp_legacy.config.research") --- @dep config.research
|
||||||
local format_time = _C.format_time --- @dep expcore.common
|
|
||||||
|
|
||||||
local research = {}
|
local research = {}
|
||||||
Storage.register(research, function(tbl)
|
Storage.register(research, function(tbl)
|
||||||
@@ -16,22 +16,8 @@ end)
|
|||||||
research.time = {}
|
research.time = {}
|
||||||
research.res_queue_enable = false
|
research.res_queue_enable = false
|
||||||
|
|
||||||
local research_time_format = {
|
local research_time_format = ExpUtil.format_time_factory{ format = "clock", hours = true, minutes = true, seconds = true }
|
||||||
hours = true,
|
local empty_time = research_time_format(nil)
|
||||||
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 font_color = {
|
local font_color = {
|
||||||
-- positive
|
-- positive
|
||||||
@@ -57,7 +43,7 @@ do
|
|||||||
res["disp"][i] = {
|
res["disp"][i] = {
|
||||||
raw_name = k,
|
raw_name = k,
|
||||||
target = res_total,
|
target = res_total,
|
||||||
target_disp = format_time(res_total, research_time_format),
|
target_disp = research_time_format(res_total),
|
||||||
}
|
}
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@@ -118,12 +104,12 @@ local function research_notification(event)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not (event.by_script) then
|
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
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not (event.by_script) then
|
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
|
end
|
||||||
|
|
||||||
if config.bonus_inventory.enabled then
|
if config.bonus_inventory.enabled then
|
||||||
@@ -159,13 +145,13 @@ local function research_gui_update()
|
|||||||
res_disp[i]["difference_color"] = font_color[1]
|
res_disp[i]["difference_color"] = font_color[1]
|
||||||
else
|
else
|
||||||
res_disp[i]["target"] = res["disp"][res_i].target_disp
|
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
|
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]
|
res_disp[i]["difference_color"] = font_color[1]
|
||||||
else
|
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]
|
res_disp[i]["difference_color"] = font_color[2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -313,7 +299,7 @@ Event.add(defines.events.on_research_finished, function(event)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
Event.on_nth_tick(60, function()
|
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
|
for _, player in pairs(game.connected_players) do
|
||||||
local frame = Gui.get_left_element(player, research_container)
|
local frame = Gui.get_left_element(player, research_container)
|
||||||
|
|||||||
@@ -4,19 +4,19 @@
|
|||||||
@alias rocket_info
|
@alias rocket_info
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
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 config = require("modules.exp_legacy.config.gui.rockets") --- @dep config.gui.rockets
|
||||||
local Colors = require("modules/exp_util/include/color")
|
local Colors = require("modules/exp_util/include/color")
|
||||||
local Rockets = require("modules.exp_legacy.modules.control.rockets") --- @dep modules.control.rockets
|
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 = {
|
local time_formats = {
|
||||||
caption = function(value) return format_time(value, { minutes = true, seconds = true }) end,
|
caption = ExpUtil.format_time_factory_locale{ format = "short", minutes = true, seconds = true },
|
||||||
caption_hours = function(value) return format_time(value) end,
|
caption_hours = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true },
|
||||||
tooltip = function(value) return format_time(value, { minutes = true, seconds = true, long = true }) end,
|
tooltip = ExpUtil.format_time_factory_locale{ format = "long", minutes = true, seconds = true },
|
||||||
tooltip_hours = function(value) return format_time(value, { hours = true, minutes = true, seconds = true, long = true }) end,
|
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
|
--- Check if a player is allowed to use certain interactions
|
||||||
|
|||||||
@@ -4,15 +4,18 @@
|
|||||||
@alias science_info
|
@alias science_info
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @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 Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local config = require("modules.exp_legacy.config.gui.science") --- @dep config.gui.science
|
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 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 clock_time_format = ExpUtil.format_time_factory_locale{ format = "clock", hours = true, minutes = true, seconds = true }
|
||||||
local null_time_long = format_time(0, { hours = true, minutes = true, seconds = true, long = true, null = 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
|
--- Data label that contains the value and the surfix
|
||||||
-- @element production_label
|
-- @element production_label
|
||||||
@@ -235,16 +238,18 @@ local function get_eta_label_data(player)
|
|||||||
-- Return the caption and tooltip
|
-- Return the caption and tooltip
|
||||||
return limit and limit > 0 and {
|
return limit and limit > 0 and {
|
||||||
research = true,
|
research = true,
|
||||||
caption = format_time(limit, { hours = true, minutes = true, seconds = true, time = true }),
|
caption = clock_time_format(limit),
|
||||||
tooltip = format_time(limit, { hours = true, minutes = true, seconds = true, long = true }),
|
tooltip = long_time_format(limit),
|
||||||
} or { research = false }
|
} or {
|
||||||
|
research = false
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Updates the eta label
|
-- Updates the eta label
|
||||||
local function update_eta_label(element, eta_label_data)
|
local function update_eta_label(element, eta_label_data)
|
||||||
-- If no research selected show null
|
-- If no research selected show null
|
||||||
if not eta_label_data.research then
|
if not eta_label_data.research then
|
||||||
element.caption = null_time_short
|
element.caption = null_time_clock
|
||||||
element.tooltip = null_time_long
|
element.tooltip = null_time_long
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -293,7 +298,7 @@ local science_info_container =
|
|||||||
footer.add{
|
footer.add{
|
||||||
name = "label",
|
name = "label",
|
||||||
type = "label",
|
type = "label",
|
||||||
caption = null_time_short,
|
caption = null_time_clock,
|
||||||
tooltip = null_time_long,
|
tooltip = null_time_long,
|
||||||
style = "frame_title",
|
style = "frame_title",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
@gui Task-List
|
@gui Task-List
|
||||||
@alias task_list
|
@alias task_list
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
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 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 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
|
--- Stores all data for the task gui by player
|
||||||
local TaskGuiData = Datastore.connect("TaskGuiData")
|
local TaskGuiData = Datastore.connect("TaskGuiData")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
@alias warp_list
|
@alias warp_list
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
||||||
local Storage = require("modules/exp_util/storage")
|
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 Colors = require("modules/exp_util/include/color")
|
||||||
local config = require("modules.exp_legacy.config.gui.warps") --- @dep config.gui.warps
|
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 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
|
--- Stores all data for the warp gui
|
||||||
local WrapGuiData = Datastore.connect("WrapGuiData")
|
local WrapGuiData = Datastore.connect("WrapGuiData")
|
||||||
@@ -94,7 +96,10 @@ local add_new_warp =
|
|||||||
-- Check if the warp is too close to water
|
-- 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 }
|
local water_tiles = surface.find_tiles_filtered{ collision_mask = "water-tile", radius = config.standard_proximity_radius + 1, position = position }
|
||||||
if #water_tiles > 0 then
|
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
|
if game.player then game.player.play_sound{ path = "utility/wire_pickup" } end
|
||||||
for _, tile in pairs(water_tiles) do
|
for _, tile in pairs(water_tiles) do
|
||||||
rendering.draw_sprite{
|
rendering.draw_sprite{
|
||||||
@@ -121,7 +126,10 @@ local add_new_warp =
|
|||||||
}
|
}
|
||||||
-- Remove 1 because that is the current player
|
-- Remove 1 because that is the current player
|
||||||
if #entities > 1 then
|
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
|
if game.player then game.player.play_sound{ path = "utility/wire_pickup" } end
|
||||||
local character = player.character
|
local character = player.character
|
||||||
for _, entity in pairs(entities) do
|
for _, entity in pairs(entities) do
|
||||||
|
|||||||
@@ -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 <table> to search
|
|
||||||
-- @param <any> 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 <table> arrayed table
|
|
||||||
-- @param index <number> 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 <table> to insert into
|
|
||||||
-- @param t2 <table> 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 <table>
|
|
||||||
-- @param e <any> table element
|
|
||||||
-- @return <any> 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 <table>
|
|
||||||
-- @param e <any> table element
|
|
||||||
-- @return <number|nil> 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 <table>
|
|
||||||
-- @param e <any> table element
|
|
||||||
-- @return <boolean> 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 <table>
|
|
||||||
-- @param e <any> table element
|
|
||||||
-- @return <boolean> 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 <table> to add into
|
|
||||||
-- @param index <number> the position in the table to add to
|
|
||||||
-- @param element <any> 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 <table>
|
|
||||||
-- @param key <boolean> to indicate whether to return the key or value
|
|
||||||
-- @return <any> 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 <table> of tables with items and their weights
|
|
||||||
-- @param item_index <number> of the index of items, defaults to 1
|
|
||||||
-- @param weight_index <number> of the index of the weights, defaults to 2
|
|
||||||
-- @return <any> 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 <table> to clear
|
|
||||||
-- @param array <boolean> 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 <table> to shuffle
|
|
||||||
-- @param rng <function> 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 <table> the table to serialize
|
|
||||||
-- @param options <table> 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 <string> 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 <table> the object to copy
|
|
||||||
-- @return <table> 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 <table> takes a table of tables to merge
|
|
||||||
-- @return <table> 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 <table>
|
|
||||||
-- @param tbl2 <table>
|
|
||||||
-- @return <boolean>
|
|
||||||
table.equals = table.compare
|
|
||||||
|
|
||||||
return table
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
return {
|
|
||||||
expgaming_lua = "6.2.0",
|
|
||||||
expgaming_api = "2.0.0",
|
|
||||||
redmew_lua = "2019-02-24-76871ee",
|
|
||||||
}
|
|
||||||
@@ -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 <number|string|LuaPlayer>
|
|
||||||
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
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
--[[-- Util Module - Common
|
--[[-- Util Module - Common
|
||||||
- Adds some commonly used functions used in many modules
|
Adds some commonly used functions used in many modules
|
||||||
@core Common
|
|
||||||
@alias Common
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local assert = assert
|
local assert = assert
|
||||||
@@ -35,6 +33,10 @@ end]]
|
|||||||
|
|
||||||
--- Check the type of a value, also considers LuaObject.object_name and metatable.__class
|
--- 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
|
--- 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 function check_type(value, type_name)
|
||||||
local value_type = type(value) --[[@as string]]
|
local value_type = type(value) --[[@as string]]
|
||||||
if value_type == "userdata" then
|
if value_type == "userdata" then
|
||||||
@@ -56,9 +58,9 @@ end
|
|||||||
|
|
||||||
local assert_type_fmt = "%s expected to be of type %s but got %s"
|
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
|
--- Raise an error if the type of a value is not as expected
|
||||||
-- @param value The value to assert the type of
|
--- @param value any The value to assert the type of
|
||||||
-- @tparam string type_name The name of the type that value is expected to be
|
--- @param type_name string 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_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)
|
function Common.assert_type(value, type_name, value_name)
|
||||||
local failed, actual_type = check_type(value, type_name)
|
local failed, actual_type = check_type(value, type_name)
|
||||||
if failed then
|
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"
|
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
|
--- 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
|
--- @param arg_value any The argument to assert the type of
|
||||||
-- @tparam string type_name The name of the type that value is expected to be
|
--- @param type_name string 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
|
--- @param arg_index number 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_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)
|
function Common.assert_argument_type(arg_value, type_name, arg_index, arg_name)
|
||||||
local failed, actual_type = check_type(arg_value, type_name)
|
local failed, actual_type = check_type(arg_value, type_name)
|
||||||
if failed then
|
if failed then
|
||||||
@@ -81,10 +83,11 @@ function Common.assert_argument_type(arg_value, type_name, arg_index, arg_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Write a luu table to a file as a json string, note the defaults are different to game.write_file
|
--- 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
|
--- @param path string The path to write the json to
|
||||||
-- @tparam table value The table to write to file
|
--- @param tbl table The table to write to file
|
||||||
-- @tparam[opt=false] boolean overwrite When true the json replaces the full contents of the file
|
--- @param overwrite boolean? 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 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)
|
function Common.write_json(path, tbl, overwrite, player_index)
|
||||||
if player_index == -1 then
|
if player_index == -1 then
|
||||||
return game.write_file(path, game.table_to_json(tbl) .. "\n", not overwrite)
|
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
|
end
|
||||||
|
|
||||||
--- Clear a file by replacing its contents with an empty string
|
--- Clear a file by replacing its contents with an empty string
|
||||||
-- @tparam string path The path to clear the contents of
|
--- @param path string 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 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)
|
function Common.clear_file(path, player_index)
|
||||||
if player_index == -1 then
|
if player_index == -1 then
|
||||||
return game.write_file(path, "", false)
|
return game.write_file(path, "", false)
|
||||||
@@ -103,8 +107,9 @@ function Common.clear_file(path, player_index)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Same as require but will return nil if the module does not exist, all other errors will propagate to the caller
|
--- 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
|
--- @param module_path string 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
|
--- @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)
|
function Common.optional_require(module_path)
|
||||||
local success, rtn = xpcall(require, traceback, module_path)
|
local success, rtn = xpcall(require, traceback, module_path)
|
||||||
if success then return rtn end
|
if success then return rtn end
|
||||||
@@ -114,16 +119,16 @@ function Common.optional_require(module_path)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a desync sale filepath for a given stack frame, default is the current file
|
--- 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
|
--- @param level number? 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
|
--- @return string # The relative filepath of the given stack frame
|
||||||
function Common.safe_file_path(level)
|
function Common.safe_file_path(level)
|
||||||
level = level or 1
|
level = level or 1
|
||||||
return getinfo(level + 1, "S").short_src:sub(10, -5)
|
return getinfo(level + 1, "S").short_src:sub(10, -5)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the name of your module, this assumes your module is stored within /modules (which it is for clustorio)
|
--- 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
|
--- @param level number? 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
|
--- @return string # The name of the module at the given stack frame
|
||||||
function Common.get_module_name(level)
|
function Common.get_module_name(level)
|
||||||
local file_within_module = getinfo((level or 1) + 1, "S").short_src:sub(18, -5)
|
local file_within_module = getinfo((level or 1) + 1, "S").short_src:sub(18, -5)
|
||||||
local next_slash = file_within_module:find("/")
|
local next_slash = file_within_module:find("/")
|
||||||
@@ -135,9 +140,9 @@ function Common.get_module_name(level)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the name of a function in a safe and consistent format
|
--- 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
|
--- @param func number | function 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
|
--- @param raw boolean 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
|
--- @return string # The name of the function at the given stack frame or provided as an argument
|
||||||
function Common.get_function_name(func, raw)
|
function Common.get_function_name(func, raw)
|
||||||
local debug_info = getinfo(func, "Sn")
|
local debug_info = getinfo(func, "Sn")
|
||||||
local safe_source = debug_info.source:find("__level__")
|
local safe_source = debug_info.source:find("__level__")
|
||||||
@@ -148,11 +153,11 @@ function Common.get_function_name(func, raw)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Attempt a simple autocomplete search from a set of options
|
--- Attempt a simple autocomplete search from a set of options
|
||||||
-- @tparam table options The table representing the possible options which can be selected
|
--- @param options table The table representing the possible options which can be selected
|
||||||
-- @tparam string input The user input string which should be matched to an option
|
--- @param input string 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
|
--- @param use_key boolean? 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
|
--- @param rtn_key boolean? 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
|
--- @return any # The selected key or value which first matches the input text
|
||||||
function Common.auto_complete(options, input, use_key, rtn_key)
|
function Common.auto_complete(options, input, use_key, rtn_key)
|
||||||
input = input:lower()
|
input = input:lower()
|
||||||
if use_key then
|
if use_key then
|
||||||
@@ -170,61 +175,71 @@ function Common.auto_complete(options, input, use_key, rtn_key)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Formats any value into a safe representation, useful with table.insert
|
--- Formats any value into a safe representation, useful with table.inspect
|
||||||
-- @param value The value to be formated
|
--- @param value any The value to be formatted
|
||||||
-- @return The formated version of the value
|
--- @return string | LocalisedString # The formatted version of the value
|
||||||
-- @return True if value is a locale string, nil otherwise
|
--- @return boolean # True if value is a locale string, nil otherwise
|
||||||
function Common.safe_value(value)
|
function Common.safe_value(value)
|
||||||
if type(value) == "table" or type(value) == "userdata" then
|
if type(value) == "table" then
|
||||||
if type(value.__self) == "userdata" or type(value) == "userdata" then
|
local v1 = value[1]
|
||||||
local success, rtn = pcall(function() -- some userdata doesnt contain "valid"
|
local str = tostring(value)
|
||||||
if value.valid then -- userdata
|
if type(v1) == "string" and not v1:find("%s")
|
||||||
return "<userdata:" .. value.object_name .. ">"
|
and (v1 == "" or v1 == "?" or v1:find(".+[.].+")) then
|
||||||
else -- invalid userdata
|
|
||||||
return "<userdata:" .. value.object_name .. ":invalid>"
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
return success and rtn or "<userdata:" .. value.object_name .. ">"
|
|
||||||
elseif type(value[1]) == "string" and string.find(value[1], ".+[.].+") and not string.find(value[1], "%s") then
|
|
||||||
return value, true -- locale string
|
return value, true -- locale string
|
||||||
elseif tostring(value) ~= "table" then
|
elseif str ~= "table" then
|
||||||
return tostring(value) -- has __tostring metamethod
|
return str, false -- has __tostring metamethod
|
||||||
else -- plain table
|
else -- plain table
|
||||||
return value
|
return value, false
|
||||||
end
|
end
|
||||||
elseif type(value) == "function" then -- function
|
elseif type(value) == "function" then -- function
|
||||||
return "<function:" .. Common.get_function_name(value, true) .. ">"
|
return "<function:" .. Common.get_function_name(value, true) .. ">", false
|
||||||
else -- not: table, userdata, or function
|
else -- not: table or function
|
||||||
return tostring(value)
|
return tostring(value), false
|
||||||
end
|
end
|
||||||
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
|
--- Formats any value to be presented in a safe and human readable format
|
||||||
-- @param value The value to be formated
|
--- @param value any The value to be formatted
|
||||||
-- @param[opt] tableAsJson If table values should be returned as json
|
--- @param options Common.format_any_param? Options for the formatter
|
||||||
-- @param[opt] maxLineCount If table newline count exceeds provided then it will be inlined
|
--- @return string | LocalisedString # The formatted version of the value
|
||||||
-- @return The formated version of the value
|
function Common.format_any(value, options)
|
||||||
function Common.format_any(value, as_json, max_line_count)
|
options = options or {}
|
||||||
local formatted, is_locale_string = Common.safe_value(value)
|
local formatted, is_locale_string = Common.safe_value(value)
|
||||||
if type(formatted) == "table" and not is_locale_string then
|
if type(formatted) == "table" and (not is_locale_string or options.no_locale_strings) then
|
||||||
if as_json then
|
if options.as_json then
|
||||||
local success, rtn = pcall(game.table_to_json, value)
|
local success, rtn = pcall(game.table_to_json, value)
|
||||||
if success then return rtn end
|
if success then return rtn end
|
||||||
end
|
end
|
||||||
local rtn = table.inspect(value, { depth = 5, indent = " ", newline = "\n", process = Common.safe_value })
|
if options.max_line_count ~= 0 then
|
||||||
if max_line_count == nil or select(2, rtn:gsub("\n", "")) < max_line_count then return rtn end
|
local rtn = table.inspect(value, { depth = options.depth or 5, indent = " ", newline = "\n", process = Common.safe_value })
|
||||||
return table.inspect(value, { depth = 5, indent = "", newline = "", 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
|
end
|
||||||
return formatted
|
return formatted
|
||||||
end
|
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)
|
--- 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
|
--- @param ticks number|nil 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
|
--- @param format Common.format_time_param_format 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
|
--- @param units Common.format_time_param_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
|
--- @return string # The ticks formatted into a string of the desired format
|
||||||
function Common.format_time(ticks, format, units)
|
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 = "--", "--", "--", "--"
|
local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = "--", "--", "--", "--"
|
||||||
|
|
||||||
if ticks ~= nil then
|
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
|
local minutes, seconds = max_minutes - floor(max_hours) * 60, max_seconds - floor(max_minutes) * 60
|
||||||
|
|
||||||
-- Calculate rhw units to be displayed
|
-- 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)
|
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.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.hours then rtn_minutes = rtn_minutes + rtn_hours * 60 end
|
||||||
@@ -269,12 +283,12 @@ function Common.format_time(ticks, format, units)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Format a tick value into one of a selection of pre-defined formats (short, long, clock)
|
--- 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
|
--- @param ticks number|nil 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
|
--- @param format Common.format_time_param_format 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
|
--- @param units Common.format_time_param_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
|
--- @return LocalisedString # The ticks formatted into a string of the desired format
|
||||||
function Common.format_locale_time(ticks, format, units)
|
function Common.format_time_locale(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 = "--", "--", "--", "--"
|
local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = "--", "--", "--", "--"
|
||||||
|
|
||||||
if ticks ~= nil then
|
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
|
local minutes, seconds = max_minutes - floor(max_hours) * 60, max_seconds - floor(max_minutes) * 60
|
||||||
|
|
||||||
-- Calculate rhw units to be displayed
|
-- 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)
|
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.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.hours then rtn_minutes = rtn_minutes + rtn_hours * 60 end
|
||||||
if not units.minutes then rtn_seconds = rtn_seconds + rtn_minutes * 60 end
|
if not units.minutes then rtn_seconds = rtn_seconds + rtn_minutes * 60 end
|
||||||
--- @diagnostic enable: cast-local-type
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local rtn = {}
|
local rtn = {}
|
||||||
local join = ", "
|
local join = ", " --- @type string | LocalisedString
|
||||||
if format == "clock" then
|
if format == "clock" then
|
||||||
-- Example 12:34:56 or --:--:--
|
-- Example 12:34:56 or --:--:--
|
||||||
if units.days then rtn[#rtn + 1] = rtn_days end
|
if units.days then rtn[#rtn + 1] = rtn_days end
|
||||||
if units.hours then rtn[#rtn + 1] = rtn_hours end
|
if units.hours then rtn[#rtn + 1] = rtn_hours end
|
||||||
if units.minutes then rtn[#rtn + 1] = rtn_minutes end
|
if units.minutes then rtn[#rtn + 1] = rtn_minutes end
|
||||||
if units.seconds then rtn[#rtn + 1] = rtn_seconds end
|
if units.seconds then rtn[#rtn + 1] = rtn_seconds end
|
||||||
--- @diagnostic disable-next-line: cast-local-type
|
|
||||||
join = { "colon" }
|
join = { "colon" }
|
||||||
elseif format == "short" then
|
elseif format == "short" then
|
||||||
-- Example 12d 34h 56m or --d --h --m
|
-- 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] }
|
rtn[#rtn] = { "", { "and" }, " ", rtn[#rtn] }
|
||||||
end
|
end
|
||||||
|
|
||||||
local joined = { "" } --[[@as any]]
|
--- @type LocalisedString
|
||||||
|
local joined = { "" }
|
||||||
for k, v in ipairs(rtn) do
|
for k, v in ipairs(rtn) do
|
||||||
joined[2 * k] = v
|
joined[2 * k] = v
|
||||||
joined[2 * k + 1] = join --[[@as any]]
|
joined[2 * k + 1] = join
|
||||||
end
|
end
|
||||||
|
|
||||||
return joined
|
return joined
|
||||||
end
|
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.
|
--- @class Common.format_time_factory_param: Common.format_time_param_units
|
||||||
-- @tparam table items The items which are to be inserted into the entities, an array of LuaItemStack
|
--- @field format Common.format_time_param_format The format to use
|
||||||
-- @tparam LuaSurface surface The surface which will be searched to find the entities
|
--- @field coefficient number? If present will multiply the input by this amount before formatting
|
||||||
-- @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
|
--- Create a formatter to format a tick value into one of a selection of pre-defined formats (short, long, clock)
|
||||||
-- type can be used to find all entities of a given type, such as a chest
|
--- @param options Common.format_time_factory_param
|
||||||
-- name can be used to further specify which entity to insert into, this field is required if entity creation is desired
|
--- @return fun(ticks: number|nil): string
|
||||||
-- allow_creation is a boolean which when true will allow the function to create new entities in order to insert all items
|
function Common.format_time_factory(options)
|
||||||
-- force is the force which new entities will be created to, the default is the neutral force
|
local formatter, format, coefficient = Common.format_time, options.format, options.coefficient
|
||||||
-- @treturn LuaEntity the last entity that had items inserted into it
|
if coefficient then
|
||||||
function Common.insert_item_stacks(items, surface, options)
|
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
|
||||||
|
|
||||||
|
--- 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
|
||||||
|
|
||||||
|
--- @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
|
||||||
|
|
||||||
|
--- @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
|
||||||
|
|
||||||
|
--- 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)
|
local entities = surface.find_entities_filtered(options)
|
||||||
local count, current, last_entity = #entities, 0, nil
|
cache = {
|
||||||
|
entities = entities,
|
||||||
|
count = #entities,
|
||||||
|
current = 0,
|
||||||
|
}
|
||||||
|
options.cache = cache
|
||||||
|
end
|
||||||
|
--- @cast cache -nil
|
||||||
|
|
||||||
for _, item in ipairs(items) do
|
-- Find a valid entity from the search results
|
||||||
if item.valid_for_read then
|
local current, count, entities = cache.current, cache.count, cache.entities
|
||||||
local inserted = false
|
for i = 1, cache.count do
|
||||||
|
|
||||||
-- Attempt to insert the items
|
|
||||||
for i = 1, count do
|
|
||||||
local entity = entities[((current + i - 1) % count) + 1]
|
local entity = entities[((current + i - 1) % count) + 1]
|
||||||
if entity.can_insert(item) then
|
if entity.can_insert(item) then
|
||||||
last_entity = entity
|
cache.current = current + 1
|
||||||
current = current + 1
|
return entity
|
||||||
entity.insert(item)
|
|
||||||
inserted = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If it was not inserted then a new entity is needed
|
-- No entity was found so one needs to be created
|
||||||
if not inserted then
|
assert(options.allow_creation, "Unable to find valid entity, consider enabling allow_creation")
|
||||||
if not options.allow_creation then error("Unable to insert items into a valid entity, consider enabling allow_creation") end
|
assert(options.name, "Name must be provided to allow creation of new entities")
|
||||||
if options.name == nil then error("Name must be provided to allow creation of new entities") end
|
|
||||||
|
|
||||||
local position
|
local position
|
||||||
if options.position then
|
if options.position then
|
||||||
position = surface.find_non_colliding_position(options.name, options.position, options.radius, 1, true)
|
position = surface.find_non_colliding_position(options.name, options.position, options.radius or 0, 1, true)
|
||||||
elseif options.area then
|
elseif options.area then
|
||||||
position = surface.find_non_colliding_position_in_box(options.name, options.area, 1, true)
|
position = surface.find_non_colliding_position_in_box(options.name, options.area, 1, true)
|
||||||
else
|
else
|
||||||
position = surface.find_non_colliding_position(options.name, { 0, 0 }, 0, 1, true)
|
position = surface.find_non_colliding_position(options.name, { 0, 0 }, 0, 1, true)
|
||||||
end
|
end
|
||||||
last_entity = surface.create_entity{ name = options.name, position = position, force = options.force or "neutral" }
|
assert(position, "Failed to find valid location")
|
||||||
|
|
||||||
count = count + 1
|
local entity = surface.create_entity{ name = options.name, position = position, force = options.force or "neutral" }
|
||||||
entities[count] = last_entity
|
assert(entity, "Failed to create a new entity")
|
||||||
last_entity.insert(item)
|
|
||||||
|
cache.count = count + 1
|
||||||
|
entities[count] = entity
|
||||||
|
return entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @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
|
||||||
end
|
end
|
||||||
|
|
||||||
return last_entity
|
return enum
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Move the given items into the found / created entities. If no entities are found then they will be created if possible.
|
--- Returns a string for a number with comma separators
|
||||||
-- @tparam table items The items which are to be inserted into the entities, an array of LuaItemStack
|
--- @param n number
|
||||||
-- @tparam LuaSurface surface The surface which will be searched to find the entities
|
--- @return string
|
||||||
-- @tparam table options A table of various optional options similar to find_entities_filtered
|
function Common.comma_value(n) -- credit http://richard.warburton.it
|
||||||
-- position + radius or area can be used to define a search area on the surface
|
local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$")
|
||||||
-- type can be used to find all entities of a given type, such as a chest
|
return left .. (num:reverse():gsub("(%d%d%d)", "%1, "):reverse()) .. right
|
||||||
-- name can be used to further specify which entity to insert into, this field is required if entity creation is desired
|
end
|
||||||
-- 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
|
--- Returns a message formatted for game chat using rich text colour tags
|
||||||
function Common.transfer_item_stacks(inventory, surface, options)
|
--- @param message string
|
||||||
Common.insert_item_stacks(inventory, surface, options)
|
--- @param color Color | string
|
||||||
inventory.clear()
|
--- @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 "<Server>"
|
||||||
|
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 "<Server>"
|
||||||
|
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
|
end
|
||||||
|
|
||||||
return Common
|
return Common
|
||||||
|
|||||||
@@ -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
|
|
||||||
89
exp_util/module/flying_text.lua
Normal file
89
exp_util/module/flying_text.lua
Normal file
@@ -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
|
||||||
@@ -32,9 +32,9 @@ end
|
|||||||
local tbl = {}
|
local tbl = {}
|
||||||
local values = {}
|
local values = {}
|
||||||
for i = 1, 1000 do tbl[i] = i values[i] = i end
|
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
|
if not values then
|
||||||
values = start_index
|
values = start_index
|
||||||
start_index = nil
|
start_index = nil
|
||||||
@@ -69,15 +69,15 @@ end
|
|||||||
local tbl = {}
|
local tbl = {}
|
||||||
local tbl2 = {}
|
local tbl2 = {}
|
||||||
for i = 1, 100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end
|
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
|
if not tbl2 then
|
||||||
tbl2 = start_index
|
tbl2 = start_index
|
||||||
start_index = nil
|
start_index = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
table.array_insert(tbl, start_index, tbl2)
|
table.insert_array(tbl, start_index, tbl2)
|
||||||
for key, value in pairs(tbl2) do
|
for key, value in pairs(tbl2) do
|
||||||
if not tonumber(key) then
|
if not tonumber(key) then
|
||||||
tbl[key] = value
|
tbl[key] = value
|
||||||
@@ -112,11 +112,6 @@ function table.remove_index(tbl, index)
|
|||||||
tbl[count] = nil
|
tbl[count] = nil
|
||||||
end
|
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
|
--- Return the key which holds this element element
|
||||||
-- @tparam table tbl The table to search
|
-- @tparam table tbl The table to search
|
||||||
-- @param element The element to find
|
-- @param element The element to find
|
||||||
@@ -428,7 +423,6 @@ table.deep_copy = table.deepcopy -- added by util
|
|||||||
table.deep_merge = util.merge
|
table.deep_merge = util.merge
|
||||||
|
|
||||||
--- Determines if two tables are structurally equal.
|
--- 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 tbl1 The first table
|
||||||
-- @tparam table tbl2 The second table
|
-- @tparam table tbl2 The second table
|
||||||
-- @treturn boolean True if the tables are equal
|
-- @treturn boolean True if the tables are equal
|
||||||
|
|||||||
Reference in New Issue
Block a user