Update all code styles

This commit is contained in:
Cooldude2606
2024-09-28 01:56:54 +01:00
parent 5e2a62ab27
commit 292c1a1b68
194 changed files with 9817 additions and 9703 deletions

View File

@@ -36,6 +36,11 @@
"param": "_?_?(\\w+)",
"$1": "snake_case"
}],
"module_local_name_style": [{
"type" : "pattern",
"param": "_?_?(\\w+)",
"$1": "snake_case"
}, "pascal_case"],
"function_param_name_style": [{
"type" : "pattern",
"param": "_?_?(\\w+)",

View File

@@ -45,7 +45,7 @@ end)
add("string-options", function(input, _, options)
local option = ExpUtil.auto_complete(options, input)
if option == nil then
return invalid{"exp-commands-parse.string-options", table.concat(options, ", ")}
return invalid{ "exp-commands-parse.string-options", table.concat(options, ", ") }
else
return valid(option)
end
@@ -55,7 +55,7 @@ end)
add("string-key", function(input, _, map)
local option = ExpUtil.auto_complete(map, input, true)
if option == nil then
return invalid{"exp-commands-parse.string-options", table.concat(table.get_keys(map), ", ")}
return invalid{ "exp-commands-parse.string-options", table.concat(table.get_keys(map), ", ") }
else
return valid(option)
end
@@ -64,7 +64,7 @@ end)
--- A string with a maximum length, takes one argument which is the maximum length of a string
add("string-max-length", function(input, _, maximum)
if input:len() > maximum then
return invalid{"exp-commands-parse.string-max-length", maximum}
return invalid{ "exp-commands-parse.string-max-length", maximum }
else
return valid(input)
end
@@ -74,7 +74,7 @@ end)
add("number", function(input)
local number = tonumber(input)
if number == nil then
return invalid{"exp-commands-parse.number"}
return invalid{ "exp-commands-parse.number" }
else
return valid(number)
end
@@ -84,7 +84,7 @@ end)
add("integer", function(input)
local number = tonumber(input)
if number == nil then
return invalid{"exp-commands-parse.number"}
return invalid{ "exp-commands-parse.number" }
else
return valid(math.floor(number))
end
@@ -96,7 +96,7 @@ add("number-range", function(input, _, minimum, maximum)
if not success then
return status, number
elseif number < minimum or number > maximum then
return invalid{"exp-commands-parse.number-range", minimum, maximum}
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
else
return valid(number)
end
@@ -108,7 +108,7 @@ add("integer-range", function(input, _, minimum, maximum)
if not success then
return status, number
elseif number < minimum or number > maximum then
return invalid{"exp-commands-parse.number-range", minimum, maximum}
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
else
return valid(number)
end
@@ -118,7 +118,7 @@ end)
add("player", function(input)
local player = game.get_player(input)
if player == nil then
return invalid{"exp-commands-parse.player", input}
return invalid{ "exp-commands-parse.player", input }
else
return valid(player)
end
@@ -130,7 +130,7 @@ add("player-online", function(input)
if not success then
return status, player
elseif player.connected == false then
return invalid{"exp-commands-parse.player-online"}
return invalid{ "exp-commands-parse.player-online" }
else
return valid(player)
end
@@ -142,7 +142,7 @@ add("player-alive", function(input)
if not success then
return status, player
elseif player.character == nil or player.character.health <= 0 then
return invalid{"exp-commands-parse.player-alive"}
return invalid{ "exp-commands-parse.player-alive" }
else
return valid(player)
end
@@ -152,7 +152,7 @@ end)
add("force", function(input)
local force = game.forces[input]
if force == nil then
return invalid{"exp-commands-parse.force"}
return invalid{ "exp-commands-parse.force" }
else
return valid(force)
end
@@ -162,7 +162,7 @@ end)
add("surface", function(input)
local surface = game.surfaces[input]
if surface == nil then
return invalid{"exp-commands-parse.surface"}
return invalid{ "exp-commands-parse.surface" }
else
return valid(surface)
end
@@ -172,7 +172,7 @@ end)
add("color", function(input)
local color = ExpUtil.auto_complete(Commands.color, input, true)
if color == nil then
return invalid{"exp-commands-parse.color"}
return invalid{ "exp-commands-parse.color" }
else
return valid(color)
end

View File

@@ -34,7 +34,7 @@ local function format_as_pages(commands, page_size)
page_length = 1
end
local aliases = #command.aliases > 0 and {"exp-commands-help.aliases", table.concat(command.aliases, ", ")} or ""
local aliases = #command.aliases > 0 and { "exp-commands-help.aliases", table.concat(command.aliases, ", ") } or ""
pages[current_page][page_length] = { "exp-commands-help.format", command.name, command.description, command.help, aliases }
end
@@ -42,40 +42,41 @@ local function format_as_pages(commands, page_size)
end
Commands.new("commands", "List and search all commands for a keyword")
:add_aliases{ "chelp", "helpp" }
:argument("keyword", "string")
:optional("page", "integer")
:defaults{ page = 1 }
:register(function(player, keyword, page)
keyword = keyword:lower()
local pages, found
local cache = search_cache[player.index]
if cache and cache.keyword == keyword then
-- Cached value found, no search is needed
pages = cache.pages
found = cache.found
else
-- No cached value, so a search needs to be done
local commands = Commands.search_for_player(keyword, player)
pages, found = format_as_pages(commands, PAGE_SIZE)
search_cache[player.index] = { keyword = keyword, pages = pages, found = found }
end
:add_aliases{ "chelp", "helpp" }
:argument("keyword", "string")
:optional("page", "integer")
:defaults{ page = 1 }
:register(function(player, keyword, page)
keyword = keyword:lower()
local pages, found
local cache = search_cache[player.index]
if cache and cache.keyword == keyword then
-- Cached value found, no search is needed
pages = cache.pages
found = cache.found
else
-- No cached value, so a search needs to be done
local commands = Commands.search_for_player(keyword, player)
pages, found = format_as_pages(commands, PAGE_SIZE)
search_cache[player.index] = { keyword = keyword, pages = pages, found = found }
end
-- Error if no pages found
if found == 0 then
return Commands.status.success{ "exp-commands-help.no-results" }
end
-- Error if no pages found
if found == 0 then
return Commands.status.success{ "exp-commands-help.no-results" }
end
local page_data = pages[page]
if page_data == nil then
-- Page number was out of range for this search
return Commands.status.invalid_input{"exp-commands-help.out-of-range", page, #pages }
end
local page_data = pages[page]
if page_data == nil then
-- Page number was out of range for this search
return Commands.status.invalid_input{ "exp-commands-help.out-of-range", page, #pages }
end
-- Print selected page to the player
Commands.print{ "exp-commands-help.header", keyword == '' and '<all>' or keyword }
for _, command in pairs(page_data) do
Commands.print(command)
end
return Commands.status.success{ "exp-commands-help.footer", found, page, #pages }
end)
-- Print selected page to the player
Commands.print{ "exp-commands-help.header", keyword == "" and "<all>" or keyword }
for _, command in pairs(page_data) do
Commands.print(command)
end
return Commands.status.success{ "exp-commands-help.footer", found, page, #pages }
end)

View File

@@ -10,16 +10,16 @@ local Commands = require("modules/exp_commands")
local Clustorio = require("modules/clusterio/api")
Commands.new("_ipc", "Send an IPC message on the selected channel")
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("channel", "string")
:argument("message", "string")
:register(function(_, channel, message)
local tbl = game.json_to_table(message)
if tbl == nil then
return Commands.status.invalid_input("Invalid json string")
else
Clustorio.send_json(channel, tbl)
return Commands.status.success()
end
end)
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("channel", "string")
:argument("message", "string")
:register(function(_, channel, message)
local tbl = game.json_to_table(message)
if tbl == nil then
return Commands.status.invalid_input("Invalid json string")
else
Clustorio.send_json(channel, tbl)
return Commands.status.success()
end
end)

View File

@@ -60,32 +60,32 @@ end
--- If a command has the flag "admin_only" then only admins can use the command#
permission_authorities.admin_only =
add(function(player, command)
if command.flags.admin_only and not player.admin then
return deny{"exp-commands-permissions.admin-only"}
else
return allow()
end
end)
add(function(player, command)
if command.flags.admin_only and not player.admin then
return deny{ "exp-commands-permissions.admin-only" }
else
return allow()
end
end)
--- If a command has the flag "system_only" then only rcon connections can use the command
permission_authorities.system_only =
add(function(player, command)
if command.flags.system_only and not system_players[player.name] then
return deny{"exp-commands-permissions.system-only"}
else
return allow()
end
end)
add(function(player, command)
if command.flags.system_only and not system_players[player.name] then
return deny{ "exp-commands-permissions.system-only" }
else
return allow()
end
end)
--- If Commands.disable was called then no one can use the command
permission_authorities.disabled =
add(function(_, command)
if disabled_commands[command.name] then
return deny{"exp-commands-permissions.disabled"}
else
return allow()
end
end)
add(function(_, command)
if disabled_commands[command.name] then
return deny{ "exp-commands-permissions.disabled" }
else
return allow()
end
end)
return permission_authorities

View File

@@ -31,10 +31,15 @@ rcon_statics.ipc = Clustorio.send_json
--- Some common callback values which are useful when a player uses the command
function rcon_callbacks.player(player) return player end
function rcon_callbacks.surface(player) return player and player.surface end
function rcon_callbacks.force(player) return player and player.force end
function rcon_callbacks.position(player) return player and player.position end
function rcon_callbacks.entity(player) return player and player.selected end
function rcon_callbacks.tile(player) return player and player.surface.get_tile(player.position) end
--- The rcon env is saved between command runs to prevent desyncs
@@ -55,28 +60,28 @@ function Commands.add_rcon_callback(name, callback)
end
Commands.new("_rcon", "Execute arbitrary code within a custom environment")
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("invocation", "string")
:register(function(player, invocation_string)
-- Construct the environment the command will run within
local env = setmetatable({}, { __index = rcon_env, __newindex = rcon_env })
for name, callback in pairs(rcon_callbacks) do
local _, rtn = pcall(callback, player.index > 0 and player or nil)
rawset(env, name, rtn)
end
-- Compile and run the invocation string
local invocation, compile_error = load(invocation_string, "rcon-invocation", "t", env)
if compile_error then
return Commands.status.invalid_input(compile_error)
else
local success, rtn = xpcall(invocation, debug.traceback)
if success == false then
local err = rtn:gsub('%.%.%..-/temp/currently%-playing/', '')
return Commands.status.error(err)
else
return Commands.status.success(rtn)
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("invocation", "string")
:register(function(player, invocation_string)
-- Construct the environment the command will run within
local env = setmetatable({}, { __index = rcon_env, __newindex = rcon_env })
for name, callback in pairs(rcon_callbacks) do
local _, rtn = pcall(callback, player.index > 0 and player or nil)
rawset(env, name, rtn)
end
end
end)
-- Compile and run the invocation string
local invocation, compile_error = load(invocation_string, "rcon-invocation", "t", env)
if compile_error then
return Commands.status.invalid_input(compile_error)
else
local success, rtn = xpcall(invocation, debug.traceback)
if success == false then
local err = rtn:gsub("%.%.%..-/temp/currently%-playing/", "")
return Commands.status.error(err)
else
return Commands.status.success(rtn)
end
end
end)

View File

@@ -10,16 +10,16 @@ System command to execute a command as another player using their permissions (e
local Commands = require("modules/exp_commands")
Commands.new("_sudo", "Run a command as another player")
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("player", "player")
:argument("command", "string-key", Commands.registered_commands)
:argument("arguments", "string")
:register(function(_, player, command, parameter)
return Commands._event_handler{
name = command.name,
tick = game.tick,
player_index = player.index,
parameter = parameter
}
end)
:add_flags{ "system_only" }
:enable_auto_concatenation()
:argument("player", "player")
:argument("command", "string-key", Commands.registered_commands)
:argument("arguments", "string")
:register(function(_, player, command, parameter)
return Commands._event_handler{
name = command.name,
tick = game.tick,
player_index = player.index,
parameter = parameter,
}
end)

View File

@@ -70,34 +70,34 @@ local Commands = {
Commands._metatable = {
__index = Commands._prototype,
__class = "ExpCommand"
__class = "ExpCommand",
}
Commands.player_server = setmetatable({
index = 0,
color = Color.white,
chat_color = Color.white,
name = "<server>",
tag = "",
connected = true,
admin = true,
afk_time = 0,
online_time = 0,
last_online = 0,
spectator = true,
show_on_map = false,
valid = true,
object_name = "LuaPlayer"
index = 0,
color = Color.white,
chat_color = Color.white,
name = "<server>",
tag = "",
connected = true,
admin = true,
afk_time = 0,
online_time = 0,
last_online = 0,
spectator = true,
show_on_map = false,
valid = true,
object_name = "LuaPlayer",
}, {
__index = function(_, key)
if key == "__self" or type(key) == "number" then return nil end
Commands.error("Command does not support rcon usage, requires reading player." .. key)
error("Command does not support rcon usage, requires reading player." .. key)
end,
__newindex = function(_, key)
Commands.error("Command does not support rcon usage, requires reading player." .. key)
error("Command does not support rcon usage, requires setting player." .. key)
end
__index = function(_, key)
if key == "__self" or type(key) == "number" then return nil end
Commands.error("Command does not support rcon usage, requires reading player." .. key)
error("Command does not support rcon usage, requires reading player." .. key)
end,
__newindex = function(_, key)
Commands.error("Command does not support rcon usage, requires reading player." .. key)
error("Command does not support rcon usage, requires setting player." .. key)
end,
})
--- Status Returns.
@@ -107,34 +107,34 @@ Commands.player_server = setmetatable({
--- Used to signal success from a command, data type parser, or permission authority
-- @tparam[opt] LocaleString|string msg An optional message to be included when a command completes (only has an effect in command callbacks)
function Commands.status.success(msg)
return Commands.status.success, msg or {'exp-commands.success'}
return Commands.status.success, msg or { "exp-commands.success" }
end
--- Used to signal an error has occurred in a command, data type parser, or permission authority
-- For data type parsers and permission authority, an error return will prevent the command from being executed
-- @tparam[opt] LocaleString|string msg An optional error message to be included in the output, a generic message is used if not provided
function Commands.status.error(msg)
return Commands.status.error, {'exp-commands.error', msg or {'exp-commands.error-default'}}
return Commands.status.error, { "exp-commands.error", msg or { "exp-commands.error-default" } }
end
--- Used to signal the player is unauthorised to use a command, primarily used by permission authorities but can be used in a command callback
-- For permission authorities, an error return will prevent the command from being executed
-- @tparam[opt] LocaleString|string msg An optional error message to be included in the output, a generic message is used if not provided
function Commands.status.unauthorised(msg)
return Commands.status.unauthorised, msg or {'exp-commands.unauthorized', msg or {'exp-commands.unauthorized-default'}}
return Commands.status.unauthorised, msg or { "exp-commands.unauthorized", msg or { "exp-commands.unauthorized-default" } }
end
--- Used to signal the player provided invalid input to an command, primarily used by data type parsers but can be used in a command callback
-- For data type parsers, an error return will prevent the command from being executed
-- @tparam[opt] LocaleString|string msg An optional error message to be included in the output, a generic message is used if not provided
function Commands.status.invalid_input(msg)
return Commands.status.invalid_input, msg or {'exp-commands.invalid-input'}
return Commands.status.invalid_input, msg or { "exp-commands.invalid-input" }
end
--- Used to signal an internal error has occurred, this is reserved for internal use
-- @tparam LocaleString|string msg A message detailing the error which has occurred, will be logged and outputted
function Commands.status.internal_error(msg)
return Commands.status.internal_error, {'exp-commands.internal-error', msg}
return Commands.status.internal_error, { "exp-commands.internal-error", msg }
end
local valid_command_status = {} -- Hashmap lookup for testing if a status is valid
@@ -207,7 +207,7 @@ end
-- @treturn string The data type passed as the first argument
function Commands.add_data_type(data_type, parser)
if Commands.data_types[data_type] then
error("Data type \""..tostring(data_type).."\" already has a parser registered", 2)
error("Data type \"" .. tostring(data_type) .. "\" already has a parser registered", 2)
end
Commands.data_types[data_type] = parser
return data_type
@@ -231,12 +231,12 @@ function Commands.parse_data_type(data_type, input, ...)
if type(data_type) == "function" then
parser = data_type
elseif parser == nil then
return false, Commands.status.internal_error, {"exp-commands.internal-error" , "Data type \""..tostring(data_type).."\" does not have a registered parser"}
return false, Commands.status.internal_error, { "exp-commands.internal-error", "Data type \"" .. tostring(data_type) .. "\" does not have a registered parser" }
end
local status, parsed = parser(input, ...)
if status == nil then
return Commands.status.internal_error, {"exp-commands.internal-error" , "Parser for data type \""..tostring(data_type).."\" returned a nil value"}
return Commands.status.internal_error, { "exp-commands.internal-error", "Parser for data type \"" .. tostring(data_type) .. "\" returned a nil value" }
elseif valid_command_status[status] then
if status ~= Commands.status.success then
return false, status, parsed -- error_type, error_msg
@@ -279,7 +279,7 @@ local function search_commands(keyword, custom_commands)
-- Search all custom commands
for name, command in pairs(custom_commands) do
local search = string.format('%s %s %s', name, command.help, table.concat(command.aliases, ' '))
local search = string.format("%s %s %s", name, command.help, table.concat(command.aliases, " "))
if search:lower():match(keyword) then
rtn[name] = command
end
@@ -287,13 +287,13 @@ local function search_commands(keyword, custom_commands)
-- Search all game commands
for name, description in pairs(commands.game_commands) do
local search = string.format('%s %s', name, description)
local search = string.format("%s %s", name, description)
if search:lower():match(keyword) then
rtn[name] = {
name = name,
help = description,
description = "",
aliases = {}
aliases = {},
}
end
end
@@ -322,8 +322,8 @@ end
-- @tparam Color color The color that the message should be
-- @treturn string The string which can be printed to game chat
function Commands.set_chat_message_color(message, color)
local color_tag = math.round(color.r, 3)..', '..math.round(color.g, 3)..', '..math.round(color.b, 3)
return string.format('[color=%s]%s[/color]', color_tag, message)
local color_tag = math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3)
return string.format("[color=%s]%s[/color]", color_tag, message)
end
--- Set the color of a locale message using rich text chat
@@ -331,8 +331,8 @@ end
-- @tparam Color color The color that the message should be
-- @treturn LocaleString The locale string which can be printed to game chat
function Commands.set_locale_chat_message_color(message, color)
local color_tag = math.round(color.r, 3)..', '..math.round(color.g, 3)..', '..math.round(color.b, 3)
return {'color-tag', color_tag, message}
local color_tag = math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3)
return { "color-tag", color_tag, message }
end
--- Get a string representing the name of the given player in their chat colour
@@ -341,8 +341,8 @@ end
function Commands.format_player_name(player)
local player_name = player and player.name or "<server>"
local player_color = player and player.chat_color or Color.white
local color_tag = math.round(player_color.r, 3)..', '..math.round(player_color.g, 3)..', '..math.round(player_color.b, 3)
return string.format('[color=%s]%s[/color]', color_tag, player_name)
local color_tag = math.round(player_color.r, 3) .. ", " .. math.round(player_color.g, 3) .. ", " .. math.round(player_color.b, 3)
return string.format("[color=%s]%s[/color]", color_tag, player_name)
end
--- Get a locale string representing the name of the given player in their chat colour
@@ -351,8 +351,8 @@ end
function Commands.format_locale_player_name(player)
local player_name = player and player.name or "<server>"
local player_color = player and player.chat_color or Color.white
local color_tag = math.round(player_color.r, 3)..', '..math.round(player_color.g, 3)..', '..math.round(player_color.b, 3)
return {'color-tag', color_tag, player_name}
local color_tag = math.round(player_color.r, 3) .. ", " .. math.round(player_color.g, 3) .. ", " .. math.round(player_color.b, 3)
return { "color-tag", color_tag, player_name }
end
--- Print a message to the user of a command, accepts any value and will print in a readable and safe format
@@ -366,14 +366,14 @@ function Commands.print(message, color, sound)
else
local formatted = ExpUtil.format_any(message, nil, 20)
player.print(formatted, color or Color.white)
player.play_sound{ path = sound or 'utility/scenario_message' }
player.play_sound{ path = sound or "utility/scenario_message" }
end
end
--- Print an error message to the user of a command, accepts any value and will print in a readable and safe format
-- @tparam any message The message / value to be printed
function Commands.error(message)
return Commands.print(message, Color.orange_red, 'utility/wire_pickup')
return Commands.print(message, Color.orange_red, "utility/wire_pickup")
end
--- Command Prototype
@@ -382,7 +382,7 @@ end
--- This is a default callback that should never be called
local function default_command_callback()
return Commands.status.internal_error('No callback registered')
return Commands.status.internal_error("No callback registered")
end
--- Returns a new command object, this will not register the command to the game
@@ -393,7 +393,7 @@ function Commands.new(name, help)
ExpUtil.assert_argument_type(name, "string", 1, "name")
ExpUtil.assert_argument_type(help, "string", 2, "help")
if Commands.registered_commands[name] then
error("Command is already defined at: "..Commands.registered_commands[name].defined_at, 2)
error("Command is already defined at: " .. Commands.registered_commands[name].defined_at, 2)
end
return setmetatable({
@@ -414,7 +414,7 @@ end
local function get_parser(data_type)
local rtn = Commands.data_types[data_type]
if rtn == nil then
error("Unknown data type: "..tostring(data_type), 3)
error("Unknown data type: " .. tostring(data_type), 3)
end
return data_type, rtn
end
@@ -434,7 +434,7 @@ function Commands._prototype:argument(name, data_type, ...)
optional = false,
data_type = data_type,
data_type_parser = get_parser(data_type),
parse_args = {...}
parse_args = { ... },
}
return self
end
@@ -450,7 +450,7 @@ function Commands._prototype:optional(name, data_type, ...)
optional = true,
data_type = data_type,
data_type_parser = get_parser(data_type),
parse_args = {...}
parse_args = { ... },
}
return self
end
@@ -459,22 +459,24 @@ end
-- @tparam table defaults A table who's keys are the argument names and values are the defaults or function which returns a default
-- @treturn Command The command object to allow chaining method calls
function Commands._prototype:defaults(defaults)
local matched = {}
for _, argument in ipairs(self.arguments) do
if defaults[argument.name] then
if not argument.optional then
error("Attempting to set default value for required argument: " .. argument.name)
end
argument.default = defaults[argument.name]
matched[argument.name] = true
end
end
-- Check that there are no extra values in the table
for name in pairs(defaults) do
if not matched[name] then
error("No argument with name: " .. name)
local matched = {}
for _, argument in ipairs(self.arguments) do
if defaults[argument.name] then
if not argument.optional then
error("Attempting to set default value for required argument: " .. argument.name)
end
argument.default = defaults[argument.name]
matched[argument.name] = true
end
end
-- Check that there are no extra values in the table
for name in pairs(defaults) do
if not matched[name] then
error("No argument with name: " .. name)
end
end
return self
end
@@ -489,6 +491,7 @@ function Commands._prototype:add_flags(flags)
self.flags[name] = value
end
end
return self
end
@@ -500,6 +503,7 @@ function Commands._prototype:add_aliases(aliases)
for index, alias in ipairs(aliases) do
self.aliases[start_index + index] = alias
end
return self
end
@@ -520,11 +524,12 @@ function Commands._prototype:register(callback)
local description = {}
for index, argument in pairs(self.arguments) do
if argument.optional then
description[index] = "["..argument.name.."]"
description[index] = "[" .. argument.name .. "]"
else
description[index] = "<"..argument.name..">"
description[index] = "<" .. argument.name .. ">"
end
end
self.description = table.concat(description, " ")
-- Callback which is called by the game engine
@@ -539,7 +544,7 @@ function Commands._prototype:register(callback)
end
-- Registers the command under its own name
local help = {'exp-commands.command-help', self.description, self.help}
local help = { "exp-commands.command-help", self.description, self.help }
commands.add_command(self.name, help, command_callback)
-- Registers the command under its aliases
@@ -554,42 +559,42 @@ end
--- Log that a command was attempted and its outcome (error / success)
local function log_command(comment, command, player, args, detail)
local player_name = player and player.name or '<Server>'
ExpUtil.write_json('log/commands.log', {
local player_name = player and player.name or "<Server>"
ExpUtil.write_json("log/commands.log", {
comment = comment,
detail = detail,
player_name = player_name,
command_name = command.name,
args = args
args = args,
})
end
--- Extract the arguments from a string input string
local function extract_arguments(raw_input, max_args, auto_concat)
-- nil check when no input given
if raw_input == nil then return {} end
-- nil check when no input given
if raw_input == nil then return {} end
-- Extract quoted arguments
local quoted_arguments = {}
local input_string = raw_input:gsub('"[^"]-"', function(word)
local no_spaces = word:gsub('%s', '%%s')
local no_spaces = word:gsub("%s", "%%s")
quoted_arguments[no_spaces] = word:sub(2, -2)
return ' '..no_spaces..' '
return " " .. no_spaces .. " "
end)
-- Extract all arguments
local index = 0
local arguments = {}
for word in input_string:gmatch('%S+') do
for word in input_string:gmatch("%S+") do
index = index + 1
if index > max_args then
-- concat the word onto the last argument
if auto_concat == false then
return nil -- too many args, exit early
elseif quoted_arguments[word] then
arguments[max_args] = arguments[max_args]..' "'..quoted_arguments[word]..'"'
arguments[max_args] = arguments[max_args] .. ' "' .. quoted_arguments[word] .. '"'
else
arguments[max_args] = arguments[max_args]..' '..word
arguments[max_args] = arguments[max_args] .. " " .. word
end
else
-- new argument to be added
@@ -608,7 +613,7 @@ end
function Commands._event_handler(event)
local command = Commands.registered_commands[event.name]
if command == nil then
error("Command not recognised: "..event.name)
error("Command not recognised: " .. event.name)
end
local player = nil -- nil represents the server until the command is called
@@ -626,20 +631,20 @@ function Commands._event_handler(event)
-- Check the edge case of parameter being nil
if command.min_arg_count > 0 and event.parameter == nil then
log_command("Too few arguments", command, player, event.parameter, { minimum = command.min_arg_count, maximum = command.max_arg_count })
return Commands.error{'exp-commands.invalid-usage', command.name, command.description}
return Commands.error{ "exp-commands.invalid-usage", command.name, command.description }
end
-- Get the arguments for the command, returns nil if there are too many arguments
local raw_arguments = extract_arguments(event.parameter, command.max_arg_count, command.auto_concat)
if raw_arguments == nil then
log_command("Too many arguments", command, player, event.parameter, { minimum = command.min_arg_count, maximum = command.max_arg_count })
return Commands.error{'exp-commands.invalid-usage', command.name, command.description}
return Commands.error{ "exp-commands.invalid-usage", command.name, command.description }
end
-- Check the minimum number of arguments is fullfiled
if #raw_arguments < command.min_arg_count then
log_command("Too few arguments", command, player, event.parameter, { minimum = command.min_arg_count, maximum = command.max_arg_count })
return Commands.error{'exp-commands.invalid-usage', command.name, command.description}
return Commands.error{ "exp-commands.invalid-usage", command.name, command.description }
end
-- Parse the arguments, optional arguments will attempt to use a default if provided
@@ -659,7 +664,7 @@ function Commands._event_handler(event)
local success, status, parsed = Commands.parse_data_type(argument.data_type_parser, input, player, table.unpack(argument.parse_args))
if success == false then
log_command("Input parse failed", command, player, event.parameter, { status = valid_command_status[status], index = index, argument = argument, reason = parsed })
return Commands.error{'exp-commands.invalid-argument', argument.name, parsed}
return Commands.error{ "exp-commands.invalid-argument", argument.name, parsed }
else
arguments[index] = parsed
end

View File

@@ -4,122 +4,124 @@ local Groups = require("modules/exp_groups")
local pending_updates = {}
Global.register(pending_updates, function(tbl)
pending_updates = tbl
pending_updates = tbl
end)
local function on_permission_group_added(event)
if not event.player_index then return end
pending_updates[event.group.name] = {
created = true,
sync_all = true,
tick = event.tick,
permissions = {},
players = {},
}
if not event.player_index then return end
pending_updates[event.group.name] = {
created = true,
sync_all = true,
tick = event.tick,
permissions = {},
players = {},
}
end
local function on_permission_group_deleted(event)
if not event.player_index then return end
local existing = pending_updates[event.group_name]
pending_updates[event.group_name] = nil
if not existing or not existing.created then
clusterio_api.send_json("exp_groups-permission_group_delete", {
group = event.group_name,
})
end
if not event.player_index then return end
local existing = pending_updates[event.group_name]
pending_updates[event.group_name] = nil
if not existing or not existing.created then
clusterio_api.send_json("exp_groups-permission_group_delete", {
group = event.group_name,
})
end
end
local function on_permission_group_edited(event)
if not event.player_index then return end
local pending = pending_updates[event.group.name]
if not pending then
pending = {
tick = event.tick,
permissions = {},
players = {},
}
pending_updates[event.group.name] = pending
end
pending.tick = event.tick
if not event.player_index then return end
local pending = pending_updates[event.group.name]
if not pending then
pending = {
tick = event.tick,
permissions = {},
players = {},
}
pending_updates[event.group.name] = pending
end
pending.tick = event.tick
if event.type == "add-permission" then
if not pending.sync_all then
pending.permissions[event.action] = true
end
elseif event.type == "remove-permission" then
if not pending.sync_all then
pending.permissions[event.action] = false
end
elseif event.type == "enable-all" then
pending.sync_all = true
elseif event.type == "disable-all" then
pending.sync_all = true
elseif event.type == "add-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = true
elseif event.type == "remove-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = nil
elseif event.type == "rename" then
pending.created = true
pending.sync_all = true
local old = pending_updates[event.old_name]
if old then pending.players = old.players end
on_permission_group_deleted{
tick = event.tick, player_index = event.player_index, group_name = event.old_name
}
end
if event.type == "add-permission" then
if not pending.sync_all then
pending.permissions[event.action] = true
end
elseif event.type == "remove-permission" then
if not pending.sync_all then
pending.permissions[event.action] = false
end
elseif event.type == "enable-all" then
pending.sync_all = true
elseif event.type == "disable-all" then
pending.sync_all = true
elseif event.type == "add-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = true
elseif event.type == "remove-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = nil
elseif event.type == "rename" then
pending.created = true
pending.sync_all = true
local old = pending_updates[event.old_name]
if old then pending.players = old.players end
on_permission_group_deleted{
tick = event.tick, player_index = event.player_index, group_name = event.old_name,
}
end
end
local function send_updates()
local tick = game.tick - 600 -- 10 Seconds
local done = {}
for group_name, pending in pairs(pending_updates) do
if pending.tick < tick then
done[group_name] = true
if pending.sync_all then
clusterio_api.send_json("exp_groups-permission_group_create", {
group = group_name, defiantion = Groups.get_group(group_name):to_json(true)
})
else
if next(pending.players) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "assign_players", group = group_name, changes = table.get_keys(pending.players)
})
end
local add, remove = {}, {}
for permission, state in pairs(pending.permissions) do
if state then
add[#add + 1] = permission
else
remove[#remove + 1] = permission
end
end
if next(add) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "add_permissions", group = group_name, changes = Groups.actions_to_names(add)
})
end
if next(remove) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "remove_permissions", group = group_name, changes = Groups.actions_to_names(remove)
})
end
end
end
end
for group_name in pairs(done) do
pending_updates[group_name] = nil
end
local tick = game.tick - 600 -- 10 Seconds
local done = {}
for group_name, pending in pairs(pending_updates) do
if pending.tick < tick then
done[group_name] = true
if pending.sync_all then
clusterio_api.send_json("exp_groups-permission_group_create", {
group = group_name, defiantion = Groups.get_group(group_name):to_json(true),
})
else
if next(pending.players) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "assign_players", group = group_name, changes = table.get_keys(pending.players),
})
end
local add, remove = {}, {}
for permission, state in pairs(pending.permissions) do
if state then
add[#add + 1] = permission
else
remove[#remove + 1] = permission
end
end
if next(add) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "add_permissions", group = group_name, changes = Groups.actions_to_names(add),
})
end
if next(remove) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "remove_permissions", group = group_name, changes = Groups.actions_to_names(remove),
})
end
end
end
end
for group_name in pairs(done) do
pending_updates[group_name] = nil
end
end
return {
events = {
[defines.events.on_permission_group_added] = on_permission_group_added,
[defines.events.on_permission_group_deleted] = on_permission_group_deleted,
[defines.events.on_permission_group_edited] = on_permission_group_edited,
},
on_nth_tick = {
[300] = send_updates,
}
events = {
[defines.events.on_permission_group_added] = on_permission_group_added,
[defines.events.on_permission_group_deleted] = on_permission_group_deleted,
[defines.events.on_permission_group_edited] = on_permission_group_edited,
},
on_nth_tick = {
[300] = send_updates,
},
}

View File

@@ -3,46 +3,47 @@ local Async = require("modules/exp_util/async")
--- Top level module table, contains event handlers and public methods
local Groups = {}
---@class ExpGroup
---@field group LuaPermissionGroup The permission group for this group proxy
--- @class ExpGroup
--- @field group LuaPermissionGroup The permission group for this group proxy
Groups._prototype = {}
Groups._metatable = {
__index = setmetatable(Groups._prototype, {
__index = function(self, key)
return self.group[key]
end
}),
__class = "ExpGroup"
__index = setmetatable(Groups._prototype, {
__index = function(self, key)
return self.group[key]
end,
}),
__class = "ExpGroup",
}
local action_to_name = {}
for name, action in pairs(defines.input_action) do
action_to_name[action] = name
action_to_name[action] = name
end
--- Async Functions
-- These are required to allow bypassing edit_permission_group
--- Add a player to a permission group, requires edit_permission_group
---@param player LuaPlayer Player to add to the group
---@param group LuaPermissionGroup Group to add the player to
--- @param player LuaPlayer Player to add to the group
--- @param group LuaPermissionGroup Group to add the player to
local function add_player_to_group(player, group)
return group.add_player(player)
return group.add_player(player)
end
--- Add a players to a permission group, requires edit_permission_group
---@param players LuaPlayer[] Players to add to the group
---@param group LuaPermissionGroup Group to add the players to
--- @param players LuaPlayer[] Players to add to the group
--- @param group LuaPermissionGroup Group to add the players to
local function add_players_to_group(players, group)
local add_player = group.add_player
if not add_player(players[1]) then
return false
end
for i = 2, #players do
add_player(players[i])
end
return true
local add_player = group.add_player
if not add_player(players[1]) then
return false
end
for i = 2, #players do
add_player(players[i])
end
return true
end
-- Async will bypass edit_permission_group but takes at least one tick
@@ -52,225 +53,230 @@ local add_players_to_group_async = Async.register(add_players_to_group)
--- Static methods for gettings, creating and removing permission groups
--- Gets the permission group proxy with the given name or group ID.
---@param group_name string|uint32 The name or id of the permission group
--- @param group_name string|uint32 The name or id of the permission group
function Groups.get_group(group_name)
local group = game.permissions.get_group(group_name)
if group == nil then return nil end
return setmetatable({
group = group
}, Groups._metatable)
local group = game.permissions.get_group(group_name)
if group == nil then return nil end
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Gets the permission group proxy for a players group
---@param player LuaPlayer The player to get the group of
--- @param player LuaPlayer The player to get the group of
function Groups.get_player_group(player)
local group = player.permission_group
if group == nil then return nil end
return setmetatable({
group = group
}, Groups._metatable)
local group = player.permission_group
if group == nil then return nil end
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Creates a new permission group, requires add_permission_group
---@param group_name string Name of the group to create
--- @param group_name string Name of the group to create
function Groups.new_group(group_name)
local group = game.permissions.get_group(group_name)
assert(group == nil, "Group already exists with name: " .. group_name)
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group
}, Groups._metatable)
local group = game.permissions.get_group(group_name)
assert(group == nil, "Group already exists with name: " .. group_name)
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Get or create a permisison group, must use the group name not the group id
---@param group_name string Name of the group to create
--- @param group_name string Name of the group to create
function Groups.get_or_create(group_name)
local group = game.permissions.get_group(group_name)
if group then
return setmetatable({
group = group
}, Groups._metatable)
else
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group
}, Groups._metatable)
end
local group = game.permissions.get_group(group_name)
if group then
return setmetatable({
group = group,
}, Groups._metatable)
else
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group,
}, Groups._metatable)
end
end
--- Destory a permission group, moves all players to default group
---@param group_name string|uint32 The name or id of the permission group to destroy
---@param move_to_name string|uint32? The name or id of the permission group to move players to
--- @param group_name string|uint32 The name or id of the permission group to destroy
--- @param move_to_name string|uint32? The name or id of the permission group to move players to
function Groups.destroy_group(group_name, move_to_name)
local group = game.permissions.get_group(group_name)
if group == nil then return nil end
local group = game.permissions.get_group(group_name)
if group == nil then return nil end
local players = group.players
if #players > 0 then
local move_to = game.permissions.get_group(move_to_name or "Default")
for _, player in ipairs(players) do
player.permission_group = move_to
end
end
local players = group.players
if #players > 0 then
local move_to = game.permissions.get_group(move_to_name or "Default")
for _, player in ipairs(players) do
player.permission_group = move_to
end
end
local success = group.destroy()
assert(success, "Requires permission delete_permission_group")
local success = group.destroy()
assert(success, "Requires permission delete_permission_group")
end
--- Prototype methods for modifying and working with permission groups
--- Add a player to the permission group
---@param player LuaPlayer The player to add to the group
--- @param player LuaPlayer The player to add to the group
function Groups._prototype:add_player(player)
return add_player_to_group(player, self.group) or add_player_to_group_async(player, self.group)
return add_player_to_group(player, self.group) or add_player_to_group_async(player, self.group)
end
--- Add players to the permission group
---@param players LuaPlayer[] The player to add to the group
--- @param players LuaPlayer[] The player to add to the group
function Groups._prototype:add_players(players)
return add_players_to_group(players, self.group) or add_players_to_group_async(players, self.group)
return add_players_to_group(players, self.group) or add_players_to_group_async(players, self.group)
end
--- Move all players to another group
---@param other_group ExpGroup The group to move players to, default is the Default group
--- @param other_group ExpGroup The group to move players to, default is the Default group
function Groups._prototype:move_players(other_group)
return add_players_to_group(self.group.players, other_group.group) or add_players_to_group_async(self.group.players, other_group.group)
return add_players_to_group(self.group.players, other_group.group) or add_players_to_group_async(self.group.players, other_group.group)
end
--- Allow a set of actions for this group
---@param actions defines.input_action[] Actions to allow
--- @param actions defines.input_action[] Actions to allow
function Groups._prototype:allow_actions(actions)
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, true)
end
return self
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, true)
end
return self
end
--- Disallow a set of actions for this group
---@param actions defines.input_action[] Actions to disallow
--- @param actions defines.input_action[] Actions to disallow
function Groups._prototype:disallow_actions(actions)
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, false)
end
return self
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, false)
end
return self
end
--- Reset the allowed state of all actions
---@param allowed boolean? default true for allow all actions, false to disallow all actions
--- @param allowed boolean? default true for allow all actions, false to disallow all actions
function Groups._prototype:reset(allowed)
local set_allow = self.group.set_allows_action
if allowed == nil then allowed = true end
for _, action in pairs(defines.input_action) do
set_allow(action, allowed)
end
return self
local set_allow = self.group.set_allows_action
if allowed == nil then allowed = true end
for _, action in pairs(defines.input_action) do
set_allow(action, allowed)
end
return self
end
--- Returns if the group is allowed a given action
---@param action string|defines.input_action Actions to test
--- @param action string|defines.input_action Actions to test
function Groups._prototype:allows(action)
if type(action) == "string" then
return self.group.allows_action(defines.input_action[action])
end
return self.group.allows_action(action)
if type(action) == "string" then
return self.group.allows_action(defines.input_action[action])
end
return self.group.allows_action(action)
end
--- Print a message to all players in the group
function Groups._prototype:print(...)
for _, player in ipairs(self.group.players) do
player.print(...)
end
for _, player in ipairs(self.group.players) do
player.print(...)
end
end
--- Static and Prototype methods for use with IPC
--- Convert an array of strings into an array of action names
---@param actions_names string[] An array of action names
--- @param actions_names string[] An array of action names
local function names_to_actions(actions_names)
local actions, invalid, invalid_i = {}, {}, 1
for i, action_name in ipairs(actions_names) do
local action = defines.input_action[action_name]
if action then
actions[i] = action
else
invalid[invalid_i] = i
invalid_i = invalid_i + 1
end
end
local actions, invalid, invalid_i = {}, {}, 1
for i, action_name in ipairs(actions_names) do
local action = defines.input_action[action_name]
if action then
actions[i] = action
else
invalid[invalid_i] = i
invalid_i = invalid_i + 1
end
end
local last = #actions
for _, i in ipairs(invalid) do
actions[i] = actions[last]
last = last - 1
end
local last = #actions
for _, i in ipairs(invalid) do
actions[i] = actions[last]
last = last - 1
end
return actions
return actions
end
--- Get the action names from the action numbers
function Groups.actions_to_names(actions)
local names = {}
for i, action in ipairs(actions) do
names[i] = action_to_name[action]
end
return names
local names = {}
for i, action in ipairs(actions) do
names[i] = action_to_name[action]
end
return names
end
--- Get all input actions that are defined
function Groups.get_actions_json()
local rtn, rtn_i = {}, 1
for name in pairs(defines.input_action) do
rtn[rtn_i] = name
rtn_i = rtn_i + 1
end
return game.table_to_json(rtn)
local rtn, rtn_i = {}, 1
for name in pairs(defines.input_action) do
rtn[rtn_i] = name
rtn_i = rtn_i + 1
end
return game.table_to_json(rtn)
end
--- Convert a json string array into an array of input actions
---@param json string A json string representing a string array of actions
--- @param json string A json string representing a string array of actions
function Groups.json_to_actions(json)
local tbl = game.json_to_table(json)
assert(tbl, "Invalid Json String")
---@cast tbl string[]
return names_to_actions(tbl)
local tbl = game.json_to_table(json)
assert(tbl, "Invalid Json String")
--- @cast tbl string[]
return names_to_actions(tbl)
end
--- Returns the shortest defination of the allowed actions
-- The first value of the return can be passed to :reset
function Groups._prototype:to_json(raw)
local allow, disallow = {}, {}
local allow_i, disallow_i = 1, 1
local allows = self.group.allows_action
for name, action in pairs(defines.input_action) do
if allows(action) then
allow[allow_i] = name
allow_i = allow_i + 1
else
disallow[disallow_i] = name
disallow_i = disallow_i + 1
end
end
local allow, disallow = {}, {}
local allow_i, disallow_i = 1, 1
local allows = self.group.allows_action
for name, action in pairs(defines.input_action) do
if allows(action) then
allow[allow_i] = name
allow_i = allow_i + 1
else
disallow[disallow_i] = name
disallow_i = disallow_i + 1
end
end
if allow_i >= disallow_i then
return raw and {true, disallow} or game.table_to_json{ true, disallow }
end
return raw and {false, allow} or game.table_to_json{ false, allow }
if allow_i >= disallow_i then
return raw and { true, disallow } or game.table_to_json{ true, disallow }
end
return raw and { false, allow } or game.table_to_json{ false, allow }
end
--- Restores this group to the state given in a json string
---@param json string The json string to restore from
--- @param json string The json string to restore from
function Groups._prototype:from_json(json)
local tbl = game.json_to_table(json)
assert(tbl and type(tbl[1]) == "boolean" and type(tbl[2]) == "table", "Invalid Json String")
local tbl = game.json_to_table(json)
assert(tbl and type(tbl[1]) == "boolean" and type(tbl[2]) == "table", "Invalid Json String")
if tbl[1] then
return self:reset(true):disallow_actions(names_to_actions(tbl[2]))
end
return self:reset(false):allow_actions(names_to_actions(tbl[2]))
if tbl[1] then
return self:reset(true):disallow_actions(names_to_actions(tbl[2]))
end
return self:reset(false):allow_actions(names_to_actions(tbl[2]))
end
return Groups

View File

@@ -4,109 +4,109 @@
-- core files should be required by modules and not be present in this list;
-- @config File-Loader
return {
--'example.file_not_loaded',
'modules.factorio-control', -- base factorio free play scenario
'expcore.player_data', -- must be loaded first to register event handlers
-- 'example.file_not_loaded',
"modules.factorio-control", -- base factorio free play scenario
"expcore.player_data", -- must be loaded first to register event handlers
--- Game Commands
'modules.commands.debug',
'modules.commands.me',
'modules.commands.kill',
'modules.commands.admin-chat',
'modules.commands.admin-markers',
'modules.commands.teleport',
'modules.commands.cheat-mode',
'modules.commands.ratio',
'modules.commands.interface',
'modules.commands.help',
'modules.commands.roles',
'modules.commands.rainbow',
'modules.commands.clear-inventory',
'modules.commands.jail',
'modules.commands.repair',
'modules.commands.reports',
'modules.commands.spawn',
'modules.commands.warnings',
'modules.commands.find',
'modules.commands.home',
'modules.commands.connect',
'modules.commands.last-location',
'modules.commands.protection',
'modules.commands.spectate',
'modules.commands.search',
'modules.commands.bot-queue',
'modules.commands.speed',
'modules.commands.pollution',
'modules.commands.train',
'modules.commands.friendly-fire',
'modules.commands.research',
'modules.commands.vlayer',
'modules.commands.enemy',
'modules.commands.waterfill',
'modules.commands.artillery',
'modules.commands.surface-clearing',
"modules.commands.debug",
"modules.commands.me",
"modules.commands.kill",
"modules.commands.admin-chat",
"modules.commands.admin-markers",
"modules.commands.teleport",
"modules.commands.cheat-mode",
"modules.commands.ratio",
"modules.commands.interface",
"modules.commands.help",
"modules.commands.roles",
"modules.commands.rainbow",
"modules.commands.clear-inventory",
"modules.commands.jail",
"modules.commands.repair",
"modules.commands.reports",
"modules.commands.spawn",
"modules.commands.warnings",
"modules.commands.find",
"modules.commands.home",
"modules.commands.connect",
"modules.commands.last-location",
"modules.commands.protection",
"modules.commands.spectate",
"modules.commands.search",
"modules.commands.bot-queue",
"modules.commands.speed",
"modules.commands.pollution",
"modules.commands.train",
"modules.commands.friendly-fire",
"modules.commands.research",
"modules.commands.vlayer",
"modules.commands.enemy",
"modules.commands.waterfill",
"modules.commands.artillery",
"modules.commands.surface-clearing",
--- Addons
'modules.addons.chat-popups',
'modules.addons.damage-popups',
'modules.addons.death-logger',
'modules.addons.advanced-start',
'modules.addons.spawn-area',
'modules.addons.compilatron',
'modules.addons.scorched-earth',
'modules.addons.pollution-grading',
'modules.addons.station-auto-name',
'modules.addons.discord-alerts',
'modules.addons.chat-reply',
'modules.addons.tree-decon',
'modules.addons.afk-kick',
'modules.addons.report-jail',
'modules.addons.protection-jail',
'modules.addons.deconlog',
'modules.addons.nukeprotect',
'modules.addons.inserter',
'modules.addons.miner',
'modules.addons.lawnmower',
'modules.addons.logging',
"modules.addons.chat-popups",
"modules.addons.damage-popups",
"modules.addons.death-logger",
"modules.addons.advanced-start",
"modules.addons.spawn-area",
"modules.addons.compilatron",
"modules.addons.scorched-earth",
"modules.addons.pollution-grading",
"modules.addons.station-auto-name",
"modules.addons.discord-alerts",
"modules.addons.chat-reply",
"modules.addons.tree-decon",
"modules.addons.afk-kick",
"modules.addons.report-jail",
"modules.addons.protection-jail",
"modules.addons.deconlog",
"modules.addons.nukeprotect",
"modules.addons.inserter",
"modules.addons.miner",
"modules.addons.lawnmower",
"modules.addons.logging",
-- Control
'modules.control.vlayer',
"modules.control.vlayer",
--- Data
'modules.data.statistics',
'modules.data.player-colours',
'modules.data.greetings',
'modules.data.quickbar',
'modules.data.alt-view',
'modules.data.tag',
"modules.data.statistics",
"modules.data.player-colours",
"modules.data.greetings",
"modules.data.quickbar",
"modules.data.alt-view",
"modules.data.tag",
-- 'modules.data.bonus',
'modules.data.personal-logistic',
'modules.data.language',
"modules.data.personal-logistic",
"modules.data.language",
--- GUI
'modules.gui.readme',
'modules.gui.rocket-info',
'modules.gui.science-info',
'modules.gui.autofill',
'modules.gui.warp-list',
'modules.gui.task-list',
'modules.gui.player-list',
'modules.gui.server-ups',
'modules.gui.bonus',
'modules.gui.vlayer',
'modules.gui.research',
'modules.gui.module',
'modules.gui.landfill',
'modules.gui.production',
'modules.gui.playerdata',
'modules.gui.surveillance',
'modules.graftorio.require', -- graftorio
'modules.gui.toolbar', -- must be loaded last to register toolbar handlers
"modules.gui.readme",
"modules.gui.rocket-info",
"modules.gui.science-info",
"modules.gui.autofill",
"modules.gui.warp-list",
"modules.gui.task-list",
"modules.gui.player-list",
"modules.gui.server-ups",
"modules.gui.bonus",
"modules.gui.vlayer",
"modules.gui.research",
"modules.gui.module",
"modules.gui.landfill",
"modules.gui.production",
"modules.gui.playerdata",
"modules.gui.surveillance",
"modules.graftorio.require", -- graftorio
"modules.gui.toolbar", -- must be loaded last to register toolbar handlers
--- Config Files
'config.expcore.command_auth_admin', -- commands tagged with admin_only are blocked for non admins
'config.expcore.command_auth_roles', -- commands must be allowed via the role config
'config.expcore.command_runtime_disable', -- allows commands to be enabled and disabled during runtime
'config.expcore.permission_groups', -- loads some predefined permission groups
'config.expcore.roles', -- loads some predefined roles
"config.expcore.command_auth_admin", -- commands tagged with admin_only are blocked for non admins
"config.expcore.command_auth_roles", -- commands must be allowed via the role config
"config.expcore.command_runtime_disable", -- allows commands to be enabled and disabled during runtime
"config.expcore.permission_groups", -- loads some predefined permission groups
"config.expcore.roles", -- loads some predefined roles
}

View File

@@ -73,58 +73,58 @@ end
]]
return {
skip_intro=true, --- @setting skip_intro skips the intro given in the default factorio free play scenario
skip_victory=true, --- @setting skip_victory will skip the victory screen when a rocket is launched
disable_base_game_silo_script=true, --- @setting disable_base_game_silo_script will not load the silo script at all
research_queue_from_start=true, --- @setting research_queue_from_start when true the research queue is useable from the start
friendly_fire=false, --- @setting friendly_fire weather players will be able to attack each other on the same force
enemy_expansion=false, --- @setting enemy_expansion a catch all for in case the map settings file fails to load
chart_radius=10*32, --- @setting chart_radius the number of tiles that will be charted when the map starts
skip_intro = true, --- @setting skip_intro skips the intro given in the default factorio free play scenario
skip_victory = true, --- @setting skip_victory will skip the victory screen when a rocket is launched
disable_base_game_silo_script = true, --- @setting disable_base_game_silo_script will not load the silo script at all
research_queue_from_start = true, --- @setting research_queue_from_start when true the research queue is useable from the start
friendly_fire = false, --- @setting friendly_fire weather players will be able to attack each other on the same force
enemy_expansion = false, --- @setting enemy_expansion a catch all for in case the map settings file fails to load
chart_radius = 10 * 32, --- @setting chart_radius the number of tiles that will be charted when the map starts
items = { --- @setting items items and there condition for being given
-- ['item-name'] = function(amount_made, production_stats, player) return <Number> end -- 0 means no items given
-- Plates
['iron-plate']=scale_amount_made(100, 10, 10),
['copper-plate']=scale_amount_made(100, 0, 8),
['steel-plate']=scale_amount_made(100, 0, 4),
["iron-plate"] = scale_amount_made(100, 10, 10),
["copper-plate"] = scale_amount_made(100, 0, 8),
["steel-plate"] = scale_amount_made(100, 0, 4),
-- Secondary Items
['electronic-circuit']=scale_amount_made(1000, 0, 6),
['iron-gear-wheel']=scale_amount_made(1000, 0, 6),
["electronic-circuit"] = scale_amount_made(1000, 0, 6),
["iron-gear-wheel"] = scale_amount_made(1000, 0, 6),
-- Starting Items
['burner-mining-drill']=cutoff_time(10*minutes, 4, 0),
['stone-furnace']=cutoff_time(10*minutes, 4, 0),
["burner-mining-drill"] = cutoff_time(10 * minutes, 4, 0),
["stone-furnace"] = cutoff_time(10 * minutes, 4, 0),
-- Armor
['light-armor']=cutoff_amount_made_unless(5, 0,1,'heavy-armor',5),
['heavy-armor']=cutoff_amount_made(5, 0,1),
["light-armor"] = cutoff_amount_made_unless(5, 0, 1, "heavy-armor", 5),
["heavy-armor"] = cutoff_amount_made(5, 0, 1),
-- Weapon
['pistol']=cutoff_amount_made_unless(0, 1, 1,'submachine-gun',5),
['submachine-gun']=cutoff_amount_made(5, 0, 1),
["pistol"] = cutoff_amount_made_unless(0, 1, 1, "submachine-gun", 5),
["submachine-gun"] = cutoff_amount_made(5, 0, 1),
-- Ammo
['firearm-magazine']=cutoff_amount_made_unless(100, 10, 0,'piercing-rounds-magazine', 100),
['piercing-rounds-magazine']=cutoff_amount_made(100, 0, 10),
["firearm-magazine"] = cutoff_amount_made_unless(100, 10, 0, "piercing-rounds-magazine", 100),
["piercing-rounds-magazine"] = cutoff_amount_made(100, 0, 10),
--[[
['construction-robot']=scale_amount_made(1, 10, 1)
]]
},
armor = {
enable=false,
main = 'modular-armor',
enable = false,
main = "modular-armor",
item = {
{
equipment='solar-panel-equipment',
count=16
equipment = "solar-panel-equipment",
count = 16,
},
{
equipment='belt-immunity-equipment',
count=1
equipment = "belt-immunity-equipment",
count = 1,
},
{
equipment='battery-equipment',
count=2
equipment = "battery-equipment",
count = 2,
},
{
equipment='personal-roboport-equipment',
count=1
equipment = "personal-roboport-equipment",
count = 1,
},
}
}
},
},
}

View File

@@ -1,9 +1,9 @@
return {
admin_as_active = true, --- @setting admin_as_active When true admins will be treated as active regardless of afk time
trust_as_active = true, --- @setting trust_as_active When true trusted players (by playtime) will be treated as active regardless of afk time
active_role = 'Veteran', --- @setting active_role When not nil a player with this role will be treated as active regardless of afk time
afk_time = 3600*10, --- @setting afk_time The time in ticks that must pass for a player to be considered afk
kick_time = 3600*30, --- @setting kick_time The time in ticks that must pass without any active players for all players to be kicked
trust_time = 3600*60*10, --- @setting trust_time The time in ticks that a player must be online for to count as trusted
update_time = 3600*30, --- @setting update_time How often in ticks the script checks for active players
}
active_role = "Veteran", --- @setting active_role When not nil a player with this role will be treated as active regardless of afk time
afk_time = 3600 * 10, --- @setting afk_time The time in ticks that must pass for a player to be considered afk
kick_time = 3600 * 30, --- @setting kick_time The time in ticks that must pass without any active players for all players to be kicked
trust_time = 3600 * 60 * 10, --- @setting trust_time The time in ticks that a player must be online for to count as trusted
update_time = 3600 * 30, --- @setting update_time How often in ticks the script checks for active players
}

View File

@@ -17,79 +17,79 @@ return {
= 480
]]
pts = {
base = 260
base = 260,
},
gui_display_width = {
half = 150,
label = 70,
slider = 180,
count = 50
count = 50,
},
conversion = {
['cmms'] = 'character_mining_speed_modifier',
['crs'] = 'character_running_speed_modifier',
['ccs'] = 'character_crafting_speed_modifier',
['cisb'] = 'character_inventory_slots_bonus',
['chb'] = 'character_health_bonus',
['crdb'] = 'character_reach_distance_bonus',
["cmms"] = "character_mining_speed_modifier",
["crs"] = "character_running_speed_modifier",
["ccs"] = "character_crafting_speed_modifier",
["cisb"] = "character_inventory_slots_bonus",
["chb"] = "character_health_bonus",
["crdb"] = "character_reach_distance_bonus",
--[[
['cpdb'] = 'character_item_pickup_distance_bonus'
]]
},
player_special_bonus_rate = 300,
player_special_bonus = {
['personal_battery_recharge'] = {
["personal_battery_recharge"] = {
-- 1 MW
value = 6,
max = 12,
scale = 1,
cost_scale = 4,
cost = 40,
is_percentage = false
}
is_percentage = false,
},
},
player_bonus = {
['character_mining_speed_modifier'] = {
["character_mining_speed_modifier"] = {
value = 3,
max = 6,
scale = 0.5,
cost_scale = 1,
cost = 10,
is_percentage = true
is_percentage = true,
},
['character_running_speed_modifier'] = {
["character_running_speed_modifier"] = {
value = 1.5,
max = 3,
scale = 0.25,
cost_scale = 1,
cost = 60,
is_percentage = true
is_percentage = true,
},
['character_crafting_speed_modifier'] = {
["character_crafting_speed_modifier"] = {
value = 8,
max = 16,
scale = 1,
cost_scale = 1,
cost = 4,
is_percentage = true
is_percentage = true,
},
['character_inventory_slots_bonus'] = {
["character_inventory_slots_bonus"] = {
value = 100,
max = 200,
scale = 10,
cost_scale = 10,
cost = 2,
is_percentage = false
is_percentage = false,
},
['character_health_bonus'] = {
["character_health_bonus"] = {
value = 200,
max = 400,
scale = 50,
cost_scale = 50,
cost = 4,
is_percentage = false
is_percentage = false,
},
['character_reach_distance_bonus'] = {
["character_reach_distance_bonus"] = {
value = 12,
max = 24,
scale = 2,
@@ -97,9 +97,9 @@ return {
cost = 1,
is_percentage = false,
combined_bonus = {
'character_resource_reach_distance_bonus',
'character_build_distance_bonus'
}
"character_resource_reach_distance_bonus",
"character_build_distance_bonus",
},
},
--[[
['character_item_pickup_distance_bonus'] = {
@@ -190,29 +190,29 @@ return {
is_percentage = false
},
]]
['worker_robots_battery_modifier'] = {
["worker_robots_battery_modifier"] = {
value = 1,
max = 1,
scale = 1,
cost_scale = 1,
cost = 1,
is_percentage = false
is_percentage = false,
},
['worker_robots_storage_bonus'] = {
["worker_robots_storage_bonus"] = {
value = 1,
max = 1,
scale = 1,
cost_scale = 1,
cost = 1,
is_percentage = false
is_percentage = false,
},
['following_robots_lifetime_modifier'] = {
["following_robots_lifetime_modifier"] = {
value = 1,
max = 1,
scale = 1,
cost_scale = 1,
cost = 1,
is_percentage = false
is_percentage = false,
},
--[[
['character_item_pickup_distance_bonus'] = {
@@ -316,5 +316,5 @@ return {
is_percentage = false
}
]]
}
},
}

View File

@@ -5,13 +5,13 @@ local ExpUtil = require("modules/exp_util")
local Async = require("modules/exp_util/async")
local send_message_async =
Async.register(function(player, message)
if player == true then
game.print(message)
else
player.print(message)
end
end)
Async.register(function(player, message)
if player == true then
game.print(message)
else
player.print(message)
end
end)
local afk_time_units = {
minutes = true,
@@ -22,107 +22,109 @@ local afk_time_units = {
return {
allow_command_prefix_for_messages = true, --- @setting allow_command_prefix_for_messages when true any message trigger will print to all player when prefixed
messages = { --- @setting messages will trigger when ever the word is said
['discord'] = {'info.discord'},
['expgaming'] = {'info.website'},
['website'] = {'info.website'},
['status'] = {'info.status'},
['github'] = {'info.github'},
['patreon'] = {'info.patreon'},
['donate'] = {'info.patreon'},
['command'] = {'info.custom-commands'},
['commands'] = {'info.custom-commands'},
['softmod'] = {'info.softmod'},
['script'] = {'info.softmod'},
['loop'] = {'chat-bot.loops'},
['rhd'] = {'info.lhd'},
['lhd'] = {'info.lhd'},
['roundabout'] = {'chat-bot.loops'},
['roundabouts'] = {'chat-bot.loops'},
['redmew'] = {'info.redmew'},
['afk'] = function(player, _is_command)
["discord"] = { "info.discord" },
["expgaming"] = { "info.website" },
["website"] = { "info.website" },
["status"] = { "info.status" },
["github"] = { "info.github" },
["patreon"] = { "info.patreon" },
["donate"] = { "info.patreon" },
["command"] = { "info.custom-commands" },
["commands"] = { "info.custom-commands" },
["softmod"] = { "info.softmod" },
["script"] = { "info.softmod" },
["loop"] = { "chat-bot.loops" },
["rhd"] = { "info.lhd" },
["lhd"] = { "info.lhd" },
["roundabout"] = { "chat-bot.loops" },
["roundabouts"] = { "chat-bot.loops" },
["redmew"] = { "info.redmew" },
["afk"] = function(player, _is_command)
local max = player
for _, next_player in pairs(game.connected_players) do
if max.afk_time < next_player.afk_time then
max = next_player
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_locale_time(max.afk_time, "long", afk_time_units) }
end,
['players'] = function(_player, _is_command)
return {'chat-bot.players', #game.players}
["players"] = function(_player, _is_command)
return { "chat-bot.players", #game.players }
end,
['online'] = function(_player, _is_command)
return {'chat-bot.players-online', #game.connected_players}
["online"] = function(_player, _is_command)
return { "chat-bot.players-online", #game.connected_players }
end,
['r!verify'] = function(player, _is_command)
return {'chat-bot.verify', player.name}
["r!verify"] = function(player, _is_command)
return { "chat-bot.verify", player.name }
end,
},
command_admin_only = false, --- @setting command_admin_only when true will only allow chat commands for admins
command_permission = 'command/chat-bot', --- @setting command_permission the permission used to allow command prefixes
command_prefix = '!', --- @setting command_prefix prefix used for commands below and to print to all players (if enabled above)
command_permission = "command/chat-bot", --- @setting command_permission the permission used to allow command prefixes
command_prefix = "!", --- @setting command_prefix prefix used for commands below and to print to all players (if enabled above)
commands = { --- @setting commands will trigger only when command prefix is given
['dev'] = {'chat-bot.not-real-dev'},
['blame'] = function(player, _is_command)
local names = {'Cooldude2606', 'arty714', 'badgamernl', 'mark9064', 'aldldl', 'Drahc_pro', player.name}
["dev"] = { "chat-bot.not-real-dev" },
["blame"] = function(player, _is_command)
local names = { "Cooldude2606", "arty714", "badgamernl", "mark9064", "aldldl", "Drahc_pro", player.name }
for _, next_player in pairs(game.connected_players) do
names[#names + 1] = next_player.name
end
return {'chat-bot.blame', table.get_random_dictionary_entry(names)}
return { "chat-bot.blame", table.get_random_dictionary_entry(names) }
end,
['magic'] = {'chat-bot.magic'},
['aids'] = {'chat-bot.aids'},
['riot'] = {'chat-bot.riot'},
['lenny'] = {'chat-bot.lenny'},
['hodor'] = function(_player, _is_command)
local options = {'?', '.', '!', '!!!'}
return {'chat-bot.hodor', table.get_random_dictionary_entry(options)}
["magic"] = { "chat-bot.magic" },
["aids"] = { "chat-bot.aids" },
["riot"] = { "chat-bot.riot" },
["lenny"] = { "chat-bot.lenny" },
["hodor"] = function(_player, _is_command)
local options = { "?", ".", "!", "!!!" }
return { "chat-bot.hodor", table.get_random_dictionary_entry(options) }
end,
['evolution'] = function(_player, _is_command)
return {'chat-bot.current-evolution', string.format('%.2f', game.forces['enemy'].evolution_factor)}
["evolution"] = function(_player, _is_command)
return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].evolution_factor) }
end,
['makepopcorn'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.get-popcorn-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.get-popcorn-2', player.name}})
["makepopcorn"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.get-popcorn-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.get-popcorn-2", player.name } })
end,
['passsomesnaps'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(player, {'chat-bot.reply', {'chat-bot.get-snaps-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.get-snaps-2', player.name}})
send_message_async:start_after(timeout*(math.random()+0.5), true, {'chat-bot.reply', {'chat-bot.get-snaps-3', player.name}})
["passsomesnaps"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(player, { "chat-bot.reply", { "chat-bot.get-snaps-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.get-snaps-2", player.name } })
send_message_async:start_after(timeout * (math.random() + 0.5), true, { "chat-bot.reply", { "chat-bot.get-snaps-3", player.name } })
end,
['makecocktail'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.get-cocktail-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.get-cocktail-2', player.name}})
send_message_async:start_after(timeout*(math.random()+0.5), true, {'chat-bot.reply', {'chat-bot.get-cocktail-3', player.name}})
["makecocktail"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.get-cocktail-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.get-cocktail-2", player.name } })
send_message_async:start_after(timeout * (math.random() + 0.5), true, { "chat-bot.reply", { "chat-bot.get-cocktail-3", player.name } })
end,
['makecoffee'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.make-coffee-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.make-coffee-2', player.name}})
["makecoffee"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.make-coffee-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.make-coffee-2", player.name } })
end,
['orderpizza'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.order-pizza-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.order-pizza-2', player.name}})
send_message_async:start_after(timeout*(math.random()+0.5), true, {'chat-bot.reply', {'chat-bot.order-pizza-3', player.name}})
["orderpizza"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.order-pizza-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.order-pizza-2", player.name } })
send_message_async:start_after(timeout * (math.random() + 0.5), true, { "chat-bot.reply", { "chat-bot.order-pizza-3", player.name } })
end,
['maketea'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.make-tea-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.make-tea-2', player.name}})
["maketea"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.make-tea-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.make-tea-2", player.name } })
end,
['meadplease'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.get-mead-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.get-mead-2', player.name}})
["meadplease"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.get-mead-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.get-mead-2", player.name } })
end,
['passabeer'] = function(player, _is_command)
local timeout = math.floor(180*(math.random()+0.5))
send_message_async(true, {'chat-bot.reply', {'chat-bot.get-beer-1'}})
send_message_async:start_after(timeout, true, {'chat-bot.reply', {'chat-bot.get-beer-2', player.name}})
end
}
["passabeer"] = function(player, _is_command)
local timeout = math.floor(180 * (math.random() + 0.5))
send_message_async(true, { "chat-bot.reply", { "chat-bot.get-beer-1" } })
send_message_async:start_after(timeout, true, { "chat-bot.reply", { "chat-bot.get-beer-2", player.name } })
end,
},
}

View File

@@ -2,22 +2,22 @@
-- @config Compilatron
return {
message_cycle=60*15, --- @setting message_cycle 15 seconds default, how often (in ticks) the messages will cycle
locations={ --- @setting locations defines the spawn locations for all compilatrons
['Spawn']={x=0,y=0}
message_cycle = 60 * 15, --- @setting message_cycle 15 seconds default, how often (in ticks) the messages will cycle
locations = { --- @setting locations defines the spawn locations for all compilatrons
["Spawn"] = { x = 0, y = 0 },
},
messages={ --- @setting messages the messages that each one will say, must be same name as its location
['Spawn']={
{'info.website'},
{'info.read-readme'},
{'info.discord'},
{'info.softmod'},
{'info.redmew'},
{'info.custom-commands'},
{'info.status'},
{'info.lhd'},
{'info.github'},
{'info.patreon'},
}
}
}
messages = { --- @setting messages the messages that each one will say, must be same name as its location
["Spawn"] = {
{ "info.website" },
{ "info.read-readme" },
{ "info.discord" },
{ "info.softmod" },
{ "info.redmew" },
{ "info.custom-commands" },
{ "info.status" },
{ "info.lhd" },
{ "info.github" },
{ "info.patreon" },
},
},
}

View File

@@ -4,13 +4,13 @@
-- @config Death-Logger
return {
--WIP_allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death
--WIP_allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body
use_chests_as_bodies=false, --- @setting use_chests_as_bodies weather items should be moved into a chest when a player dies
auto_collect_bodies=true, --- @setting auto_collect_bodies enables items being returned to the spawn point in chests upon corpse expiring
show_map_markers=true, --- @setting show_map_markers shows markers on the map where bodies are
include_time_of_death=true, --- @setting include_time_of_death weather to include the time of death on the map marker
map_icon=nil, --- @setting map_icon the icon that the map marker shows; nil means no icon; format as a SingleID
show_light_at_corpse=true, --- @setting show_light_at_corpse if a light should be rendered at the corpse
show_line_to_corpse=true --- @setting show_line_to_corpse if a line should be rendered from you to your corpse
}
-- WIP_allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death
-- WIP_allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body
use_chests_as_bodies = false, --- @setting use_chests_as_bodies weather items should be moved into a chest when a player dies
auto_collect_bodies = true, --- @setting auto_collect_bodies enables items being returned to the spawn point in chests upon corpse expiring
show_map_markers = true, --- @setting show_map_markers shows markers on the map where bodies are
include_time_of_death = true, --- @setting include_time_of_death weather to include the time of death on the map marker
map_icon = nil, --- @setting map_icon the icon that the map marker shows; nil means no icon; format as a SingleID
show_light_at_corpse = true, --- @setting show_light_at_corpse if a light should be rendered at the corpse
show_line_to_corpse = true, --- @setting show_line_to_corpse if a line should be rendered from you to your corpse
}

View File

@@ -2,10 +2,10 @@
-- @config Deconlog
return {
decon_area = true, ---@setting decon_area whether to log when an area is being deconstructed
built_entity = true, ---@setting built_entity whether to log when an entity is built
mined_entity = true, ---@setting mined_entity whether to log when an entity is mined
fired_rocket = true, ---@setting fired_nuke whether to log when a rocket is fired
fired_explosive_rocket = true, ---@setting fired_nuke whether to log when a explosive rocket is fired
fired_nuke = true, ---@setting fired_nuke whether to log when a nuke is fired
decon_area = true, --- @setting decon_area whether to log when an area is being deconstructed
built_entity = true, --- @setting built_entity whether to log when an entity is built
mined_entity = true, --- @setting mined_entity whether to log when an entity is mined
fired_rocket = true, --- @setting fired_nuke whether to log when a rocket is fired
fired_explosive_rocket = true, --- @setting fired_nuke whether to log when a explosive rocket is fired
fired_nuke = true, --- @setting fired_nuke whether to log when a nuke is fired
}

View File

@@ -2,24 +2,24 @@
-- @config Discord-Alerts
return {
show_playtime=true,
entity_protection=true,
player_reports=true,
player_warnings=true,
player_bans=true,
player_mutes=true,
player_kicks=true,
player_promotes=false,
player_jail=true,
['config']=true,
['purge']=true,
['c']=true,
['command']=true,
['silent-command']=true,
['measured-command']=true,
['banlist']=true,
['permissions']=true,
['editor']=true,
['cheat']=true,
['open']=false
}
show_playtime = true,
entity_protection = true,
player_reports = true,
player_warnings = true,
player_bans = true,
player_mutes = true,
player_kicks = true,
player_promotes = false,
player_jail = true,
["config"] = true,
["purge"] = true,
["c"] = true,
["command"] = true,
["silent-command"] = true,
["measured-command"] = true,
["banlist"] = true,
["permissions"] = true,
["editor"] = true,
["cheat"] = true,
["open"] = false,
}

View File

@@ -11,9 +11,9 @@ Commands.add_authenticator(function(player, command, tags, reject)
if player.admin then
return true
else
return reject{'command-auth.admin-only'}
return reject{ "command-auth.admin-only" }
end
else
return true
end
end)
end)

View File

@@ -6,9 +6,9 @@ local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
-- luacheck:ignore 212/tags
Commands.add_authenticator(function(player, command, tags, reject)
if Roles.player_allowed(player,'command/'..command) then
if Roles.player_allowed(player, "command/" .. command) then
return true
else
return reject()
end
end)
end)

View File

@@ -4,12 +4,12 @@
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
local Colours = require("modules/exp_util/include/color")
Commands.add_parse('color',function(input, _, reject)
Commands.add_parse("color", function(input, _, reject)
if not input then return end
local color = Colours[input]
if not color then
return reject{'expcore-commands.reject-color'}
return reject{ "expcore-commands.reject-color" }
else
return input
end
end)
end)

View File

@@ -22,121 +22,121 @@ see ./expcore/commands.lua for more details
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
-- luacheck:ignore 212/player
Commands.add_parse('boolean',function(input, player)
Commands.add_parse("boolean", function(input, player)
if not input then return end -- nil check
input = input:lower()
if input == 'yes'
or input == 'y'
or input == 'true'
or input == '1' then
if input == "yes"
or input == "y"
or input == "true"
or input == "1" then
return true
else
return false
end
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
local option = _C.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)
Commands.add_parse('string-max-length',function(input, player, reject, max_length)
Commands.add_parse("string-max-length", function(input, player, reject, max_length)
if not input then return end -- nil check
local length = input:len()
if length > max_length then
return reject{'expcore-commands.reject-string-max-length',max_length}
return reject{ "expcore-commands.reject-string-max-length", max_length }
else
return input
end
end)
Commands.add_parse('number',function(input, player, reject)
Commands.add_parse("number", function(input, player, reject)
if not input then return end -- nil check
local number = tonumber(input)
if not number then
return reject{'expcore-commands.reject-number'}
return reject{ "expcore-commands.reject-number" }
else
return number
end
end)
Commands.add_parse('integer',function(input, player, reject)
Commands.add_parse("integer", function(input, player, reject)
if not input then return end -- nil check
local number = tonumber(input)
if not number then
return reject{'expcore-commands.reject-number'}
return reject{ "expcore-commands.reject-number" }
else
return math.floor(number)
end
end)
Commands.add_parse('number-range',function(input, player, reject, range_min, range_max)
local number = Commands.parse('number',input, player, reject)
Commands.add_parse("number-range", function(input, player, reject, range_min, range_max)
local number = Commands.parse("number", input, player, reject)
if not number then return end -- nil check
if number < range_min or number > range_max then
return reject{'expcore-commands.reject-number-range',range_min, range_max}
return reject{ "expcore-commands.reject-number-range", range_min, range_max }
else
return number
end
end)
Commands.add_parse('integer-range',function(input, player, reject, range_min, range_max)
local number = Commands.parse('integer',input, player, reject)
Commands.add_parse("integer-range", function(input, player, reject, range_min, range_max)
local number = Commands.parse("integer", input, player, reject)
if not number then return end -- nil check
if number < range_min or number > range_max then
return reject{'expcore-commands.reject-number-range',range_min, range_max}
return reject{ "expcore-commands.reject-number-range", range_min, range_max }
else
return number
end
end)
Commands.add_parse('player',function(input, player, reject)
Commands.add_parse("player", function(input, player, reject)
if not input then return end -- nil check
local input_player = game.players[input]
if not input_player then
return reject{'expcore-commands.reject-player',input}
return reject{ "expcore-commands.reject-player", input }
else
return input_player
end
end)
Commands.add_parse('player-online',function(input, player, reject)
local input_player = Commands.parse('player',input, player, reject)
Commands.add_parse("player-online", function(input, player, reject)
local input_player = Commands.parse("player", input, player, reject)
if not input_player then return end -- nil check
if not input_player.connected then
return reject{'expcore-commands.reject-player-online'}
return reject{ "expcore-commands.reject-player-online" }
else
return input_player
end
end)
Commands.add_parse('player-alive',function(input, player, reject)
local input_player = Commands.parse('player-online',input, player, reject)
Commands.add_parse("player-alive", function(input, player, reject)
local input_player = Commands.parse("player-online", input, player, reject)
if not input_player then return end -- nil check
if not input_player.character or not input_player.character.health or input_player.character.health <= 0 then
return reject{'expcore-commands.reject-player-alive'}
return reject{ "expcore-commands.reject-player-alive" }
else
return input_player
end
end)
Commands.add_parse('force',function(input, player, reject)
Commands.add_parse("force", function(input, player, reject)
if not input then return end -- nil check
local force = game.forces[input]
if not force then
return reject{'expcore-commands.reject-force'}
return reject{ "expcore-commands.reject-force" }
else
return force
end
end)
Commands.add_parse('surface',function(input, player, reject)
Commands.add_parse("surface", function(input, player, reject)
if not input then return end
local surface = game.surfaces[input]
if not surface then
return reject{'expcore-commands.reject-surface'}
return reject{ "expcore-commands.reject-surface" }
else
return surface
end
end)
end)

View File

@@ -13,42 +13,43 @@ local auto_complete = _C.auto_complete --- @dep expcore.common
require("modules.exp_legacy.config.expcore.command_general_parse")
-- luacheck:ignore 212/player
Commands.add_parse('role',function(input, player, reject)
Commands.add_parse("role", function(input, player, reject)
if not input then return end
local roles = Roles.config.order
local rev_roles = {}
for i=#roles, 1,-1 do
for i = #roles, 1, -1 do
table.insert(rev_roles, roles[i])
end
local role = auto_complete(rev_roles, input)
role = Roles.get_role_by_name(role)
if not role then
return reject{'expcore-role.reject-role'}
return reject{ "expcore-role.reject-role" }
else
return role
end
end)
Commands.add_parse('player-role',function(input, player, reject)
local input_player = Commands.parse('player',input, player, reject)
Commands.add_parse("player-role", function(input, player, reject)
local input_player = Commands.parse("player", input, player, reject)
if not input_player then return end -- nil check
local player_highest = Roles.get_player_highest_role(player)
local input_player_highest = Roles.get_player_highest_role(input_player)
if player_highest.index < input_player_highest.index then
return input_player
else
return reject{'expcore-roles.reject-player-role'}
return reject{ "expcore-roles.reject-player-role" }
end
end)
Commands.add_parse('player-role-online',function(input, player, reject)
local input_player = Commands.parse('player-role',input, player, reject)
Commands.add_parse("player-role-online", function(input, player, reject)
local input_player = Commands.parse("player-role", input, player, reject)
if not input_player then return end -- nil check
return Commands.parse('player-online',input_player.name, player, reject)
return Commands.parse("player-online", input_player.name, player, reject)
end)
Commands.add_parse('player-role-alive',function(input, player, reject)
local input_player = Commands.parse('player-role',input, player, reject)
Commands.add_parse("player-role-alive", function(input, player, reject)
local input_player = Commands.parse("player-role", input, player, reject)
if not input_player then return end -- nil check
return Commands.parse('player-alive',input_player.name, player, reject)
end)
return Commands.parse("player-alive", input_player.name, player, reject)
end)

View File

@@ -25,8 +25,8 @@ end
-- luacheck:ignore 212/player 212/tags
Commands.add_authenticator(function(player, command, tags, reject)
if disabled_commands[command] then
return reject{'command-auth.command-disabled'}
return reject{ "command-auth.command-disabled" }
else
return true
end
end)
end)

View File

@@ -4,102 +4,102 @@
-- then use :allow{} and :disallow{} to specify certain actions to allow/disallow
-- @config Permission-Groups
--local Event = require("modules/exp_legacy/utils/event") -- @dep utils.event
-- local Event = require("modules/exp_legacy/utils/event") -- @dep utils.event
local Permission_Groups = require("modules.exp_legacy.expcore.permission_groups") --- @dep expcore.permission_groups
Permission_Groups.new_group('Admin')
:allow_all()
:disallow{
'add_permission_group', -- admin
'delete_permission_group',
'edit_permission_group',
'import_permissions_string',
'map_editor_action',
'toggle_map_editor',
'change_multiplayer_config',
'set_heat_interface_mode',
'set_heat_interface_temperature',
'set_infinity_container_filter_item',
'set_infinity_container_remove_unfiltered_items',
'set_infinity_pipe_filter'
}
Permission_Groups.new_group("Admin")
:allow_all()
:disallow{
"add_permission_group", -- admin
"delete_permission_group",
"edit_permission_group",
"import_permissions_string",
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
}
Permission_Groups.new_group('Trusted')
:allow_all()
:disallow{
'add_permission_group', -- admin
'delete_permission_group',
'edit_permission_group',
'import_permissions_string',
'map_editor_action',
'toggle_map_editor',
'change_multiplayer_config',
'set_heat_interface_mode',
'set_heat_interface_temperature',
'set_infinity_container_filter_item',
'set_infinity_container_remove_unfiltered_items',
'set_infinity_pipe_filter',
'admin_action' -- trusted
}
Permission_Groups.new_group("Trusted")
:allow_all()
:disallow{
"add_permission_group", -- admin
"delete_permission_group",
"edit_permission_group",
"import_permissions_string",
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
}
Permission_Groups.new_group('Standard')
:allow_all()
:disallow{
'add_permission_group', -- admin
'delete_permission_group',
'edit_permission_group',
'import_permissions_string',
'map_editor_action',
'toggle_map_editor',
'change_multiplayer_config',
'set_heat_interface_mode',
'set_heat_interface_temperature',
'set_infinity_container_filter_item',
'set_infinity_container_remove_unfiltered_items',
'set_infinity_pipe_filter',
'admin_action', -- trusted
'change_programmable_speaker_alert_parameters', -- standard
'drop_item',
'change_rocket_silo_mode'
}
Permission_Groups.new_group("Standard")
:allow_all()
:disallow{
"add_permission_group", -- admin
"delete_permission_group",
"edit_permission_group",
"import_permissions_string",
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
"change_programmable_speaker_alert_parameters", -- standard
"drop_item",
"change_rocket_silo_mode",
}
Permission_Groups.new_group('Guest')
:allow_all()
:disallow{
'add_permission_group', -- admin
'delete_permission_group',
'edit_permission_group',
'import_permissions_string',
'map_editor_action',
'toggle_map_editor',
'change_multiplayer_config',
'set_heat_interface_mode',
'set_heat_interface_temperature',
'set_infinity_container_filter_item',
'set_infinity_container_remove_unfiltered_items',
'set_infinity_pipe_filter',
'admin_action', -- trusted
'change_programmable_speaker_alert_parameters', -- standard
'drop_item',
'change_rocket_silo_mode',
'change_programmable_speaker_parameters', -- guest
'change_train_stop_station',
--'deconstruct',
'remove_cables',
'remove_train_station',
'reset_assembling_machine',
'rotate_entity',
--'use_artillery_remote', -- not in 2.0
'launch_rocket',
'cancel_research',
--'activate_cut', -- not in 2.0
'flush_opened_entity_fluid',
'flush_opened_entity_specific_fluid'
}
Permission_Groups.new_group("Guest")
:allow_all()
:disallow{
"add_permission_group", -- admin
"delete_permission_group",
"edit_permission_group",
"import_permissions_string",
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
"change_programmable_speaker_alert_parameters", -- standard
"drop_item",
"change_rocket_silo_mode",
"change_programmable_speaker_parameters", -- guest
"change_train_stop_station",
-- 'deconstruct',
"remove_cables",
"remove_train_station",
"reset_assembling_machine",
"rotate_entity",
-- 'use_artillery_remote', -- not in 2.0
"launch_rocket",
"cancel_research",
-- 'activate_cut', -- not in 2.0
"flush_opened_entity_fluid",
"flush_opened_entity_specific_fluid",
}
Permission_Groups.new_group('Restricted')
:disallow_all()
:allow('write_to_console')
Permission_Groups.new_group("Restricted")
:disallow_all()
:allow("write_to_console")
--[[ These events are used until a role system is added to make it easier for our admins

View File

@@ -6,362 +6,362 @@ local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep ex
local Statistics = PlayerData.Statistics
--- Role flags that will run when a player changes roles
Roles.define_flag_trigger('is_admin',function(player,state)
Roles.define_flag_trigger("is_admin", function(player, state)
player.admin = state
end)
Roles.define_flag_trigger('is_spectator',function(player,state)
Roles.define_flag_trigger("is_spectator", function(player, state)
player.spectator = state
end)
Roles.define_flag_trigger('is_jail',function(player,state)
Roles.define_flag_trigger("is_jail", function(player, state)
if player.character then
player.character.active = not state
end
end)
--- Admin Roles
Roles.new_role('System','SYS')
:set_permission_group('Default', true)
:set_flag('is_admin')
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_allow_all()
Roles.new_role("System", "SYS")
:set_permission_group("Default", true)
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_allow_all()
Roles.new_role('Senior Administrator','SAdmin')
:set_permission_group('Admin')
:set_custom_color{r=233,g=63,b=233}
:set_flag('is_admin')
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Administrator')
:allow{
'command/interface',
'command/debug',
'command/toggle-cheat-mode',
'command/research-all'
}
Roles.new_role("Senior Administrator", "SAdmin")
:set_permission_group("Admin")
:set_custom_color{ r = 233, g = 63, b = 233 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Administrator")
:allow{
"command/interface",
"command/debug",
"command/toggle-cheat-mode",
"command/research-all",
}
Roles.new_role('Administrator','Admin')
:set_permission_group('Admin')
:set_custom_color{r=233,g=63,b=233}
:set_flag('is_admin')
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Moderator')
:allow{
'gui/warp-list/bypass-proximity',
'gui/warp-list/bypass-cooldown',
'command/connect-all',
'command/collectdata'
}
Roles.new_role("Administrator", "Admin")
:set_permission_group("Admin")
:set_custom_color{ r = 233, g = 63, b = 233 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Moderator")
:allow{
"gui/warp-list/bypass-proximity",
"gui/warp-list/bypass-cooldown",
"command/connect-all",
"command/collectdata",
}
Roles.new_role('Moderator','Mod')
:set_permission_group('Admin')
:set_custom_color{r=0,g=170,b=0}
:set_flag('is_admin')
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Trainee')
:allow{
'command/assign-role',
'command/unassign-role',
'command/repair',
'command/kill/always',
'command/clear-tag/always',
'command/go-to-spawn/always',
'command/clear-reports',
'command/clear-warnings',
'command/clear-inventory',
-- 'command/bonus',
'gui/bonus',
'command/home',
'command/home-set',
'command/home-get',
'command/return',
'command/connect-player',
'gui/rocket-info/toggle-active',
'gui/rocket-info/remote_launch',
'command/toggle-friendly-fire',
'command/toggle-always-day',
'fast-tree-decon'
}
Roles.new_role("Moderator", "Mod")
:set_permission_group("Admin")
:set_custom_color{ r = 0, g = 170, b = 0 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Trainee")
:allow{
"command/assign-role",
"command/unassign-role",
"command/repair",
"command/kill/always",
"command/clear-tag/always",
"command/go-to-spawn/always",
"command/clear-reports",
"command/clear-warnings",
"command/clear-inventory",
-- 'command/bonus',
"gui/bonus",
"command/home",
"command/home-set",
"command/home-get",
"command/return",
"command/connect-player",
"gui/rocket-info/toggle-active",
"gui/rocket-info/remote_launch",
"command/toggle-friendly-fire",
"command/toggle-always-day",
"fast-tree-decon",
}
Roles.new_role('Trainee','TrMod')
:set_permission_group('Admin')
:set_custom_color{r=0,g=170,b=0}
:set_flag('is_admin')
:set_flag('is_spectator')
:set_flag('report-immune')
:set_parent('Veteran')
:allow{
'command/admin-chat',
'command/admin-marker',
'command/goto',
'command/teleport',
'command/bring',
'command/give-warning',
'command/get-warnings',
'command/get-reports',
'command/protect-entity',
'command/protect-area',
'command/jail',
'command/unjail',
'command/kick',
'command/ban',
'command/spectate',
'command/follow',
'command/search',
'command/search-amount',
'command/search-recent',
'command/search-online',
'command/personal-battery-recharge',
'command/pollution-off',
'command/pollution-clear',
'command/bot-queue-get',
'command/bot-queue-set',
'command/game-speed',
'command/kill-biters',
'command/remove-biters',
'gui/playerdata'
}
Roles.new_role("Trainee", "TrMod")
:set_permission_group("Admin")
:set_custom_color{ r = 0, g = 170, b = 0 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_parent("Veteran")
:allow{
"command/admin-chat",
"command/admin-marker",
"command/goto",
"command/teleport",
"command/bring",
"command/give-warning",
"command/get-warnings",
"command/get-reports",
"command/protect-entity",
"command/protect-area",
"command/jail",
"command/unjail",
"command/kick",
"command/ban",
"command/spectate",
"command/follow",
"command/search",
"command/search-amount",
"command/search-recent",
"command/search-online",
"command/personal-battery-recharge",
"command/pollution-off",
"command/pollution-clear",
"command/bot-queue-get",
"command/bot-queue-set",
"command/game-speed",
"command/kill-biters",
"command/remove-biters",
"gui/playerdata",
}
--- Trusted Roles
Roles.new_role('Board Member','Board')
:set_permission_group('Trusted')
:set_custom_color{r=247,g=246,b=54}
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Sponsor')
:allow{
'command/goto',
'command/repair',
'command/spectate',
'command/follow',
'gui/playerdata'
}
Roles.new_role("Board Member", "Board")
:set_permission_group("Trusted")
:set_custom_color{ r = 247, g = 246, b = 54 }
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Sponsor")
:allow{
"command/goto",
"command/repair",
"command/spectate",
"command/follow",
"gui/playerdata",
}
Roles.new_role('Senior Backer','Backer')
:set_permission_group('Trusted')
:set_custom_color{r=238,g=172,b=44}
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Sponsor')
:allow{
}
Roles.new_role("Senior Backer", "Backer")
:set_permission_group("Trusted")
:set_custom_color{ r = 238, g = 172, b = 44 }
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Sponsor")
:allow{
}
Roles.new_role('Sponsor','Spon')
:set_permission_group('Trusted')
:set_custom_color{r=238,g=172,b=44}
:set_flag('is_spectator')
:set_flag('report-immune')
:set_flag('instant-respawn')
:set_parent('Supporter')
:allow{
'gui/rocket-info/toggle-active',
'gui/rocket-info/remote_launch',
-- 'command/bonus',
'gui/bonus',
'command/home',
'command/home-set',
'command/home-get',
'command/return',
'fast-tree-decon'
}
Roles.new_role("Sponsor", "Spon")
:set_permission_group("Trusted")
:set_custom_color{ r = 238, g = 172, b = 44 }
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Supporter")
:allow{
"gui/rocket-info/toggle-active",
"gui/rocket-info/remote_launch",
-- 'command/bonus',
"gui/bonus",
"command/home",
"command/home-set",
"command/home-get",
"command/return",
"fast-tree-decon",
}
Roles.new_role('Supporter','Sup')
:set_permission_group('Trusted')
:set_custom_color{r=230,g=99,b=34}
:set_flag('is_spectator')
:set_parent('Veteran')
:allow{
'command/tag-color',
'command/jail',
'command/unjail',
'command/join-message',
'command/join-message-clear'
}
Roles.new_role("Supporter", "Sup")
:set_permission_group("Trusted")
:set_custom_color{ r = 230, g = 99, b = 34 }
:set_flag("is_spectator")
:set_parent("Veteran")
:allow{
"command/tag-color",
"command/jail",
"command/unjail",
"command/join-message",
"command/join-message-clear",
}
Roles.new_role('Partner','Part')
:set_permission_group('Trusted')
:set_custom_color{r=140,g=120,b=200}
:set_flag('is_spectator')
:set_parent('Veteran')
:allow{
'command/jail',
'command/unjail'
}
Roles.new_role("Partner", "Part")
:set_permission_group("Trusted")
:set_custom_color{ r = 140, g = 120, b = 200 }
:set_flag("is_spectator")
:set_parent("Veteran")
:allow{
"command/jail",
"command/unjail",
}
local hours10, hours250 = 10*216000, 250*60
Roles.new_role('Veteran','Vet')
:set_permission_group('Trusted')
:set_custom_color{r=140,g=120,b=200}
:set_parent('Member')
:allow{
'command/chat-bot',
'command/last-location'
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours10 then
return true
else
local stats = Statistics:get(player, {})
local playTime, afkTime, mapCount = stats.Playtime or 0, stats.AfkTime or 0, stats.MapsPlayed or 0
return playTime - afkTime >= hours250 and mapCount >= 25
end
end)
local hours10, hours250 = 10 * 216000, 250 * 60
Roles.new_role("Veteran", "Vet")
:set_permission_group("Trusted")
:set_custom_color{ r = 140, g = 120, b = 200 }
:set_parent("Member")
:allow{
"command/chat-bot",
"command/last-location",
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours10 then
return true
else
local stats = Statistics:get(player, {})
local playTime, afkTime, mapCount = stats.Playtime or 0, stats.AfkTime or 0, stats.MapsPlayed or 0
return playTime - afkTime >= hours250 and mapCount >= 25
end
end)
--- Standard User Roles
Roles.new_role('Member','Mem')
:set_permission_group('Standard')
:set_custom_color{r=24,g=172,b=188}
:set_flag('deconlog-bypass')
:set_parent('Regular')
:allow{
'gui/task-list/add',
'gui/task-list/edit',
'gui/warp-list/add',
'gui/warp-list/edit',
'command/save-quickbar',
'gui/vlayer-edit',
'command/vlayer-info',
'command/personal-logistic',
'command/auto-research',
'command/set-trains-to-automatic',
'command/lawnmower',
'command/waterfill',
'command/artillery-target-remote',
'command/clear-item-on-ground',
'command/clear-blueprint',
'gui/surveillance'
}
Roles.new_role("Member", "Mem")
:set_permission_group("Standard")
:set_custom_color{ r = 24, g = 172, b = 188 }
:set_flag("deconlog-bypass")
:set_parent("Regular")
:allow{
"gui/task-list/add",
"gui/task-list/edit",
"gui/warp-list/add",
"gui/warp-list/edit",
"command/save-quickbar",
"gui/vlayer-edit",
"command/vlayer-info",
"command/personal-logistic",
"command/auto-research",
"command/set-trains-to-automatic",
"command/lawnmower",
"command/waterfill",
"command/artillery-target-remote",
"command/clear-item-on-ground",
"command/clear-blueprint",
"gui/surveillance",
}
local hours3, hours15 = 3*216000, 15*60
Roles.new_role('Regular','Reg')
:set_permission_group('Standard')
:set_custom_color{r=79,g=155,b=163}
:set_parent('Guest')
:allow{
'command/kill',
'command/rainbow',
'command/go-to-spawn',
'command/me',
'standard-decon',
'bypass-entity-protection',
'bypass-nukeprotect'
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours3 then
return true
else
local stats = Statistics:get(player, {})
local playTime, afkTime, mapCount = stats.Playtime or 0, stats.AfkTime or 0, stats.MapsPlayed or 0
return playTime - afkTime >= hours15 and mapCount >= 5
end
end)
local hours3, hours15 = 3 * 216000, 15 * 60
Roles.new_role("Regular", "Reg")
:set_permission_group("Standard")
:set_custom_color{ r = 79, g = 155, b = 163 }
:set_parent("Guest")
:allow{
"command/kill",
"command/rainbow",
"command/go-to-spawn",
"command/me",
"standard-decon",
"bypass-entity-protection",
"bypass-nukeprotect",
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours3 then
return true
else
local stats = Statistics:get(player, {})
local playTime, afkTime, mapCount = stats.Playtime or 0, stats.AfkTime or 0, stats.MapsPlayed or 0
return playTime - afkTime >= hours15 and mapCount >= 5
end
end)
--- Guest/Default role
local default = Roles.new_role('Guest','')
:set_permission_group('Guest')
:set_custom_color{r=185,g=187,b=160}
:allow{
'command/tag',
'command/tag-clear',
'command/search-help',
'command/list-roles',
'command/find-on-map',
'command/report',
'command/ratio',
'command/server-ups',
'command/save-data',
'command/preference',
'command/set-preference',
'command/connect',
'gui/player-list',
'gui/rocket-info',
'gui/science-info',
'gui/task-list',
'gui/warp-list',
'gui/readme',
'gui/vlayer',
'gui/research',
'gui/autofill',
'gui/module',
'gui/landfill',
'gui/production'
}
local default = Roles.new_role("Guest", "")
:set_permission_group("Guest")
:set_custom_color{ r = 185, g = 187, b = 160 }
:allow{
"command/tag",
"command/tag-clear",
"command/search-help",
"command/list-roles",
"command/find-on-map",
"command/report",
"command/ratio",
"command/server-ups",
"command/save-data",
"command/preference",
"command/set-preference",
"command/connect",
"gui/player-list",
"gui/rocket-info",
"gui/science-info",
"gui/task-list",
"gui/warp-list",
"gui/readme",
"gui/vlayer",
"gui/research",
"gui/autofill",
"gui/module",
"gui/landfill",
"gui/production",
}
--- Jail role
Roles.new_role('Jail')
:set_permission_group('Restricted')
:set_custom_color{r=50,g=50,b=50}
:set_block_auto_assign(true)
:set_flag('defer_role_changes')
:disallow(default.allowed)
Roles.new_role("Jail")
:set_permission_group("Restricted")
:set_custom_color{ r = 50, g = 50, b = 50 }
:set_block_auto_assign(true)
:set_flag("defer_role_changes")
:disallow(default.allowed)
--- System defaults which are required to be set
Roles.set_root('System')
Roles.set_default('Guest')
Roles.set_root("System")
Roles.set_default("Guest")
Roles.define_role_order{
'System', -- Best to keep root at top
'Senior Administrator',
'Administrator',
'Moderator',
'Trainee',
'Board Member',
'Senior Backer',
'Sponsor',
'Supporter',
'Partner',
'Veteran',
'Member',
'Regular',
'Jail',
'Guest' -- Default must be last if you want to apply restrictions to other roles
"System", -- Best to keep root at top
"Senior Administrator",
"Administrator",
"Moderator",
"Trainee",
"Board Member",
"Senior Backer",
"Sponsor",
"Supporter",
"Partner",
"Veteran",
"Member",
"Regular",
"Jail",
"Guest", -- Default must be last if you want to apply restrictions to other roles
}
Roles.override_player_roles{
['PHIDIAS0303']={'Moderator', 'Board Member', 'Member'},
['aldldl']={'Administrator', 'Moderator','Member'},
['arty714']={'Senior Administrator', 'Moderator', 'Member'},
['Cooldude2606']={'Senior Administrator', 'Moderator', 'Member'},
['Drahc_pro']={'Administrator', 'Moderator', 'Member'},
['mark9064']={'Administrator', 'Moderator','Member'},
['7h3w1z4rd']={'Moderator','Member'},
['FlipHalfling90']={'Moderator','Member'},
['hamsterbryan']={'Moderator','Member'},
['HunterOfGames']={'Moderator','Member'},
['NextIdea']={'Moderator','Member'},
['TheKernel32']={'Moderator','Member'},
['TheKernel64']={'Moderator','Member'},
['tovernaar123']={'Moderator','Member'},
['UUBlueFire']={'Moderator','Member'},
['AssemblyStorm']={'Moderator', 'Member'},
['banakeg']={'Moderator','Member'},
['connormkii']={'Moderator', 'Member'},
['cydes']={'Moderator','Member'},
['darklich14']={'Moderator','Member'},
['facere']={'Moderator','Member'},
['freek18']={'Moderator','Member'},
['Gizan']={'Moderator','Member'},
['LoicB']={'Moderator','Member'},
['M74132']={'Moderator','Member'},
['mafisch3']={'Moderator','Member'},
['maplesyrup01']={'Moderator','Member'},
['ookl']={'Moderator','Member'},
['Phoenix27833']={'Moderator','Member'},
['porelos']={'Moderator','Member'},
['Ruuyji']={'Moderator','Member'},
['samy115']={'Moderator','Member'},
['SilentLog']={'Moderator','Member'},
['Tcheko']={'Moderator','Member'},
['thadius856']={'Moderator','Member'},
['whoami32']={'Moderator','Member'},
['Windbomb']={'Moderator','Member'},
['XenoCyber']={'Moderator','Member'}
["PHIDIAS0303"] = { "Moderator", "Board Member", "Member" },
["aldldl"] = { "Administrator", "Moderator", "Member" },
["arty714"] = { "Senior Administrator", "Moderator", "Member" },
["Cooldude2606"] = { "Senior Administrator", "Moderator", "Member" },
["Drahc_pro"] = { "Administrator", "Moderator", "Member" },
["mark9064"] = { "Administrator", "Moderator", "Member" },
["7h3w1z4rd"] = { "Moderator", "Member" },
["FlipHalfling90"] = { "Moderator", "Member" },
["hamsterbryan"] = { "Moderator", "Member" },
["HunterOfGames"] = { "Moderator", "Member" },
["NextIdea"] = { "Moderator", "Member" },
["TheKernel32"] = { "Moderator", "Member" },
["TheKernel64"] = { "Moderator", "Member" },
["tovernaar123"] = { "Moderator", "Member" },
["UUBlueFire"] = { "Moderator", "Member" },
["AssemblyStorm"] = { "Moderator", "Member" },
["banakeg"] = { "Moderator", "Member" },
["connormkii"] = { "Moderator", "Member" },
["cydes"] = { "Moderator", "Member" },
["darklich14"] = { "Moderator", "Member" },
["facere"] = { "Moderator", "Member" },
["freek18"] = { "Moderator", "Member" },
["Gizan"] = { "Moderator", "Member" },
["LoicB"] = { "Moderator", "Member" },
["M74132"] = { "Moderator", "Member" },
["mafisch3"] = { "Moderator", "Member" },
["maplesyrup01"] = { "Moderator", "Member" },
["ookl"] = { "Moderator", "Member" },
["Phoenix27833"] = { "Moderator", "Member" },
["porelos"] = { "Moderator", "Member" },
["Ruuyji"] = { "Moderator", "Member" },
["samy115"] = { "Moderator", "Member" },
["SilentLog"] = { "Moderator", "Member" },
["Tcheko"] = { "Moderator", "Member" },
["thadius856"] = { "Moderator", "Member" },
["whoami32"] = { "Moderator", "Member" },
["Windbomb"] = { "Moderator", "Member" },
["XenoCyber"] = { "Moderator", "Member" },
}

View File

@@ -1,7 +1,7 @@
return {
modules = {
["forcestats"] = true,
["logistorage"] = false,
["other"] = true,
}
modules = {
["forcestats"] = true,
["logistorage"] = false,
["other"] = true,
},
}

View File

@@ -4,109 +4,110 @@
local table = require("modules.exp_legacy.overrides.table") -- @dep overrides.table
local config = {
-- General config
icon = 'item/piercing-rounds-magazine', -- @setting icon that will be used for the toolbar
categories = {
ammo = 'ammo',
fuel = 'fuel',
shell = 'shell'
},
entities = {
car = 'car',
tank = 'tank',
spidertron = 'spidertron',
locomotive = 'locomotive',
gun_turret = 'gun-turret',
burner_mining_drill = 'burner-mining-drill',
stone_furnace = 'stone-furnace',
steel_furnace = 'steel-furnace'
},
default_entities = {}
-- General config
icon = "item/piercing-rounds-magazine", -- @setting icon that will be used for the toolbar
categories = {
ammo = "ammo",
fuel = "fuel",
shell = "shell",
},
entities = {
car = "car",
tank = "tank",
spidertron = "spidertron",
locomotive = "locomotive",
gun_turret = "gun-turret",
burner_mining_drill = "burner-mining-drill",
stone_furnace = "stone-furnace",
steel_furnace = "steel-furnace",
},
default_entities = {},
}
local default_categories = {
{
category = config.categories.ammo,
entity = {config.entities.car, config.entities.tank, config.entities.gun_turret},
inv = {defines.inventory.car_ammo, defines.inventory.turret_ammo},
items = {
{ name = 'uranium-rounds-magazine', amount = 10, enabled = false },
{ name = 'piercing-rounds-magazine', amount = 10, enabled = false },
{ name = 'firearm-magazine', amount = 10, enabled = false },
}
},
{
category = config.categories.ammo,
entity = {config.entities.tank},
inv = {defines.inventory.car_ammo},
items = {
{ name = 'flamethrower-ammo', amount = 10, enabled = false },
}
},
{
category = config.categories.shell,
entity = {config.entities.tank},
inv = {defines.inventory.car_ammo},
items = {
{ name = 'cannon-shell', amount = 10, enabled = false },
{ name = 'explosive-cannon-shell', amount = 10, enabled = false },
{ name = 'uranium-cannon-shell', amount = 10, enabled = false },
{ name = 'explosive-uranium-cannon-shell', amount = 10, enabled = false },
}
},
{
category = config.categories.ammo,
entity = {config.entities.spidertron},
inv = {defines.inventory.car_ammo},
items = {
{ name = 'rocket', amount = 10, enabled = false },
{ name = 'explosive-rocket', amount = 10, enabled = false },
{ name = 'atomic-bomb', amount = 10, enabled = false },
}
},
{
category = config.categories.fuel,
entity = {config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.burner_mining_drill, config.entities.stone_furnace, config.entities.steel_furnace},
inv = {defines.inventory.fuel},
items = {
{ name = 'nuclear-fuel', amount = 10, enabled = false },
{ name = 'rocket-fuel', amount = 10, enabled = false },
{ name = 'solid-fuel', amount = 10, enabled = false },
{ name = 'coal', amount = 10, enabled = false },
}
}
{
category = config.categories.ammo,
entity = { config.entities.car, config.entities.tank, config.entities.gun_turret },
inv = { defines.inventory.car_ammo, defines.inventory.turret_ammo },
items = {
{ name = "uranium-rounds-magazine", amount = 10, enabled = false },
{ name = "piercing-rounds-magazine", amount = 10, enabled = false },
{ name = "firearm-magazine", amount = 10, enabled = false },
},
},
{
category = config.categories.ammo,
entity = { config.entities.tank },
inv = { defines.inventory.car_ammo },
items = {
{ name = "flamethrower-ammo", amount = 10, enabled = false },
},
},
{
category = config.categories.shell,
entity = { config.entities.tank },
inv = { defines.inventory.car_ammo },
items = {
{ name = "cannon-shell", amount = 10, enabled = false },
{ name = "explosive-cannon-shell", amount = 10, enabled = false },
{ name = "uranium-cannon-shell", amount = 10, enabled = false },
{ name = "explosive-uranium-cannon-shell", amount = 10, enabled = false },
},
},
{
category = config.categories.ammo,
entity = { config.entities.spidertron },
inv = { defines.inventory.car_ammo },
items = {
{ name = "rocket", amount = 10, enabled = false },
{ name = "explosive-rocket", amount = 10, enabled = false },
{ name = "atomic-bomb", amount = 10, enabled = false },
},
},
{
category = config.categories.fuel,
entity = { config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.burner_mining_drill, config.entities.stone_furnace, config.entities.steel_furnace },
inv = { defines.inventory.fuel },
items = {
{ name = "nuclear-fuel", amount = 10, enabled = false },
{ name = "rocket-fuel", amount = 10, enabled = false },
{ name = "solid-fuel", amount = 10, enabled = false },
{ name = "coal", amount = 10, enabled = false },
},
},
}
local function get_items_by_inv(entity, inv)
local items = entity.items
for _, category in pairs(default_categories) do
if table.contains(category.entity, entity.entity) then
if table.contains(category.inv, inv) then
for _, item in pairs(category.items) do
items[item.name] = {
entity = entity.entity,
category = category.category,
inv = inv,
name = item.name,
amount = item.amount,
enabled = item.enabled
}
end
end
end
end
return items
local items = entity.items
for _, category in pairs(default_categories) do
if table.contains(category.entity, entity.entity) then
if table.contains(category.inv, inv) then
for _, item in pairs(category.items) do
items[item.name] = {
entity = entity.entity,
category = category.category,
inv = inv,
name = item.name,
amount = item.amount,
enabled = item.enabled,
}
end
end
end
end
return items
end
local function generate_default_setting(entity_name, inv, enabled)
if not config.default_entities[entity_name] then
config.default_entities[entity_name] = {
entity = entity_name,
enabled = enabled,
items = {}
}
end
get_items_by_inv(config.default_entities[entity_name], inv)
if not config.default_entities[entity_name] then
config.default_entities[entity_name] = {
entity = entity_name,
enabled = enabled,
items = {},
}
end
get_items_by_inv(config.default_entities[entity_name], inv)
end
generate_default_setting(config.entities.car, defines.inventory.fuel, true)
@@ -127,4 +128,4 @@ generate_default_setting(config.entities.stone_furnace, defines.inventory.fuel,
generate_default_setting(config.entities.steel_furnace, defines.inventory.fuel, true)
return config
return config

View File

@@ -19,7 +19,7 @@ local function set_datastores(player, action)
end
-- auth that will only allow when on player's of lower roles
local function auth_lower_role(player,selected_player_name)
local function auth_lower_role(player, selected_player_name)
local player_highest = Roles.get_player_highest_role(player)
local action_player_highest = Roles.get_player_highest_role(selected_player_name)
if player_highest.index < action_player_highest.index then
@@ -36,170 +36,170 @@ local function get_action_player_name(player)
end
-- teleports one player to another
local function teleport(from_player,to_player)
local function teleport(from_player, to_player)
local surface = to_player.surface
local position = surface.find_non_colliding_position('character',to_player.position,32,1)
local position = surface.find_non_colliding_position("character", to_player.position, 32, 1)
if not position then return false end -- return false if no new position
if from_player.driving then from_player.driving = false end -- kicks a player out a vehicle if in one
from_player.teleport(position,surface)
from_player.teleport(position, surface)
return true
end
local function new_button(sprite,tooltip)
local function new_button(sprite, tooltip)
return Gui.element{
type = 'sprite-button',
style = 'tool_button',
type = "sprite-button",
style = "tool_button",
sprite = sprite,
tooltip = tooltip
tooltip = tooltip,
}:style{
padding = -1,
height = 28,
width = 28
width = 28,
}
end
--- Teleports the user to the action player
-- @element goto_player
local goto_player = new_button('utility/export',{'player-list.goto-player'})
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
local selected_player = game.players[selected_player_name]
if not player.character or not selected_player.character then
player.print({'expcore-commands.reject-player-alive'},Colors.orange_red)
else
teleport(player,selected_player)
end
end)
local goto_player = new_button("utility/export", { "player-list.goto-player" })
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
local selected_player = game.players[selected_player_name]
if not player.character or not selected_player.character then
player.print({ "expcore-commands.reject-player-alive" }, Colors.orange_red)
else
teleport(player, selected_player)
end
end)
--- Teleports the action player to the user
-- @element bring_player
local bring_player = new_button('utility/import',{'player-list.bring-player'})
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
local selected_player = game.players[selected_player_name]
if not player.character or not selected_player.character then
player.print({'expcore-commands.reject-player-alive'},Colors.orange_red)
else
teleport(selected_player,player)
end
end)
local bring_player = new_button("utility/import", { "player-list.bring-player" })
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
local selected_player = game.players[selected_player_name]
if not player.character or not selected_player.character then
player.print({ "expcore-commands.reject-player-alive" }, Colors.orange_red)
else
teleport(selected_player, player)
end
end)
--- Reports the action player, requires a reason to be given
-- @element report_player
local report_player = new_button('utility/spawn_flag',{'player-list.report-player'})
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
if Reports.is_reported(selected_player_name,player.name) then
player.print({'expcom-report.already-reported'},Colors.orange_red)
else
SelectedAction:set(player, 'command/report')
end
end)
local report_player = new_button("utility/spawn_flag", { "player-list.report-player" })
:on_click(function(player)
local selected_player_name = get_action_player_name(player)
if Reports.is_reported(selected_player_name, player.name) then
player.print({ "expcom-report.already-reported" }, Colors.orange_red)
else
SelectedAction:set(player, "command/report")
end
end)
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 by_player_name_color = format_chat_player_name(player)
game.print{'expcom-report.non-admin', selected_player_color,reason}
Roles.print_to_roles_higher('Trainee',{'expcom-report.admin', selected_player_color,by_player_name_color,reason})
Reports.report_player(selected_player_name,player.name,reason)
game.print{ "expcom-report.non-admin", selected_player_color, reason }
Roles.print_to_roles_higher("Trainee", { "expcom-report.admin", selected_player_color, by_player_name_color, reason })
Reports.report_player(selected_player_name, player.name, reason)
end
--- Gives the action player a warning, requires a reason
-- @element warn_player
local warn_player = new_button('utility/spawn_flag',{'player-list.warn-player'})
:on_click(function(player)
SelectedAction:set(player, 'command/give-warning')
end)
local warn_player = new_button("utility/spawn_flag", { "player-list.warn-player" })
:on_click(function(player)
SelectedAction:set(player, "command/give-warning")
end)
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 by_player_name_color = format_chat_player_name(player)
game.print{'expcom-warnings.received', selected_player_color,by_player_name_color,reason}
Warnings.add_warning(selected_player_name,player.name,reason)
game.print{ "expcom-warnings.received", selected_player_color, by_player_name_color, reason }
Warnings.add_warning(selected_player_name, player.name, reason)
end
--- Jails the action player, requires a reason
-- @element jail_player
local jail_player = new_button('utility/multiplayer_waiting_icon',{'player-list.jail-player'})
:on_click(function(player)
local selected_player_name, selected_player_color = get_action_player_name(player)
if Jail.is_jailed(selected_player_name) then
player.print({'expcom-jail.already-jailed', selected_player_color},Colors.orange_red)
else
SelectedAction:set(player, 'command/jail')
end
end)
local jail_player = new_button("utility/multiplayer_waiting_icon", { "player-list.jail-player" })
:on_click(function(player)
local selected_player_name, selected_player_color = get_action_player_name(player)
if Jail.is_jailed(selected_player_name) then
player.print({ "expcom-jail.already-jailed", selected_player_color }, Colors.orange_red)
else
SelectedAction:set(player, "command/jail")
end
end)
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 by_player_name_color = format_chat_player_name(player)
game.print{'expcom-jail.give', selected_player_color,by_player_name_color,reason}
Jail.jail_player(selected_player_name,player.name,reason)
game.print{ "expcom-jail.give", selected_player_color, by_player_name_color, reason }
Jail.jail_player(selected_player_name, player.name, reason)
end
--- Kicks the action player, requires a reason
-- @element kick_player
local kick_player = new_button('utility/warning_icon',{'player-list.kick-player'})
:on_click(function(player)
SelectedAction:set(player, 'command/kick')
end)
local kick_player = new_button("utility/warning_icon", { "player-list.kick-player" })
:on_click(function(player)
SelectedAction:set(player, "command/kick")
end)
local function kick_player_callback(player,reason)
local function kick_player_callback(player, reason)
local selected_player = get_action_player_name(player)
game.kick_player(selected_player,reason)
game.kick_player(selected_player, reason)
end
--- Bans the action player, requires a reason
-- @element ban_player
local ban_player = new_button('utility/danger_icon',{'player-list.ban-player'})
:on_click(function(player)
SelectedAction:set(player, 'command/ban')
end)
local ban_player = new_button("utility/danger_icon", { "player-list.ban-player" })
:on_click(function(player)
SelectedAction:set(player, "command/ban")
end)
local function ban_player_callback(player,reason)
local function ban_player_callback(player, reason)
local selected_player = get_action_player_name(player)
game.ban_player(selected_player,reason)
game.ban_player(selected_player, reason)
end
return {
set_datastores = set_datastores,
buttons = {
['command/teleport'] = {
auth=function(player,selected_player)
["command/teleport"] = {
auth = function(player, selected_player)
return player.name ~= selected_player.name
end, -- cant teleport to your self
goto_player,
bring_player
bring_player,
},
['command/report'] = {
auth=function(player,selected_player)
["command/report"] = {
auth = function(player, selected_player)
if player == selected_player then return false end
if not Roles.player_allowed(player,'command/give-warning') then
return not Roles.player_has_flag(selected_player,'report-immune')
if not Roles.player_allowed(player, "command/give-warning") then
return not Roles.player_has_flag(selected_player, "report-immune")
end
end, -- can report any player that isn't immune and you aren't able to give warnings
reason_callback=report_player_callback,
report_player
reason_callback = report_player_callback,
report_player,
},
['command/give-warning'] = {
auth=auth_lower_role, -- warn a lower user, replaces report
reason_callback=warn_player_callback,
warn_player
["command/give-warning"] = {
auth = auth_lower_role, -- warn a lower user, replaces report
reason_callback = warn_player_callback,
warn_player,
},
['command/jail'] = {
auth=auth_lower_role,
reason_callback=jail_player_callback,
jail_player
["command/jail"] = {
auth = auth_lower_role,
reason_callback = jail_player_callback,
jail_player,
},
['command/kick'] = {
auth=auth_lower_role,
reason_callback=kick_player_callback,
kick_player
["command/kick"] = {
auth = auth_lower_role,
reason_callback = kick_player_callback,
kick_player,
},
['command/ban'] = {
auth=auth_lower_role,
reason_callback=ban_player_callback,
ban_player
}
}
}
["command/ban"] = {
auth = auth_lower_role,
reason_callback = ban_player_callback,
ban_player,
},
},
}

View File

@@ -3,33 +3,45 @@
return {
stats = { --- @setting stats The data that will show in the stats section
show_stats=true, --- @setting show_stats false will hide this section all together
show_stats = true, --- @setting show_stats false will hide this section all together
show_first_rocket = true, --- @setting show_first_rocket false will not show when the first rocket was launched
show_last_rocket = true, --- @setting show_last_rocket false will not show when the last rocket was launched
show_fastest_rocket = true, --- @setting show_fastest_rocket false will not show the time taken for the fastest rocket
show_total_rockets = true, --- @setting show_total_rockets false will not show the total number of rockets launched
show_game_avg = true, --- @setting show_game_avg false will hide the avg across the entire map time
rolling_avg = { --- @setting rolling_avg each number will be one statistic; 5 means the avg time taken for the last 5 rockets
5,10,25
}
5, 10, 25,
},
},
milestones = { --- @setting milestones each number will be one statistic; 5 means the time that the 5th rocket was launched
show_milestones=true, --- @setting show_milestones false will hide this section all together
1,2,5,
10,20,50,
100,200,500,
1000,1500,2000,2500,
3000,3500,4000,4500,
5000
show_milestones = true, --- @setting show_milestones false will hide this section all together
1,
2,
5,
10,
20,
50,
100,
200,
500,
1000,
1500,
2000,
2500,
3000,
3500,
4000,
4500,
5000,
},
progress = { --- @setting progress The data and buttons in the build progress section
show_progress = true, --- @setting show_progress false will hide this section altogether
allow_zoom_to_map = true, --- @setting allow_zoom_to_map false will disable the zoom to map feature
allow_remote_launch = true, --- @setting allow_remote_launch false removes the remote launch button for all players
remote_launch_admins_only = false, --- @setting remote_launch_admins_only true will remove the remote launch button for all non (game) admins
remote_launch_role_permission = 'gui/rocket-info/remote_launch', --- @setting remote_launch_role_permission value used by custom permission system to allow or disallow the button
remote_launch_role_permission = "gui/rocket-info/remote_launch", --- @setting remote_launch_role_permission value used by custom permission system to allow or disallow the button
allow_toggle_active = true, --- @setting allow_toggle_active false removes the remote toggle auto launch button for all players
toggle_active_admins_only = false, --- @setting toggle_active_admins_only true will remove the toggle auto launch button for all non (game) admins
toggle_active_role_permission = 'gui/rocket-info/toggle-active' --- @setting toggle_active_role_permission value used by custom permission system to allow or disallow the button
}
}
toggle_active_role_permission = "gui/rocket-info/toggle-active", --- @setting toggle_active_role_permission value used by custom permission system to allow or disallow the button
},
}

View File

@@ -6,11 +6,11 @@ return {
show_eta = true, --- @setting show_eta when true the eta for research completion will be shown
color_cutoff = 0.8, --- @setting color_cutoff the amount that production can fall before the text changes color
color_flux = 0.1, --- @setting color_flux the amount of fluctuation allowed in production before the icon changes color
'automation-science-pack',
'logistic-science-pack',
'military-science-pack',
'chemical-science-pack',
'production-science-pack',
'utility-science-pack',
'space-science-pack',
}
"automation-science-pack",
"logistic-science-pack",
"military-science-pack",
"chemical-science-pack",
"production-science-pack",
"utility-science-pack",
"space-science-pack",
}

View File

@@ -3,11 +3,11 @@
return {
-- Adding tasks
allow_add_task = 'all', --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none
expcore_roles_allow_add_task = 'gui/task-list/add', --- @setting expcore_roles_allow_add_task if expcore.roles is used then this is the required permission
allow_add_task = "all", --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none
expcore_roles_allow_add_task = "gui/task-list/add", --- @setting expcore_roles_allow_add_task if expcore.roles is used then this is the required permission
-- Editing tasks
allow_edit_task = 'expcore.roles', --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none
expcore_roles_allow_edit_task = 'gui/task-list/edit', --- @setting expcore_roles_allow_edit_task if expcore.roles is used then this is the required permission
user_can_edit_own_tasks = true --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting
}
allow_edit_task = "expcore.roles", --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none
expcore_roles_allow_edit_task = "gui/task-list/edit", --- @setting expcore_roles_allow_edit_task if expcore.roles is used then this is the required permission
user_can_edit_own_tasks = true, --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting
}

View File

@@ -5,48 +5,48 @@ return {
-- General config
update_smoothing = 10, --- @setting update_smoothing the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60
minimum_distance = 100, --- @setting minimum_distance the minimum distance that is allowed between warps on the same force
default_icon = {type = 'item', name = 'discharge-defense-equipment'}, --- @setting default_icon the default icon that will be used for warps
default_icon = { type = "item", name = "discharge-defense-equipment" }, --- @setting default_icon the default icon that will be used for warps
-- Warp cooldowns
bypass_warp_cooldown = 'expcore.roles', --- @setting bypass_warp_cooldown dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none
expcore_roles_bypass_warp_cooldown = 'gui/warp-list/bypass-cooldown', --- @setting expcore_roles_bypass_warp_cooldown if expcore.roles is used then this is the required permission
bypass_warp_cooldown = "expcore.roles", --- @setting bypass_warp_cooldown dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none
expcore_roles_bypass_warp_cooldown = "gui/warp-list/bypass-cooldown", --- @setting expcore_roles_bypass_warp_cooldown if expcore.roles is used then this is the required permission
cooldown_duration = 60, --- @setting cooldown_duration the duration of the warp cooldown in seconds
-- Warp proximity
bypass_warp_proximity = 'expcore.roles', --- @setting bypass_warp_proximity dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none
expcore_roles_bypass_warp_proximity = 'gui/warp-list/bypass-proximity', --- @setting expcore_roles_bypass_warp_proximity if expcore.roles is used then this is the required permission
bypass_warp_proximity = "expcore.roles", --- @setting bypass_warp_proximity dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none
expcore_roles_bypass_warp_proximity = "gui/warp-list/bypass-proximity", --- @setting expcore_roles_bypass_warp_proximity if expcore.roles is used then this is the required permission
standard_proximity_radius = 4, --- @setting standard_proximity_radius the minimum distance a player is allowed to be to a warp in order to use it
spawn_proximity_radius = 20, --- @setting spawn_proximity_radius the minimum distance a player is allowed to be from they spawn point to use warps
-- Adding warps
allow_add_warp = 'expcore.roles', --- @setting allow_add_warp dictates who is allowed to add warps; values: all, admin, expcore.roles, none
expcore_roles_allow_add_warp = 'gui/warp-list/add', --- @setting expcore_roles_allow_add_warp if expcore.roles is used then this is the required permission
allow_add_warp = "expcore.roles", --- @setting allow_add_warp dictates who is allowed to add warps; values: all, admin, expcore.roles, none
expcore_roles_allow_add_warp = "gui/warp-list/add", --- @setting expcore_roles_allow_add_warp if expcore.roles is used then this is the required permission
-- Editing warps
allow_edit_warp = 'expcore.roles', --- @setting allow_edit_warp dictates who is allowed to edit warps; values: all, admin, expcore.roles, none
expcore_roles_allow_edit_warp = 'gui/warp-list/edit', --- @setting expcore_roles_allow_edit_warp if expcore.roles is used then this is the required permission
allow_edit_warp = "expcore.roles", --- @setting allow_edit_warp dictates who is allowed to edit warps; values: all, admin, expcore.roles, none
expcore_roles_allow_edit_warp = "gui/warp-list/edit", --- @setting expcore_roles_allow_edit_warp if expcore.roles is used then this is the required permission
user_can_edit_own_warps = false, --- @settings user_can_edit_own_warps if true then the user who made the warp can edit it regardless of the allow_edit_warp setting
-- Warp area generation
entities = { --- @setting entities The entities which are created for warp areas
{'small-lamp', -4, -2}, {'small-lamp', -2, -4}, {'medium-electric-pole',-3,-3}, -- Top left corner
{'small-lamp', 3, -2}, {'small-lamp', 1, -4}, {'medium-electric-pole',2,-3}, -- Top right corner
{'small-lamp', 3, 1}, {'small-lamp', 1, 3}, {'medium-electric-pole',2,2}, -- Bottom right corner
{'small-lamp', -4, 1}, {'small-lamp', -2, 3}, {'medium-electric-pole',-3,2}, -- Bottom left corner
{ "small-lamp", -4, -2 }, { "small-lamp", -2, -4 }, { "medium-electric-pole", -3, -3 }, -- Top left corner
{ "small-lamp", 3, -2 }, { "small-lamp", 1, -4 }, { "medium-electric-pole", 2, -3 }, -- Top right corner
{ "small-lamp", 3, 1 }, { "small-lamp", 1, 3 }, { "medium-electric-pole", 2, 2 }, -- Bottom right corner
{ "small-lamp", -4, 1 }, { "small-lamp", -2, 3 }, { "medium-electric-pole", -3, 2 }, -- Bottom left corner
},
tiles = { --- @setting tiles The tiles which are created for warp areas
{'black-refined-concrete',-4,-2}, {'black-refined-concrete',-4,-1}, {'black-refined-concrete',-4,0}, {'black-refined-concrete',-4,1},
{'black-refined-concrete',-3,-3}, {'purple-refined-concrete',-3,-2}, {'purple-refined-concrete',-3,-1}, {'purple-refined-concrete',-3,0},
{'purple-refined-concrete',-3,1}, {'black-refined-concrete',-3,2}, {'black-refined-concrete',-2,-4}, {'purple-refined-concrete',-2,-3},
{'purple-refined-concrete',-2,-2}, {'purple-refined-concrete',-2,-1}, {'purple-refined-concrete',-2,0}, {'purple-refined-concrete',-2,1},
{'purple-refined-concrete',-2,2}, {'black-refined-concrete',-2,3}, {'black-refined-concrete',-1,-4}, {'purple-refined-concrete',-1,-3},
{'purple-refined-concrete',-1,-2}, {'purple-refined-concrete',-1,-1}, {'purple-refined-concrete',-1,0}, {'purple-refined-concrete',-1,1},
{'purple-refined-concrete',-1,2}, {'black-refined-concrete',-1,3}, {'black-refined-concrete',0,-4}, {'purple-refined-concrete',0,-3},
{'purple-refined-concrete',0,-2}, {'purple-refined-concrete',0,-1}, {'purple-refined-concrete',0,0}, {'purple-refined-concrete',0,1},
{'purple-refined-concrete',0,2}, {'black-refined-concrete',0,3}, {'black-refined-concrete',1,-4}, {'purple-refined-concrete',1,-3},
{'purple-refined-concrete',1,-2}, {'purple-refined-concrete',1,-1}, {'purple-refined-concrete',1,0}, {'purple-refined-concrete',1,1},
{'purple-refined-concrete',1,2}, {'black-refined-concrete',1,3}, {'black-refined-concrete',2,-3}, {'purple-refined-concrete',2,-2},
{'purple-refined-concrete',2,-1}, {'purple-refined-concrete',2,0}, {'purple-refined-concrete',2,1}, {'black-refined-concrete',2,2},
{'black-refined-concrete',3,-2}, {'black-refined-concrete',3,-1}, {'black-refined-concrete',3,0}, {'black-refined-concrete',3,1}
}
{ "black-refined-concrete", -4, -2 }, { "black-refined-concrete", -4, -1 }, { "black-refined-concrete", -4, 0 }, { "black-refined-concrete", -4, 1 },
{ "black-refined-concrete", -3, -3 }, { "purple-refined-concrete", -3, -2 }, { "purple-refined-concrete", -3, -1 }, { "purple-refined-concrete", -3, 0 },
{ "purple-refined-concrete", -3, 1 }, { "black-refined-concrete", -3, 2 }, { "black-refined-concrete", -2, -4 }, { "purple-refined-concrete", -2, -3 },
{ "purple-refined-concrete", -2, -2 }, { "purple-refined-concrete", -2, -1 }, { "purple-refined-concrete", -2, 0 }, { "purple-refined-concrete", -2, 1 },
{ "purple-refined-concrete", -2, 2 }, { "black-refined-concrete", -2, 3 }, { "black-refined-concrete", -1, -4 }, { "purple-refined-concrete", -1, -3 },
{ "purple-refined-concrete", -1, -2 }, { "purple-refined-concrete", -1, -1 }, { "purple-refined-concrete", -1, 0 }, { "purple-refined-concrete", -1, 1 },
{ "purple-refined-concrete", -1, 2 }, { "black-refined-concrete", -1, 3 }, { "black-refined-concrete", 0, -4 }, { "purple-refined-concrete", 0, -3 },
{ "purple-refined-concrete", 0, -2 }, { "purple-refined-concrete", 0, -1 }, { "purple-refined-concrete", 0, 0 }, { "purple-refined-concrete", 0, 1 },
{ "purple-refined-concrete", 0, 2 }, { "black-refined-concrete", 0, 3 }, { "black-refined-concrete", 1, -4 }, { "purple-refined-concrete", 1, -3 },
{ "purple-refined-concrete", 1, -2 }, { "purple-refined-concrete", 1, -1 }, { "purple-refined-concrete", 1, 0 }, { "purple-refined-concrete", 1, 1 },
{ "purple-refined-concrete", 1, 2 }, { "black-refined-concrete", 1, 3 }, { "black-refined-concrete", 2, -3 }, { "purple-refined-concrete", 2, -2 },
{ "purple-refined-concrete", 2, -1 }, { "purple-refined-concrete", 2, 0 }, { "purple-refined-concrete", 2, 1 }, { "black-refined-concrete", 2, 2 },
{ "black-refined-concrete", 3, -2 }, { "black-refined-concrete", 3, -1 }, { "black-refined-concrete", 3, 0 }, { "black-refined-concrete", 3, 1 },
},
}

View File

@@ -5,5 +5,5 @@ local events = defines.events
return {
events.on_player_banned,
events.on_player_kicked,
--events.on_player_left_game
}
-- events.on_player_left_game
}

View File

@@ -1,8 +1,8 @@
return {
Cooldude2606 = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.',
samy115 = 'Tremble in fear as the banhammer is now here, its owner: samy115',
Cooldude2606 = "Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.",
samy115 = "Tremble in fear as the banhammer is now here, its owner: samy115",
XenoCyber = '"Fire Fire Fire" oops wrong game, have no fear XenoCyber is here',
HunterOfGames = 'Unable to support HunterOfGames. You must construct additional miners.',
HunterOfGames = "Unable to support HunterOfGames. You must construct additional miners.",
ookl = 'ookl says: "Pineapples are amazing, hello everyone!"',
arty714 = 'Arty\'s Potato made it!'
}
arty714 = "Arty\'s Potato made it!",
}

View File

@@ -2,5 +2,5 @@
-- @config lawnmower
return {
destroy_decoratives = false
destroy_decoratives = false,
}

View File

@@ -2,7 +2,7 @@
-- @config logging
return {
file_name = 'log/logging.log',
file_name = "log/logging.log",
rocket_launch_display = {
[1] = true,
[2] = true,
@@ -11,20 +11,33 @@ return {
[20] = true,
[50] = true,
[100] = true,
[200] = true
[200] = true,
[500] = true,
[1000] = true,
[2000] = true,
[5000] = true,
[10000] = true,
[20000] = true,
[50000] = true,
[100000] = true,
[200000] = true,
[500000] = true,
[1000000] = true,
[2000000] = true,
[5000000] = true,
[10000000] = true,
},
rocket_launch_display_rate = 500,
disconnect_reason = {
[defines.disconnect_reason.quit] = ' left the game',
[defines.disconnect_reason.dropped] = ' was dropped from the game',
[defines.disconnect_reason.reconnect] = ' is reconnecting',
[defines.disconnect_reason.wrong_input] = ' was having a wrong input',
[defines.disconnect_reason.desync_limit_reached] = ' had desync limit reached',
[defines.disconnect_reason.cannot_keep_up] = ' cannot keep up',
[defines.disconnect_reason.afk] = ' was afk',
[defines.disconnect_reason.kicked] = ' was kicked',
[defines.disconnect_reason.kicked_and_deleted] = ' was kicked and deleted',
[defines.disconnect_reason.banned] = ' was banned',
[defines.disconnect_reason.switching_servers] = ' is switching servers'
}
[defines.disconnect_reason.quit] = " left the game",
[defines.disconnect_reason.dropped] = " was dropped from the game",
[defines.disconnect_reason.reconnect] = " is reconnecting",
[defines.disconnect_reason.wrong_input] = " was having a wrong input",
[defines.disconnect_reason.desync_limit_reached] = " had desync limit reached",
[defines.disconnect_reason.cannot_keep_up] = " cannot keep up",
[defines.disconnect_reason.afk] = " was afk",
[defines.disconnect_reason.kicked] = " was kicked",
[defines.disconnect_reason.kicked_and_deleted] = " was kicked and deleted",
[defines.disconnect_reason.banned] = " was banned",
[defines.disconnect_reason.switching_servers] = " is switching servers",
},
}

View File

@@ -3,5 +3,5 @@
return {
fluid = true, --- @setting fluid When true, checks for for fluid pipes when removing miners
chest = true --- @setting chest When true, checks for for chest when removing miners
chest = true, --- @setting chest When true, checks for for chest when removing miners
}

View File

@@ -5,94 +5,94 @@ return {
copy_paste_module = true,
copy_paste_rotation = false,
machine = {
['electric-mining-drill'] = {
['module'] = 'effectivity-module',
['prod'] = true
["electric-mining-drill"] = {
["module"] = "effectivity-module",
["prod"] = true,
},
['pumpjack'] = {
['module'] = 'effectivity-module',
['prod'] = true
["pumpjack"] = {
["module"] = "effectivity-module",
["prod"] = true,
},
['assembling-machine-2'] = {
['module'] = 'productivity-module',
['prod'] = true
["assembling-machine-2"] = {
["module"] = "productivity-module",
["prod"] = true,
},
['assembling-machine-3'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["assembling-machine-3"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['electric-furnace'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["electric-furnace"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['beacon'] = {
['module'] = 'speed-module-3',
['prod'] = false
["beacon"] = {
["module"] = "speed-module-3",
["prod"] = false,
},
['oil-refinery'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["oil-refinery"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['chemical-plant'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["chemical-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['centrifuge'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["centrifuge"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['lab'] = {
['module'] = 'productivity-module-3',
['prod'] = true
["lab"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["rocket-silo"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
['rocket-silo'] = {
['module'] = 'productivity-module-3',
['prod'] = true
}
},
module_allowed = {
['advanced-circuit'] = true,
['automation-science-pack'] = true,
['battery'] = true,
['chemical-science-pack'] = true,
['copper-cable'] = true,
['copper-plate'] = true,
['electric-engine-unit'] = true,
['electronic-circuit'] = true,
['empty-barrel'] = true,
['engine-unit'] = true,
['explosives'] = true,
['flying-robot-frame'] = true,
['iron-gear-wheel'] = true,
['iron-plate'] = true,
['iron-stick'] = true,
['logistic-science-pack'] = true,
['low-density-structure'] = true,
['lubricant'] = true,
['military-science-pack'] = true,
['nuclear-fuel'] = true,
['plastic-bar'] = true,
['processing-unit'] = true,
['production-science-pack'] = true,
['rocket-control-unit'] = true,
['rocket-fuel'] = true,
['rocket-part'] = true,
['steel-plate'] = true,
['stone-brick'] = true,
['sulfur'] = true,
['sulfuric-acid'] = true,
['uranium-fuel-cell'] = true,
['utility-science-pack'] = true,
['basic-oil-processing'] = true,
['advanced-oil-processing'] = true,
['coal-liquefaction'] = true,
['heavy-oil-cracking'] = true,
['light-oil-cracking'] = true,
['solid-fuel-from-light-oil'] = true,
['solid-fuel-from-petroleum-gas'] = true,
['solid-fuel-from-heavy-oil'] = true,
['uranium-processing'] = true,
['nuclear-fuel-reprocessing'] = true,
['kovarex-enrichment-process'] = true
}
["advanced-circuit"] = true,
["automation-science-pack"] = true,
["battery"] = true,
["chemical-science-pack"] = true,
["copper-cable"] = true,
["copper-plate"] = true,
["electric-engine-unit"] = true,
["electronic-circuit"] = true,
["empty-barrel"] = true,
["engine-unit"] = true,
["explosives"] = true,
["flying-robot-frame"] = true,
["iron-gear-wheel"] = true,
["iron-plate"] = true,
["iron-stick"] = true,
["logistic-science-pack"] = true,
["low-density-structure"] = true,
["lubricant"] = true,
["military-science-pack"] = true,
["nuclear-fuel"] = true,
["plastic-bar"] = true,
["processing-unit"] = true,
["production-science-pack"] = true,
["rocket-control-unit"] = true,
["rocket-fuel"] = true,
["rocket-part"] = true,
["steel-plate"] = true,
["stone-brick"] = true,
["sulfur"] = true,
["sulfuric-acid"] = true,
["uranium-fuel-cell"] = true,
["utility-science-pack"] = true,
["basic-oil-processing"] = true,
["advanced-oil-processing"] = true,
["coal-liquefaction"] = true,
["heavy-oil-cracking"] = true,
["light-oil-cracking"] = true,
["solid-fuel-from-light-oil"] = true,
["solid-fuel-from-petroleum-gas"] = true,
["solid-fuel-from-heavy-oil"] = true,
["uranium-processing"] = true,
["nuclear-fuel-reprocessing"] = true,
["kovarex-enrichment-process"] = true,
},
}

View File

@@ -1,34 +1,34 @@
return {
inventories = {
{
inventory = defines.inventory.character_ammo,
event = defines.events.on_player_ammo_inventory_changed,
items = {
["atomic-bomb"] = true
},
},
{
inventory = defines.inventory.character_armor,
event = defines.events.on_player_armor_inventory_changed,
items = {},
},
{
inventory = defines.inventory.character_guns,
event = defines.events.on_player_gun_inventory_changed,
items = {},
},
{
inventory = defines.inventory.character_main,
event = defines.events.on_player_main_inventory_changed,
items = {
["atomic-bomb"] = true
},
},
},
ignore_permisison = "bypass-nukeprotect", -- @setting ignore_permisison The permission that nukeprotect will ignore
ignore_admins = true, -- @setting ignore_admins Ignore admins, true by default. Allows usage outside of the roles module
disable_nuke_research = false, -- @setting disable_nuke_research Disable the nuke research, true by default
disable_nuke_research_names = {
["atomic-bomb"] = true
} -- @setting disable_nuke_research_names The names of the researches to disabled
inventories = {
{
inventory = defines.inventory.character_ammo,
event = defines.events.on_player_ammo_inventory_changed,
items = {
["atomic-bomb"] = true,
},
},
{
inventory = defines.inventory.character_armor,
event = defines.events.on_player_armor_inventory_changed,
items = {},
},
{
inventory = defines.inventory.character_guns,
event = defines.events.on_player_gun_inventory_changed,
items = {},
},
{
inventory = defines.inventory.character_main,
event = defines.events.on_player_main_inventory_changed,
items = {
["atomic-bomb"] = true,
},
},
},
ignore_permisison = "bypass-nukeprotect", -- @setting ignore_permisison The permission that nukeprotect will ignore
ignore_admins = true, -- @setting ignore_admins Ignore admins, true by default. Allows usage outside of the roles module
disable_nuke_research = false, -- @setting disable_nuke_research Disable the nuke research, true by default
disable_nuke_research_names = {
["atomic-bomb"] = true,
}, -- @setting disable_nuke_research_names The names of the researches to disabled
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,8 @@
-- @config Pollution-Grading
return {
reference_point = {x=0,y=0}, --- @setting reference_point where pollution is read from
reference_point = { x = 0, y = 0 }, --- @setting reference_point where pollution is read from
max_scalar = 0.5, --- @setting max_scalar the scale between true max and max
min_scalar = 0.17, --- @setting min_scalar the scale between the lowest max and min
update_delay = 15 --- @setting update_delay time in minutes between view updates
}
update_delay = 15, --- @setting update_delay time in minutes between view updates
}

View File

@@ -2,9 +2,9 @@
-- @config Popup-Messages
return {
show_player_messages=true, --- @setting show_player_messages weather a message in chat will make a popup above them
show_player_mentions=true, --- @setting show_player_mentions weather a mentioned player will have a popup when mentioned in chat
show_player_damage=true, --- @setting show_player_damage weather to show damage done by players
show_player_health=true, --- @setting show_player_health weather to show player health when attacked
damage_location_variance=0.8 --- @setting damage_location_variance how close to the eade of an entity the popups will appear
}
show_player_messages = true, --- @setting show_player_messages weather a message in chat will make a popup above them
show_player_mentions = true, --- @setting show_player_mentions weather a mentioned player will have a popup when mentioned in chat
show_player_damage = true, --- @setting show_player_damage weather to show damage done by players
show_player_health = true, --- @setting show_player_health weather to show player health when attacked
damage_location_variance = 0.8, --- @setting damage_location_variance how close to the eade of an entity the popups will appear
}

View File

@@ -2,32 +2,32 @@
-- @config Preset-Player-Colours
return {
players={ --- @setting players list of all players and the colour in rgb256 that they will recive upon joining
PHIDIAS0303={r=255,g=255,b=255},
BADgamerNL={r=255,g=20,b=147},
arty714={r=150,g=68,b=161},
Cooldude2606={r=57,g=192,b=207},
mark9064={r=99,g=0,b=255},
eissturm={r=25,g=25,b=112},
Sakama={r=20,g=213,b=80},
freek18={r=50,g=0,b=255},
aldldl={r=0,g=131,b=255},
NAD4X4={r=135,g=206,b=250},
cydes={r=82,g=249,b=155},
UUBlueFire={r=0,g=204,b=255},
CmonMate497={r=103,g=224,b=194},
s4sh={r=255,g=120,b=0},
ArPiiX={r=0,g=255,b=0},
NextIdea={r=255,g=255,b=255},
hamsterbryan={r=0,g=255,b=0},
XenoCyber={r=0,g=128,b=255}
},
disallow = { --- @setting disallow colours which will not given to players; the value does not matter it is only the key which is checked
black = {r = 0, g = 0, b = 0},
white = {r = 255, g = 255, b = 255},
success = {r = 0, g = 255, b = 0},
warning = {r = 255, g = 255, b = 0},
fail = {r = 255, g = 0, b = 0},
info = {r = 255, g = 255, b = 255}
}
players = { --- @setting players list of all players and the colour in rgb256 that they will recive upon joining
PHIDIAS0303 = { r = 255, g = 255, b = 255 },
BADgamerNL = { r = 255, g = 20, b = 147 },
arty714 = { r = 150, g = 68, b = 161 },
Cooldude2606 = { r = 57, g = 192, b = 207 },
mark9064 = { r = 99, g = 0, b = 255 },
eissturm = { r = 25, g = 25, b = 112 },
Sakama = { r = 20, g = 213, b = 80 },
freek18 = { r = 50, g = 0, b = 255 },
aldldl = { r = 0, g = 131, b = 255 },
NAD4X4 = { r = 135, g = 206, b = 250 },
cydes = { r = 82, g = 249, b = 155 },
UUBlueFire = { r = 0, g = 204, b = 255 },
CmonMate497 = { r = 103, g = 224, b = 194 },
s4sh = { r = 255, g = 120, b = 0 },
ArPiiX = { r = 0, g = 255, b = 0 },
NextIdea = { r = 255, g = 255, b = 255 },
hamsterbryan = { r = 0, g = 255, b = 0 },
XenoCyber = { r = 0, g = 128, b = 255 },
},
disallow = { --- @setting disallow colours which will not given to players; the value does not matter it is only the key which is checked
black = { r = 0, g = 0, b = 0 },
white = { r = 255, g = 255, b = 255 },
success = { r = 0, g = 255, b = 0 },
warning = { r = 255, g = 255, b = 0 },
fail = { r = 255, g = 0, b = 0 },
info = { r = 255, g = 255, b = 255 },
},
}

View File

@@ -2,5 +2,5 @@
-- @config Preset-Player-Quickbar
return {
dangerarea = {"transport-belt", "underground-belt", "splitter", "pipe", "pipe-to-ground", "inserter", "fast-inserter", "long-handed-inserter", "stack-inserter", "roboport", "small-electric-pole", "medium-electric-pole", "big-electric-pole", "substation", nil, "rail", "rail-signal", "rail-chain-signal", "landfill", "cliff-explosives", "fast-transport-belt", "fast-underground-belt", "fast-splitter", "pipe", "pipe-to-ground", "fast-inserter", "long-handed-inserter", "stack-inserter", "stack-filter-inserter", "roboport", [81] = "red-wire", [82] = "green-wire", [83] = "arithmetic-combinator", [84] = "decider-combinator", [85] = "constant-combinator", [86] = "power-switch", [91] = "logistic-chest-active-provider", [92] = "logistic-chest-passive-provider", [93] = "logistic-chest-storage", [94] = "logistic-chest-buffer", [95] = "logistic-chest-requester", [96] = "roboport"}
dangerarea = { "transport-belt", "underground-belt", "splitter", "pipe", "pipe-to-ground", "inserter", "fast-inserter", "long-handed-inserter", "stack-inserter", "roboport", "small-electric-pole", "medium-electric-pole", "big-electric-pole", "substation", nil, "rail", "rail-signal", "rail-chain-signal", "landfill", "cliff-explosives", "fast-transport-belt", "fast-underground-belt", "fast-splitter", "pipe", "pipe-to-ground", "fast-inserter", "long-handed-inserter", "stack-inserter", "stack-filter-inserter", "roboport", [81] = "red-wire", [82] = "green-wire", [83] = "arithmetic-combinator", [84] = "decider-combinator", [85] = "constant-combinator", [86] = "power-switch", [91] = "logistic-chest-active-provider", [92] = "logistic-chest-passive-provider", [93] = "logistic-chest-storage", [94] = "logistic-chest-buffer", [95] = "logistic-chest-requester", [96] = "roboport" },
}

View File

@@ -1,19 +1,19 @@
return {
ignore_admins = true, --- @setting ignore_admins If admins are ignored by the protection filter
ignore_permission = 'bypass-entity-protection', --- @setting ignore_permission Players with this permission will be ignored by the protection filter, leave nil if expcore.roles is not used
ignore_permission = "bypass-entity-protection", --- @setting ignore_permission Players with this permission will be ignored by the protection filter, leave nil if expcore.roles is not used
repeat_count = 5, --- @setting repeat_count Number of protected entities that must be removed within repeat_lifetime in order to trigger repeated removal protection
repeat_lifetime = 3600*20, --- @setting repeat_lifetime The length of time, in ticks, that protected removals will be remembered for
refresh_rate = 3600*5, --- @setting refresh_rate How often the age of protected removals are checked against repeat_lifetime
repeat_lifetime = 3600 * 20, --- @setting repeat_lifetime The length of time, in ticks, that protected removals will be remembered for
refresh_rate = 3600 * 5, --- @setting refresh_rate How often the age of protected removals are checked against repeat_lifetime
always_protected_names = { --- @setting always_protected_names Names of entities which are always protected
},
always_protected_types = { --- @setting always_protected_types Types of entities which are always protected
'boiler', 'generator', 'offshore-pump', 'power-switch', 'reactor', 'rocket-silo'
"boiler", "generator", "offshore-pump", "power-switch", "reactor", "rocket-silo",
},
always_trigger_repeat_names = { --- @setting always_trigger_repeat_names Names of entities which always trigger repeated removal protection
},
always_trigger_repeat_types = { --- @setting always_trigger_repeat_types Types of entities which always trigger repeated removal protection
'reactor', 'rocket-silo'
}
}
"reactor", "rocket-silo",
},
}

View File

@@ -3,14 +3,14 @@
return {
disallow = { --- @setting disallow items in this list will never be repaired
['loader']=true,
['fast-loader']=true,
['express-loader']=true,
['electric-energy-interface']=true,
['infinity-chest']=true
["loader"] = true,
["fast-loader"] = true,
["express-loader"] = true,
["electric-energy-interface"] = true,
["infinity-chest"] = true,
},
max_range=50, --- @setting max_range the max range that can be used with the repair command
allow_blueprint_repair=false, --- @setting allow_blueprint_repair when true will allow blueprints (things not destroyed by biters) to be build instantly using the repair command
allow_ghost_revive=true, --- @setting allow_ghost_revive when true will allow ghosts (things destroyed by biters) to be build instantly using the repair command
allow_heal_entities=true --- @setting allow_heal_entities when true will heal entities to full health that are within range
}
max_range = 50, --- @setting max_range the max range that can be used with the repair command
allow_blueprint_repair = false, --- @setting allow_blueprint_repair when true will allow blueprints (things not destroyed by biters) to be build instantly using the repair command
allow_ghost_revive = true, --- @setting allow_ghost_revive when true will allow ghosts (things destroyed by biters) to be build instantly using the repair command
allow_heal_entities = true, --- @setting allow_heal_entities when true will heal entities to full health that are within range
}

View File

@@ -8,74 +8,74 @@ return {
-- this enable 20 more inventory for each mining productivity level up to 4
bonus_inventory = {
enabled = true,
name = 'character_inventory_slots_bonus',
name = "character_inventory_slots_bonus",
rate = 5,
limit = 20
limit = 20,
},
file_name = 'log/research.log',
file_name = "log/research.log",
milestone = {
['automation'] = 600,
['logistics'] = 300,
['steel-processing'] = 300,
['logistic-science-pack'] = 300,
['electronics'] = 300,
['fast-inserter'] = 300,
['steel-axe'] = 300,
['automation-2'] = 300,
['advanced-material-processing'] = 300,
['engine'] = 300,
['fluid-handling'] = 300,
['oil-processing'] = 300,
['sulfur-processing'] = 300,
['plastics'] = 300,
['advanced-electronics'] = 300,
['chemical-science-pack'] = 300,
['modules'] = 300,
['logistics-2'] = 300,
['railway'] = 300,
['research-speed-1'] = 300,
['research-speed-2'] = 300,
['battery'] = 300,
['concrete'] = 300,
['flammables'] = 300,
['low-density-structure'] = 300,
['advanced-material-processing-2'] = 300,
['productivity-module'] = 300,
['production-science-pack'] = 300,
['advanced-electronics-2'] = 300,
['advanced-oil-processing'] = 300,
['electric-engine'] = 300,
['robotics'] = 300,
['construction-robotics'] = 300,
['worker-robots-speed-1'] = 300,
['worker-robots-speed-2'] = 300,
['utility-science-pack'] = 300,
['productivity-module-2'] = 300,
['speed-module-2'] = 300,
['rocket-fuel'] = 300,
['effect-transmission'] = 300,
['productivity-module-3'] = 300,
['rocket-control-unit'] = 300,
['speed-module-3'] = 300,
['rocket-silo'] = 300,
['space-science-pack'] = 300,
["automation"] = 600,
["logistics"] = 300,
["steel-processing"] = 300,
["logistic-science-pack"] = 300,
["electronics"] = 300,
["fast-inserter"] = 300,
["steel-axe"] = 300,
["automation-2"] = 300,
["advanced-material-processing"] = 300,
["engine"] = 300,
["fluid-handling"] = 300,
["oil-processing"] = 300,
["sulfur-processing"] = 300,
["plastics"] = 300,
["advanced-electronics"] = 300,
["chemical-science-pack"] = 300,
["modules"] = 300,
["logistics-2"] = 300,
["railway"] = 300,
["research-speed-1"] = 300,
["research-speed-2"] = 300,
["battery"] = 300,
["concrete"] = 300,
["flammables"] = 300,
["low-density-structure"] = 300,
["advanced-material-processing-2"] = 300,
["productivity-module"] = 300,
["production-science-pack"] = 300,
["advanced-electronics-2"] = 300,
["advanced-oil-processing"] = 300,
["electric-engine"] = 300,
["robotics"] = 300,
["construction-robotics"] = 300,
["worker-robots-speed-1"] = 300,
["worker-robots-speed-2"] = 300,
["utility-science-pack"] = 300,
["productivity-module-2"] = 300,
["speed-module-2"] = 300,
["rocket-fuel"] = 300,
["effect-transmission"] = 300,
["productivity-module-3"] = 300,
["rocket-control-unit"] = 300,
["speed-module-3"] = 300,
["rocket-silo"] = 300,
["space-science-pack"] = 300,
},
inf_res = {
-- Mining Productivity
['mining-productivity-4'] = 4,
["mining-productivity-4"] = 4,
-- Robot Speed
['worker-robots-speed-6'] = 6,
["worker-robots-speed-6"] = 6,
-- Laser Damage
['energy-weapons-damage-7'] = 7,
["energy-weapons-damage-7"] = 7,
-- Explosive Damage
['stronger-explosives-7'] = 7,
["stronger-explosives-7"] = 7,
-- Bullet Damage
['physical-projectile-damage-7'] = 7,
["physical-projectile-damage-7"] = 7,
-- Flame Damage
['refined-flammables-7'] = 7,
["refined-flammables-7"] = 7,
-- Artillery Range
['artillery-shell-range-1'] = 1,
["artillery-shell-range-1"] = 1,
-- Artillery Speed
['artillery-shell-speed-1'] = 1
}
["artillery-shell-speed-1"] = 1,
},
}

View File

@@ -2,115 +2,115 @@
-- @config Scorched-Earth
return {
weakness_value=70, --- @setting weakness_value lower value will make tiles more likely to degrade
strengths={ --- @setting strengths this decides how "strong" a tile is, bigger number means less likely to degrade
weakness_value = 70, --- @setting weakness_value lower value will make tiles more likely to degrade
strengths = { --- @setting strengths this decides how "strong" a tile is, bigger number means less likely to degrade
-- debug: /interface require('modules.addons.worn-paths')(player.name,true)
-- note: tiles are effected by the tiles around them, so player paths will not degrade as fast when made wider
-- note: values are relative to the tile with the highest value, recommended to keep highest tile as a "nice" number
-- note: tiles not in list will never degrade under any conditions (which is why some are omitted such as water)
["refined-concrete"]=100,
["refined-hazard-concrete-left"]=100,
["refined-hazard-concrete-right"]=100,
["concrete"]=90,
["hazard-concrete-left"]=90,
["hazard-concrete-right"]=90,
["stone-path"]=80,
["red-desert-0"]=80,
["dry-dirt"]=50,
["refined-concrete"] = 100,
["refined-hazard-concrete-left"] = 100,
["refined-hazard-concrete-right"] = 100,
["concrete"] = 90,
["hazard-concrete-left"] = 90,
["hazard-concrete-right"] = 90,
["stone-path"] = 80,
["red-desert-0"] = 80,
["dry-dirt"] = 50,
-- grass four (main grass tiles)
["grass-1"]=50,
["grass-2"]=40,
["grass-3"]=30,
["grass-4"]=25,
["grass-1"] = 50,
["grass-2"] = 40,
["grass-3"] = 30,
["grass-4"] = 25,
-- red three (main red tiles)
["red-desert-1"]=40,
["red-desert-2"]=30,
["red-desert-3"]=25,
["red-desert-1"] = 40,
["red-desert-2"] = 30,
["red-desert-3"] = 25,
-- sand three (main sand tiles)
["sand-1"]=40,
["sand-2"]=30,
["sand-3"]=25,
["sand-1"] = 40,
["sand-2"] = 30,
["sand-3"] = 25,
-- dirt 3 (main dirt tiles)
["dirt-1"]=40,
["dirt-2"]=30,
["dirt-3"]=25,
["dirt-1"] = 40,
["dirt-2"] = 30,
["dirt-3"] = 25,
-- last three/four (all sets of three merge here)
["dirt-4"]=25,
["dirt-5"]=30,
["dirt-6"]=40,
--["dirt-7"]=0, -- last tile, nothing to degrade to
["dirt-4"] = 25,
["dirt-5"] = 30,
["dirt-6"] = 40,
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]=50,
--["water-shallow"]=90,
--["water-mud"]=0, -- last tile, nothing to degrade to
-- ["water-shallow"]=90,
-- ["water-mud"]=0, -- last tile, nothing to degrade to
},
degrade_order={ --- @setting degrade_order when a tile degrades it will turn into the next tile given here
["refined-concrete"]='concrete',
["refined-hazard-concrete-left"]='hazard-concrete-left',
["refined-hazard-concrete-right"]='hazard-concrete-right',
["concrete"]='stone-path',
["hazard-concrete-left"]='stone-path',
["hazard-concrete-right"]='stone-path',
["stone-path"]='dry-dirt',
["red-desert-0"]='dry-dirt',
["dry-dirt"]='dirt-4',
degrade_order = { --- @setting degrade_order when a tile degrades it will turn into the next tile given here
["refined-concrete"] = "concrete",
["refined-hazard-concrete-left"] = "hazard-concrete-left",
["refined-hazard-concrete-right"] = "hazard-concrete-right",
["concrete"] = "stone-path",
["hazard-concrete-left"] = "stone-path",
["hazard-concrete-right"] = "stone-path",
["stone-path"] = "dry-dirt",
["red-desert-0"] = "dry-dirt",
["dry-dirt"] = "dirt-4",
-- grass four (main grass tiles)
["grass-1"]='grass-2',
["grass-2"]='grass-3',
["grass-3"]='grass-4',
["grass-4"]='dirt-4',
["grass-1"] = "grass-2",
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
-- red three (main red tiles)
["red-desert-1"]='red-desert-2',
["red-desert-2"]='red-desert-3',
["red-desert-3"]='dirt-4',
["red-desert-1"] = "red-desert-2",
["red-desert-2"] = "red-desert-3",
["red-desert-3"] = "dirt-4",
-- sand three (main sand tiles)
["sand-1"]='sand-2',
["sand-2"]='sand-3',
["sand-3"]='dirt-4',
["sand-1"] = "sand-2",
["sand-2"] = "sand-3",
["sand-3"] = "dirt-4",
-- dirt 3 (main dirt tiles)
["dirt-1"]='dirt-2',
["dirt-2"]='dirt-3',
["dirt-3"]='dirt-4',
["dirt-1"] = "dirt-2",
["dirt-2"] = "dirt-3",
["dirt-3"] = "dirt-4",
-- last three/four (all sets of three merge here)
["dirt-4"]='dirt-5',
["dirt-5"]='dirt-6',
["dirt-6"]='dirt-7',
--["dirt-7"]=0, -- last tile, nothing to degrade to
["dirt-4"] = "dirt-5",
["dirt-5"] = "dirt-6",
["dirt-6"] = "dirt-7",
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]='grass-2', -- 'water-shallow'
--["water-shallow"]='water-mud',
--["water-mud"]=0, -- last tile, nothing to degrade to
-- ["water-shallow"]='water-mud',
-- ["water-mud"]=0, -- last tile, nothing to degrade to
},
entities={ --- @setting entities entities in this list will degrade the tiles under them when they are placed
['stone-furnace']=true,
['steel-furnace']=true,
['electric-furnace']=true,
['assembling-machine-1']=true,
['assembling-machine-2']=true,
['assembling-machine-3']=true,
['beacon']=true,
['centrifuge']=true,
['chemical-plant']=true,
['oil-refinery']=true,
['storage-tank']=true,
['nuclear-reactor']=true,
['steam-engine']=true,
['steam-turbine']=true,
['boiler']=true,
['heat-exchanger']=true,
['stone-wall']=true,
['gate']=true,
['gun-turret']=true,
['laser-turret']=true,
['flamethrower-turret']=true,
['radar']=true,
['lab']=true,
['big-electric-pole']=true,
['substation']=true,
['rocket-silo']=true,
['pumpjack']=true,
['electric-mining-drill']=true,
['roboport']=true,
['accumulator']=true
}
}
entities = { --- @setting entities entities in this list will degrade the tiles under them when they are placed
["stone-furnace"] = true,
["steel-furnace"] = true,
["electric-furnace"] = true,
["assembling-machine-1"] = true,
["assembling-machine-2"] = true,
["assembling-machine-3"] = true,
["beacon"] = true,
["centrifuge"] = true,
["chemical-plant"] = true,
["oil-refinery"] = true,
["storage-tank"] = true,
["nuclear-reactor"] = true,
["steam-engine"] = true,
["steam-turbine"] = true,
["boiler"] = true,
["heat-exchanger"] = true,
["stone-wall"] = true,
["gate"] = true,
["gun-turret"] = true,
["laser-turret"] = true,
["flamethrower-turret"] = true,
["radar"] = true,
["lab"] = true,
["big-electric-pole"] = true,
["substation"] = true,
["rocket-silo"] = true,
["pumpjack"] = true,
["electric-mining-drill"] = true,
["roboport"] = true,
["accumulator"] = true,
},
}

View File

@@ -6,249 +6,249 @@ return {
-- Enable predefined patches: 128, else: 32
deconstruction_radius = 20, -- @setting deconstruction_radius All entities within this radius will be removed
tile_radius = 20,
deconstruction_tile = 'concrete', --- @setting deconstruction_tile Tile to be placed in the deconstruction radius, use nil for map gen
deconstruction_tile = "concrete", --- @setting deconstruction_tile Tile to be placed in the deconstruction radius, use nil for map gen
landfill_radius = 50, --- @setting pattern_radius All water within this radius will be land filled
},
turrets = { --- @setting turrets Settings relating to adding turrets to spawn
enabled = true, --- @setting enabled Whether turrets will be added to spawn
ammo_type = 'uranium-rounds-magazine', --- @setting ammo_type The ammo type that will be used during refills
refill_time = 60*60*5, --- @setting refill_time The time in ticks between each refill of the turrets, only change if having lag issues
offset = {x=0, y=0}, --- @setting offset The position offset to apply to turrets
ammo_type = "uranium-rounds-magazine", --- @setting ammo_type The ammo type that will be used during refills
refill_time = 60 * 60 * 5, --- @setting refill_time The time in ticks between each refill of the turrets, only change if having lag issues
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to turrets
locations = { --- @setting locations The locations of all turrets, this list can change during runtime
{surface=1,position={x=-3,y=-3}},
{surface=1,position={x=3,y=-3}},
{surface=1,position={x=-3,y=3}},
{surface=1,position={x=3,y=3}}
}
{ surface = 1, position = { x = -3, y = -3 } },
{ surface = 1, position = { x = 3, y = -3 } },
{ surface = 1, position = { x = -3, y = 3 } },
{ surface = 1, position = { x = 3, y = 3 } },
},
},
afk_belts = { --- @setting afk_belts Settings relating to adding afk belts to spawn
enabled = true, --- @setting enabled Whether afk belts will be added to spawn
belt_type = 'transport-belt', --- @setting belt_type The belt to be used as afk belts
belt_type = "transport-belt", --- @setting belt_type The belt to be used as afk belts
protected = true, --- @setting protected Whether belts will be protected from player interaction
offset = {x=0, y=0}, --- @setting offset The position offset to apply to afk belts
locations={ --- @setting locations The locations to spawn afk belts at, given as the top left position
{-5,-5}, {5,-5},
{-5,5}, {5,5}
}
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to afk belts
locations = { --- @setting locations The locations to spawn afk belts at, given as the top left position
{ -5, -5 }, { 5, -5 },
{ -5, 5 }, { 5, 5 },
},
},
water = { --- @setting water Settings relating to adding water to spawn
enabled = true, --- @setting enabled Whether water tiles will be added to spawn
water_tile = 'water-mud', --- @setting water_tile The tile to be used as the water tile
offset = {x=0, y=0}, --- @setting offset The position offset to apply to water tiles
water_tile = "water-mud", --- @setting water_tile The tile to be used as the water tile
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to water tiles
locations = { --- @setting locations The location of the water tiles {x,y}
-- Each is a 3x3 with the closest tile to 0,0 removed
{7,8}, {7,9}, {8,7}, {8,8}, {8,9}, {9,7}, {9,8}, {9,9}, -- Bottom Right
{7,-9}, {7,-10}, {8,-8}, {8,-9}, {8,-10}, {9,-8}, { 9,-9}, {9,-10}, -- Top Right
{-8,-9}, {-8,-10}, {-9,-8}, {-9,-9}, {-9,-10}, {-10,-8}, {-10,-9}, {-10,-10}, -- Top Left
{-8,8}, {-8,9}, {-9,7}, {-9,8}, {-9,9}, {-10,7}, {-10,8}, {-10,9}, -- Bottom Left
}
{ 7, 8 }, { 7, 9 }, { 8, 7 }, { 8, 8 }, { 8, 9 }, { 9, 7 }, { 9, 8 }, { 9, 9 }, -- Bottom Right
{ 7, -9 }, { 7, -10 }, { 8, -8 }, { 8, -9 }, { 8, -10 }, { 9, -8 }, { 9, -9 }, { 9, -10 }, -- Top Right
{ -8, -9 }, { -8, -10 }, { -9, -8 }, { -9, -9 }, { -9, -10 }, { -10, -8 }, { -10, -9 }, { -10, -10 }, -- Top Left
{ -8, 8 }, { -8, 9 }, { -9, 7 }, { -9, 8 }, { -9, 9 }, { -10, 7 }, { -10, 8 }, { -10, 9 }, -- Bottom Left
},
},
entities = { --- @setting entities Settings relating to adding entities to spawn
enabled = true, --- @setting enabled Whether entities will be added to spawn
enabled = true, --- @setting enabled Whether entities will be added to spawn
protected = true, --- @setting protected Whether entities will be protected from player interaction
operable = true, --- @setting operable Whether entities can be opened by players, must be true if chests are used
offset = {x=0, y=-2}, --- @setting offset The position offset to apply to entities
offset = { x = 0, y = -2 }, --- @setting offset The position offset to apply to entities
locations = { --- @setting locations The location and names of entities {name,x,y}
{'stone-wall',-10,-5},{'stone-wall',-10,-4},{'stone-wall',-10,-3},{'stone-wall',-10,-2},{'stone-wall',-10,-1},{'stone-wall',-10,0},{'stone-wall',-10,3},{'stone-wall',-10,4},{'stone-wall',-10,5},
{'stone-wall',-10,6},{'stone-wall',-10,7},{'stone-wall',-10,8},{'small-lamp',-8,-4},{'small-lamp',-8,-1},{'iron-chest',-8,0},{'iron-chest',-8,3},{'small-lamp',-8,4},
{'small-lamp',-8,7},{'stone-wall',-7,-8},{'small-electric-pole',-7,-2},{'iron-chest',-7,0},{'iron-chest',-7,3},{'small-electric-pole',-7,5},{'stone-wall',-7,11},{'stone-wall',-6,-8},{'small-lamp',-6,-6},
{'iron-chest',-6,0},{'iron-chest',-6,3},{'small-lamp',-6,9},{'stone-wall',-6,11},{'stone-wall',-5,-8},{'small-lamp',-5,-1},{'iron-chest',-5,0},{'iron-chest',-5,3},{'small-lamp',-5,4},{'stone-wall',-5,11},
{'stone-wall',-4,-8},{'small-electric-pole',-4,-5},{'iron-chest',-4,0},{'iron-chest',-4,3},{'small-electric-pole',-4,8},{'stone-wall',-4,11},{'stone-wall',-3,-8},{'small-lamp',-3,-6},{'small-lamp',-3,-3},{'small-lamp',-3,6},
{'small-lamp',-3,9},{'stone-wall',-3,11},{'stone-wall',-2,-8},{'iron-chest',-2,-6},{'iron-chest',-2,-5},{'iron-chest',-2,-4},{'iron-chest',-2,-3},{'iron-chest',-2,-2},{'iron-chest',-2,5},{'iron-chest',-2,6},
{'iron-chest',-2,7},{'iron-chest',-2,8},{'iron-chest',-2,9},{'stone-wall',-2,11},{'stone-wall',1,-8},{'iron-chest',1,-6},
{'iron-chest',1,-5},{'iron-chest',1,-4},{'iron-chest',1,-3},{'iron-chest',1,-2},{'iron-chest',1,5},{'iron-chest',1,6},{'iron-chest',1,7},{'iron-chest',1,8},{'iron-chest',1,9},{'stone-wall',1,11},
{'stone-wall',2,-8},{'small-lamp',2,-6},{'small-lamp',2,-3},{'small-lamp',2,6},{'small-lamp',2,9},{'stone-wall',2,11},{'stone-wall',3,-8},{'small-electric-pole',3,-5},{'iron-chest',3,0},{'iron-chest',3,3},
{'small-electric-pole',3,8},{'stone-wall',3,11},{'stone-wall',4,-8},{'small-lamp',4,-1},{'iron-chest',4,0},{'iron-chest',4,3},{'small-lamp',4,4},{'stone-wall',4,11},{'stone-wall',5,-8},{'small-lamp',5,-6},
{'iron-chest',5,0},{'iron-chest',5,3},{'small-lamp',5,9},{'stone-wall',5,11},{'stone-wall',6,-8},{'small-electric-pole',6,-2},{'iron-chest',6,0},{'iron-chest',6,3},{'small-electric-pole',6,5},{'stone-wall',6,11},
{'small-lamp',7,-4},{'small-lamp',7,-1},{'iron-chest',7,0},{'iron-chest',7,3},{'small-lamp',7,4},{'small-lamp',7,7},{'stone-wall',9,-5},
{'stone-wall',9,-4},{'stone-wall',9,-3},{'stone-wall',9,-2},{'stone-wall',9,-1},{'stone-wall',9,0},{'stone-wall',9,3},{'stone-wall',9,4},{'stone-wall',9,5},{'stone-wall',9,6},{'stone-wall',9,7},
{'stone-wall',9,8}
}
{ "stone-wall", -10, -5 }, { "stone-wall", -10, -4 }, { "stone-wall", -10, -3 }, { "stone-wall", -10, -2 }, { "stone-wall", -10, -1 }, { "stone-wall", -10, 0 }, { "stone-wall", -10, 3 }, { "stone-wall", -10, 4 }, { "stone-wall", -10, 5 },
{ "stone-wall", -10, 6 }, { "stone-wall", -10, 7 }, { "stone-wall", -10, 8 }, { "small-lamp", -8, -4 }, { "small-lamp", -8, -1 }, { "iron-chest", -8, 0 }, { "iron-chest", -8, 3 }, { "small-lamp", -8, 4 },
{ "small-lamp", -8, 7 }, { "stone-wall", -7, -8 }, { "small-electric-pole", -7, -2 }, { "iron-chest", -7, 0 }, { "iron-chest", -7, 3 }, { "small-electric-pole", -7, 5 }, { "stone-wall", -7, 11 }, { "stone-wall", -6, -8 }, { "small-lamp", -6, -6 },
{ "iron-chest", -6, 0 }, { "iron-chest", -6, 3 }, { "small-lamp", -6, 9 }, { "stone-wall", -6, 11 }, { "stone-wall", -5, -8 }, { "small-lamp", -5, -1 }, { "iron-chest", -5, 0 }, { "iron-chest", -5, 3 }, { "small-lamp", -5, 4 }, { "stone-wall", -5, 11 },
{ "stone-wall", -4, -8 }, { "small-electric-pole", -4, -5 }, { "iron-chest", -4, 0 }, { "iron-chest", -4, 3 }, { "small-electric-pole", -4, 8 }, { "stone-wall", -4, 11 }, { "stone-wall", -3, -8 }, { "small-lamp", -3, -6 }, { "small-lamp", -3, -3 }, { "small-lamp", -3, 6 },
{ "small-lamp", -3, 9 }, { "stone-wall", -3, 11 }, { "stone-wall", -2, -8 }, { "iron-chest", -2, -6 }, { "iron-chest", -2, -5 }, { "iron-chest", -2, -4 }, { "iron-chest", -2, -3 }, { "iron-chest", -2, -2 }, { "iron-chest", -2, 5 }, { "iron-chest", -2, 6 },
{ "iron-chest", -2, 7 }, { "iron-chest", -2, 8 }, { "iron-chest", -2, 9 }, { "stone-wall", -2, 11 }, { "stone-wall", 1, -8 }, { "iron-chest", 1, -6 },
{ "iron-chest", 1, -5 }, { "iron-chest", 1, -4 }, { "iron-chest", 1, -3 }, { "iron-chest", 1, -2 }, { "iron-chest", 1, 5 }, { "iron-chest", 1, 6 }, { "iron-chest", 1, 7 }, { "iron-chest", 1, 8 }, { "iron-chest", 1, 9 }, { "stone-wall", 1, 11 },
{ "stone-wall", 2, -8 }, { "small-lamp", 2, -6 }, { "small-lamp", 2, -3 }, { "small-lamp", 2, 6 }, { "small-lamp", 2, 9 }, { "stone-wall", 2, 11 }, { "stone-wall", 3, -8 }, { "small-electric-pole", 3, -5 }, { "iron-chest", 3, 0 }, { "iron-chest", 3, 3 },
{ "small-electric-pole", 3, 8 }, { "stone-wall", 3, 11 }, { "stone-wall", 4, -8 }, { "small-lamp", 4, -1 }, { "iron-chest", 4, 0 }, { "iron-chest", 4, 3 }, { "small-lamp", 4, 4 }, { "stone-wall", 4, 11 }, { "stone-wall", 5, -8 }, { "small-lamp", 5, -6 },
{ "iron-chest", 5, 0 }, { "iron-chest", 5, 3 }, { "small-lamp", 5, 9 }, { "stone-wall", 5, 11 }, { "stone-wall", 6, -8 }, { "small-electric-pole", 6, -2 }, { "iron-chest", 6, 0 }, { "iron-chest", 6, 3 }, { "small-electric-pole", 6, 5 }, { "stone-wall", 6, 11 },
{ "small-lamp", 7, -4 }, { "small-lamp", 7, -1 }, { "iron-chest", 7, 0 }, { "iron-chest", 7, 3 }, { "small-lamp", 7, 4 }, { "small-lamp", 7, 7 }, { "stone-wall", 9, -5 },
{ "stone-wall", 9, -4 }, { "stone-wall", 9, -3 }, { "stone-wall", 9, -2 }, { "stone-wall", 9, -1 }, { "stone-wall", 9, 0 }, { "stone-wall", 9, 3 }, { "stone-wall", 9, 4 }, { "stone-wall", 9, 5 }, { "stone-wall", 9, 6 }, { "stone-wall", 9, 7 },
{ "stone-wall", 9, 8 },
},
},
pattern = {
enabled = true, --- @setting enabled Whether pattern tiles will be added to spawn
pattern_tile = 'stone-path', --- @setting pattern_tile The tile to be used for the pattern
offset = {x=0, y=-2}, --- @setting offset The position offset to apply to pattern tiles
pattern_tile = "stone-path", --- @setting pattern_tile The tile to be used for the pattern
offset = { x = 0, y = -2 }, --- @setting offset The position offset to apply to pattern tiles
locations = { --- @setting locations The location of the pattern tiles {x,y}
{-49,-3},{-49,-2},{-49,1},{-49,2},{-49,5},{-49,6},{-48,-4},{-48,-3},{-48,-2},{-48,1},{-48,2},{-48,5},{-48,6},{-48,7},{-47,-7},{-47,-6},{-47,-5},{-47,-4},{-47,-3},{-47,-2},{-47,5},{-47,6},{-47,7},{-47,8},{-47,9},{-47,10},{-46,-8},{-46,-7},{-46,-6},{-46,-5},
{-46,-4},{-46,-3},{-46,-2},{-46,-1},{-46,4},{-46,5},{-46,6},{-46,7},{-46,8},{-46,9},{-46,10},{-46,11},{-45,-17},{-45,-16},{-45,-15},{-45,-14},{-45,-13},{-45,-12},{-45,-9},{-45,-8},{-45,-7},{-45,-2},{-45,-1},{-45,0},{-45,1},{-45,2},{-45,3},{-45,4},{-45,5},{-45,10},
{-45,11},{-45,12},{-45,15},{-45,16},{-45,17},{-45,18},{-45,19},{-45,20},{-44,-18},{-44,-17},{-44,-16},{-44,-15},{-44,-14},{-44,-13},{-44,-12},{-44,-9},{-44,-8},{-44,-1},{-44,0},{-44,1},{-44,2},{-44,3},{-44,4},{-44,11},{-44,12},{-44,15},{-44,16},{-44,17},{-44,18},{-44,19},
{-44,20},{-44,21},{-43,-19},{-43,-18},{-43,-17},{-43,-1},{-43,0},{-43,1},{-43,2},{-43,3},{-43,4},{-43,20},{-43,21},{-43,22},{-42,-19},{-42,-18},{-42,-1},{-42,0},{-42,1},{-42,2},{-42,3},{-42,4},{-42,21},{-42,22},{-41,-25},{-41,-24},{-41,-19},{-41,-18},{-41,-13},{-41,-12},
{-41,-11},{-41,-10},{-41,-5},{-41,-4},{-41,7},{-41,8},{-41,13},{-41,14},{-41,15},{-41,16},{-41,21},{-41,22},{-41,27},{-41,28},{-40,-26},{-40,-25},{-40,-24},{-40,-20},{-40,-19},{-40,-18},{-40,-13},{-40,-12},{-40,-11},{-40,-10},{-40,-5},{-40,-4},{-40,7},{-40,8},{-40,13},{-40,14},
{-40,15},{-40,16},{-40,21},{-40,22},{-40,23},{-40,27},{-40,28},{-40,29},{-39,-27},{-39,-26},{-39,-25},{-39,-24},{-39,-21},{-39,-20},{-39,-19},{-39,-13},{-39,-12},{-39,-5},{-39,-4},{-39,-3},{-39,-2},{-39,-1},{-39,0},{-39,1},{-39,2},{-39,3},{-39,4},{-39,5},{-39,6},{-39,7},
{-39,8},{-39,15},{-39,16},{-39,22},{-39,23},{-39,24},{-39,27},{-39,28},{-39,29},{-39,30},{-38,-27},{-38,-26},{-38,-25},{-38,-24},{-38,-21},{-38,-20},{-38,-13},{-38,-12},{-38,-5},{-38,-4},{-38,-3},{-38,-2},{-38,-1},{-38,0},{-38,1},{-38,2},{-38,3},{-38,4},{-38,5},{-38,6},
{-38,7},{-38,8},{-38,15},{-38,16},{-38,23},{-38,24},{-38,27},{-38,28},{-38,29},{-38,30},{-37,-17},{-37,-16},{-37,-13},{-37,-12},{-37,-11},{-37,-10},{-37,-4},{-37,-3},{-37,-2},{-37,-1},{-37,0},{-37,3},{-37,4},{-37,5},{-37,6},{-37,7},{-37,13},{-37,14},{-37,15},{-37,16},
{-37,19},{-37,20},{-36,-17},{-36,-16},{-36,-13},{-36,-12},{-36,-11},{-36,-10},{-36,-9},{-36,-3},{-36,-2},{-36,-1},{-36,0},{-36,3},{-36,4},{-36,5},{-36,6},{-36,12},{-36,13},{-36,14},{-36,15},{-36,16},{-36,19},{-36,20},{-35,-29},{-35,-28},{-35,-23},{-35,-22},{-35,-17},{-35,-16},
{-35,-12},{-35,-11},{-35,-10},{-35,-9},{-35,-8},{-35,11},{-35,12},{-35,13},{-35,14},{-35,15},{-35,19},{-35,20},{-35,25},{-35,26},{-35,31},{-35,32},{-34,-30},{-34,-29},{-34,-28},{-34,-23},{-34,-22},{-34,-17},{-34,-16},{-34,-15},{-34,-11},{-34,-10},{-34,-9},{-34,-8},{-34,11},{-34,12},
{-34,13},{-34,14},{-34,18},{-34,19},{-34,20},{-34,25},{-34,26},{-34,31},{-34,32},{-34,33},{-33,-31},{-33,-30},{-33,-29},{-33,-28},{-33,-23},{-33,-22},{-33,-16},{-33,-15},{-33,-14},{-33,-5},{-33,-4},{-33,-1},{-33,0},{-33,3},{-33,4},{-33,7},{-33,8},{-33,17},{-33,18},{-33,19},
{-33,25},{-33,26},{-33,31},{-33,32},{-33,33},{-33,34},{-32,-32},{-32,-31},{-32,-30},{-32,-29},{-32,-28},{-32,-27},{-32,-23},{-32,-22},{-32,-21},{-32,-15},{-32,-14},{-32,-6},{-32,-5},{-32,-4},{-32,-1},{-32,0},{-32,3},{-32,4},{-32,7},{-32,8},{-32,9},{-32,17},{-32,18},{-32,24},
{-32,25},{-32,26},{-32,30},{-32,31},{-32,32},{-32,33},{-32,34},{-32,35},{-31,-33},{-31,-32},{-31,-31},{-31,-30},{-31,-29},{-31,-28},{-31,-27},{-31,-26},{-31,-22},{-31,-21},{-31,-20},{-31,-19},{-31,-18},{-31,-11},{-31,-10},{-31,-9},{-31,-8},{-31,-7},{-31,-6},{-31,-5},{-31,-1},{-31,0},
{-31,1},{-31,2},{-31,3},{-31,4},{-31,8},{-31,9},{-31,10},{-31,11},{-31,12},{-31,13},{-31,14},{-31,21},{-31,22},{-31,23},{-31,24},{-31,25},{-31,29},{-31,30},{-31,31},{-31,32},{-31,33},{-31,34},{-31,35},{-31,36},{-30,-33},{-30,-32},{-30,-31},{-30,-30},{-30,-29},{-30,-28},
{-30,-27},{-30,-26},{-30,-21},{-30,-20},{-30,-19},{-30,-18},{-30,-11},{-30,-10},{-30,-9},{-30,-8},{-30,-7},{-30,-6},{-30,-1},{-30,0},{-30,1},{-30,2},{-30,3},{-30,4},{-30,9},{-30,10},{-30,11},{-30,12},{-30,13},{-30,14},{-30,21},{-30,22},{-30,23},{-30,24},{-30,29},{-30,30},
{-30,31},{-30,32},{-30,33},{-30,34},{-30,35},{-30,36},{-29,-37},{-29,-36},{-29,-30},{-29,-29},{-29,-28},{-29,-27},{-29,-26},{-29,-15},{-29,-14},{-29,-10},{-29,-9},{-29,-8},{-29,-7},{-29,10},{-29,11},{-29,12},{-29,13},{-29,17},{-29,18},{-29,29},{-29,30},{-29,31},{-29,32},{-29,33},
{-29,39},{-29,40},{-28,-38},{-28,-37},{-28,-36},{-28,-29},{-28,-28},{-28,-27},{-28,-26},{-28,-16},{-28,-15},{-28,-14},{-28,-9},{-28,-8},{-28,11},{-28,12},{-28,17},{-28,18},{-28,19},{-28,29},{-28,30},{-28,31},{-28,32},{-28,39},{-28,40},{-28,41},{-27,-39},{-27,-38},{-27,-37},{-27,-36},
{-27,-23},{-27,-22},{-27,-19},{-27,-18},{-27,-17},{-27,-16},{-27,-15},{-27,-5},{-27,-4},{-27,-1},{-27,0},{-27,1},{-27,2},{-27,3},{-27,4},{-27,7},{-27,8},{-27,18},{-27,19},{-27,20},{-27,21},{-27,22},{-27,25},{-27,26},{-27,39},{-27,40},{-27,41},{-27,42},{-26,-39},{-26,-38},
{-26,-37},{-26,-36},{-26,-24},{-26,-23},{-26,-22},{-26,-19},{-26,-18},{-26,-17},{-26,-16},{-26,-6},{-26,-5},{-26,-4},{-26,-1},{-26,0},{-26,1},{-26,2},{-26,3},{-26,4},{-26,7},{-26,8},{-26,9},{-26,19},{-26,20},{-26,21},{-26,22},{-26,25},{-26,26},{-26,27},{-26,39},{-26,40},
{-26,41},{-26,42},{-25,-33},{-25,-32},{-25,-31},{-25,-30},{-25,-25},{-25,-24},{-25,-23},{-25,-22},{-25,-19},{-25,-18},{-25,-17},{-25,-9},{-25,-8},{-25,-7},{-25,-6},{-25,-5},{-25,-4},{-25,-1},{-25,0},{-25,1},{-25,2},{-25,3},{-25,4},{-25,7},{-25,8},{-25,9},{-25,10},{-25,11},
{-25,12},{-25,20},{-25,21},{-25,22},{-25,25},{-25,26},{-25,27},{-25,28},{-25,33},{-25,34},{-25,35},{-25,36},{-24,-33},{-24,-32},{-24,-31},{-24,-30},{-24,-29},{-24,-25},{-24,-24},{-24,-23},{-24,-22},{-24,-19},{-24,-18},{-24,-9},{-24,-8},{-24,-7},{-24,-6},{-24,-5},{-24,-4},{-24,-1},
{-24,0},{-24,1},{-24,2},{-24,3},{-24,4},{-24,7},{-24,8},{-24,9},{-24,10},{-24,11},{-24,12},{-24,21},{-24,22},{-24,25},{-24,26},{-24,27},{-24,28},{-24,32},{-24,33},{-24,34},{-24,35},{-24,36},{-23,-37},{-23,-36},{-23,-30},{-23,-29},{-23,-28},{-23,-19},{-23,-18},{-23,-15},
{-23,-14},{-23,-9},{-23,-8},{-23,-7},{-23,-6},{-23,-5},{-23,0},{-23,1},{-23,2},{-23,3},{-23,8},{-23,9},{-23,10},{-23,11},{-23,12},{-23,17},{-23,18},{-23,21},{-23,22},{-23,31},{-23,32},{-23,33},{-23,39},{-23,40},{-22,-38},{-22,-37},{-22,-36},{-22,-29},{-22,-28},{-22,-19},
{-22,-18},{-22,-15},{-22,-14},{-22,-13},{-22,-9},{-22,-8},{-22,-7},{-22,-6},{-22,1},{-22,2},{-22,9},{-22,10},{-22,11},{-22,12},{-22,16},{-22,17},{-22,18},{-22,21},{-22,22},{-22,31},{-22,32},{-22,39},{-22,40},{-22,41},{-21,-41},{-21,-40},{-21,-39},{-21,-38},{-21,-37},{-21,-29},
{-21,-28},{-21,-25},{-21,-24},{-21,-23},{-21,-22},{-21,-21},{-21,-20},{-21,-19},{-21,-18},{-21,-15},{-21,-14},{-21,-13},{-21,-12},{-21,-3},{-21,-2},{-21,5},{-21,6},{-21,15},{-21,16},{-21,17},{-21,18},{-21,21},{-21,22},{-21,23},{-21,24},{-21,25},{-21,26},{-21,27},{-21,28},{-21,31},
{-21,32},{-21,40},{-21,41},{-21,42},{-21,43},{-21,44},{-20,-42},{-20,-41},{-20,-40},{-20,-39},{-20,-38},{-20,-29},{-20,-28},{-20,-25},{-20,-24},{-20,-23},{-20,-22},{-20,-21},{-20,-20},{-20,-19},{-20,-18},{-20,-15},{-20,-14},{-20,-13},{-20,-12},{-20,-3},{-20,-2},{-20,-1},{-20,4},{-20,5},
{-20,6},{-20,15},{-20,16},{-20,17},{-20,18},{-20,21},{-20,22},{-20,23},{-20,24},{-20,25},{-20,26},{-20,27},{-20,28},{-20,31},{-20,32},{-20,41},{-20,42},{-20,43},{-20,44},{-20,45},{-19,-43},{-19,-42},{-19,-41},{-19,-35},{-19,-34},{-19,-33},{-19,-32},{-19,-25},{-19,-24},{-19,-23},
{-19,-15},{-19,-14},{-19,-13},{-19,-9},{-19,-8},{-19,-7},{-19,-6},{-19,-2},{-19,-1},{-19,0},{-19,1},{-19,2},{-19,3},{-19,4},{-19,5},{-19,9},{-19,10},{-19,11},{-19,12},{-19,16},{-19,17},{-19,18},{-19,26},{-19,27},{-19,28},{-19,35},{-19,36},{-19,37},{-19,38},{-19,44},
{-19,45},{-19,46},{-18,-43},{-18,-42},{-18,-35},{-18,-34},{-18,-33},{-18,-32},{-18,-31},{-18,-26},{-18,-25},{-18,-24},{-18,-15},{-18,-14},{-18,-10},{-18,-9},{-18,-8},{-18,-7},{-18,-6},{-18,-1},{-18,0},{-18,1},{-18,2},{-18,3},{-18,4},{-18,9},{-18,10},{-18,11},{-18,12},{-18,13},
{-18,17},{-18,18},{-18,27},{-18,28},{-18,29},{-18,34},{-18,35},{-18,36},{-18,37},{-18,38},{-18,45},{-18,46},{-17,-43},{-17,-42},{-17,-32},{-17,-31},{-17,-30},{-17,-27},{-17,-26},{-17,-25},{-17,-21},{-17,-20},{-17,-19},{-17,-18},{-17,-17},{-17,-16},{-17,-15},{-17,-14},{-17,-11},{-17,-10},
{-17,-9},{-17,-8},{-17,-7},{-17,-6},{-17,0},{-17,1},{-17,2},{-17,3},{-17,9},{-17,10},{-17,11},{-17,12},{-17,13},{-17,14},{-17,17},{-17,18},{-17,19},{-17,20},{-17,21},{-17,22},{-17,23},{-17,24},{-17,28},{-17,29},{-17,30},{-17,33},{-17,34},{-17,35},{-17,45},{-17,46},
{-16,-43},{-16,-42},{-16,-31},{-16,-30},{-16,-27},{-16,-26},{-16,-21},{-16,-20},{-16,-19},{-16,-18},{-16,-17},{-16,-16},{-16,-15},{-16,-14},{-16,-11},{-16,-10},{-16,-9},{-16,-8},{-16,-7},{-16,-6},{-16,1},{-16,2},{-16,9},{-16,10},{-16,11},{-16,12},{-16,13},{-16,14},{-16,17},{-16,18},
{-16,19},{-16,20},{-16,21},{-16,22},{-16,23},{-16,24},{-16,29},{-16,30},{-16,33},{-16,34},{-16,45},{-16,46},{-15,-43},{-15,-42},{-15,-39},{-15,-38},{-15,-37},{-15,-36},{-15,-35},{-15,-34},{-15,-20},{-15,-19},{-15,-18},{-15,-17},{-15,-10},{-15,-9},{-15,-8},{-15,-7},{-15,-3},{-15,-2},
{-15,1},{-15,2},{-15,5},{-15,6},{-15,10},{-15,11},{-15,12},{-15,13},{-15,20},{-15,21},{-15,22},{-15,23},{-15,37},{-15,38},{-15,39},{-15,40},{-15,41},{-15,42},{-15,45},{-15,46},{-14,-43},{-14,-42},{-14,-39},{-14,-38},{-14,-37},{-14,-36},{-14,-35},{-14,-34},{-14,-33},{-14,-19},
{-14,-18},{-14,-9},{-14,-8},{-14,-4},{-14,-3},{-14,-2},{-14,1},{-14,2},{-14,5},{-14,6},{-14,7},{-14,11},{-14,12},{-14,21},{-14,22},{-14,36},{-14,37},{-14,38},{-14,39},{-14,40},{-14,41},{-14,42},{-14,45},{-14,46},{-13,-39},{-13,-38},{-13,-35},{-13,-34},{-13,-33},{-13,-32},
{-13,-29},{-13,-28},{-13,-15},{-13,-14},{-13,-5},{-13,-4},{-13,-3},{-13,-2},{-13,5},{-13,6},{-13,7},{-13,8},{-13,17},{-13,18},{-13,31},{-13,32},{-13,35},{-13,36},{-13,37},{-13,38},{-13,41},{-13,42},{-12,-39},{-12,-38},{-12,-35},{-12,-34},{-12,-33},{-12,-32},{-12,-29},{-12,-28},
{-12,-27},{-12,-16},{-12,-15},{-12,-14},{-12,-13},{-12,-5},{-12,-4},{-12,-3},{-12,-2},{-12,5},{-12,6},{-12,7},{-12,8},{-12,16},{-12,17},{-12,18},{-12,19},{-12,30},{-12,31},{-12,32},{-12,35},{-12,36},{-12,37},{-12,38},{-12,41},{-12,42},{-11,-43},{-11,-42},{-11,-34},{-11,-33},
{-11,-32},{-11,-29},{-11,-28},{-11,-27},{-11,-26},{-11,-23},{-11,-22},{-11,-21},{-11,-20},{-11,-17},{-11,-16},{-11,-15},{-11,-14},{-11,-13},{-11,-12},{-11,-9},{-11,-8},{-11,1},{-11,2},{-11,11},{-11,12},{-11,15},{-11,16},{-11,17},{-11,18},{-11,19},{-11,20},{-11,23},{-11,24},{-11,25},
{-11,26},{-11,29},{-11,30},{-11,31},{-11,32},{-11,35},{-11,36},{-11,37},{-11,45},{-11,46},{-10,-44},{-10,-43},{-10,-42},{-10,-33},{-10,-32},{-10,-29},{-10,-28},{-10,-27},{-10,-26},{-10,-23},{-10,-22},{-10,-21},{-10,-20},{-10,-17},{-10,-16},{-10,-15},{-10,-14},{-10,-13},{-10,-12},{-10,-9},
{-10,-8},{-10,-7},{-10,0},{-10,1},{-10,2},{-10,3},{-10,10},{-10,11},{-10,12},{-10,15},{-10,16},{-10,17},{-10,18},{-10,19},{-10,20},{-10,23},{-10,24},{-10,25},{-10,26},{-10,29},{-10,30},{-10,31},{-10,32},{-10,35},{-10,36},{-10,45},{-10,46},{-10,47},{-9,-45},{-9,-44},
{-9,-43},{-9,-29},{-9,-28},{-9,-27},{-9,-23},{-9,-22},{-9,-21},{-9,-20},{-9,-17},{-9,-16},{-9,-15},{-9,-14},{-9,-13},{-9,-8},{-9,-7},{-9,-6},{-9,-5},{-9,-1},{-9,0},{-9,1},{-9,2},{-9,3},{-9,4},{-9,8},{-9,9},{-9,10},{-9,11},{-9,16},{-9,17},{-9,18},
{-9,19},{-9,20},{-9,23},{-9,24},{-9,25},{-9,26},{-9,30},{-9,31},{-9,32},{-9,46},{-9,47},{-9,48},{-8,-45},{-8,-44},{-8,-30},{-8,-29},{-8,-28},{-8,-24},{-8,-23},{-8,-22},{-8,-21},{-8,-20},{-8,-17},{-8,-16},{-8,-15},{-8,-14},{-8,-7},{-8,-6},{-8,-5},{-8,-4},
{-8,-1},{-8,0},{-8,1},{-8,2},{-8,3},{-8,4},{-8,7},{-8,8},{-8,9},{-8,10},{-8,17},{-8,18},{-8,19},{-8,20},{-8,23},{-8,24},{-8,25},{-8,26},{-8,27},{-8,31},{-8,32},{-8,33},{-8,47},{-8,48},{-7,-45},{-7,-44},{-7,-39},{-7,-38},{-7,-37},{-7,-36},
{-7,-31},{-7,-30},{-7,-29},{-7,-25},{-7,-24},{-7,-23},{-7,-22},{-7,-21},{-7,-11},{-7,-10},{-7,-7},{-7,-6},{-7,-5},{-7,-4},{-7,7},{-7,8},{-7,9},{-7,10},{-7,13},{-7,14},{-7,24},{-7,25},{-7,26},{-7,27},{-7,28},{-7,32},{-7,33},{-7,34},{-7,39},{-7,40},
{-7,41},{-7,42},{-7,47},{-7,48},{-6,-46},{-6,-45},{-6,-44},{-6,-39},{-6,-38},{-6,-37},{-6,-36},{-6,-35},{-6,-31},{-6,-30},{-6,-25},{-6,-24},{-6,-23},{-6,-22},{-6,-12},{-6,-11},{-6,-10},{-6,-6},{-6,-5},{-6,8},{-6,9},{-6,13},{-6,14},{-6,15},{-6,25},{-6,26},
{-6,27},{-6,28},{-6,33},{-6,34},{-6,38},{-6,39},{-6,40},{-6,41},{-6,42},{-6,47},{-6,48},{-6,49},{-5,-47},{-5,-46},{-5,-45},{-5,-44},{-5,-37},{-5,-36},{-5,-35},{-5,-34},{-5,-19},{-5,-18},{-5,-13},{-5,-12},{-5,-11},{-5,-10},{-5,-1},{-5,0},{-5,1},{-5,2},
{-5,3},{-5,4},{-5,13},{-5,14},{-5,15},{-5,16},{-5,21},{-5,22},{-5,37},{-5,38},{-5,39},{-5,40},{-5,47},{-5,48},{-5,49},{-5,50},{-4,-47},{-4,-46},{-4,-45},{-4,-44},{-4,-43},{-4,-37},{-4,-36},{-4,-35},{-4,-34},{-4,-19},{-4,-18},{-4,-17},{-4,-13},{-4,-12},
{-4,-11},{-4,-10},{-4,-2},{-4,-1},{-4,0},{-4,1},{-4,2},{-4,3},{-4,4},{-4,5},{-4,13},{-4,14},{-4,15},{-4,16},{-4,20},{-4,21},{-4,22},{-4,37},{-4,38},{-4,39},{-4,40},{-4,46},{-4,47},{-4,48},{-4,49},{-4,50},{-3,-44},{-3,-43},{-3,-42},{-3,-41},
{-3,-40},{-3,-37},{-3,-36},{-3,-35},{-3,-34},{-3,-31},{-3,-30},{-3,-29},{-3,-28},{-3,-25},{-3,-24},{-3,-23},{-3,-22},{-3,-18},{-3,-17},{-3,-16},{-3,-7},{-3,-6},{-3,-3},{-3,-2},{-3,-1},{-3,0},{-3,3},{-3,4},{-3,5},{-3,6},{-3,9},{-3,10},{-3,19},{-3,20},
{-3,21},{-3,25},{-3,26},{-3,27},{-3,28},{-3,31},{-3,32},{-3,33},{-3,34},{-3,37},{-3,38},{-3,39},{-3,40},{-3,43},{-3,44},{-3,45},{-3,46},{-3,47},{-2,-43},{-2,-42},{-2,-41},{-2,-40},{-2,-37},{-2,-36},{-2,-35},{-2,-34},{-2,-31},{-2,-30},{-2,-29},{-2,-28},
{-2,-25},{-2,-24},{-2,-23},{-2,-22},{-2,-21},{-2,-17},{-2,-16},{-2,-15},{-2,-8},{-2,-7},{-2,-6},{-2,-3},{-2,-2},{-2,-1},{-2,0},{-2,3},{-2,4},{-2,5},{-2,6},{-2,9},{-2,10},{-2,11},{-2,18},{-2,19},{-2,20},{-2,24},{-2,25},{-2,26},{-2,27},{-2,28},
{-2,31},{-2,32},{-2,33},{-2,34},{-2,37},{-2,38},{-2,39},{-2,40},{-2,43},{-2,44},{-2,45},{-2,46},{-1,-47},{-1,-46},{-1,-43},{-1,-42},{-1,-41},{-1,-40},{-1,-37},{-1,-36},{-1,-29},{-1,-28},{-1,-25},{-1,-24},{-1,-23},{-1,-22},{-1,-21},{-1,-20},{-1,-17},{-1,-16},
{-1,-15},{-1,-14},{-1,-13},{-1,-12},{-1,-9},{-1,-8},{-1,-7},{-1,-6},{-1,-3},{-1,-2},{-1,5},{-1,6},{-1,9},{-1,10},{-1,11},{-1,12},{-1,15},{-1,16},{-1,17},{-1,18},{-1,19},{-1,20},{-1,23},{-1,24},{-1,25},{-1,26},{-1,27},{-1,28},{-1,31},{-1,32},
{-1,39},{-1,40},{-1,43},{-1,44},{-1,45},{-1,46},{-1,49},{-1,50},{0,-47},{0,-46},{0,-43},{0,-42},{0,-41},{0,-40},{0,-37},{0,-36},{0,-29},{0,-28},{0,-25},{0,-24},{0,-23},{0,-22},{0,-21},{0,-20},{0,-17},{0,-16},{0,-15},{0,-14},{0,-13},{0,-12},
{0,-9},{0,-8},{0,-7},{0,-6},{0,-3},{0,-2},{0,5},{0,6},{0,9},{0,10},{0,11},{0,12},{0,15},{0,16},{0,17},{0,18},{0,19},{0,20},{0,23},{0,24},{0,25},{0,26},{0,27},{0,28},{0,31},{0,32},{0,39},{0,40},{0,43},{0,44},
{0,45},{0,46},{0,49},{0,50},{1,-43},{1,-42},{1,-41},{1,-40},{1,-37},{1,-36},{1,-35},{1,-34},{1,-31},{1,-30},{1,-29},{1,-28},{1,-25},{1,-24},{1,-23},{1,-22},{1,-21},{1,-17},{1,-16},{1,-15},{1,-8},{1,-7},{1,-6},{1,-3},{1,-2},{1,-1},
{1,0},{1,3},{1,4},{1,5},{1,6},{1,9},{1,10},{1,11},{1,18},{1,19},{1,20},{1,24},{1,25},{1,26},{1,27},{1,28},{1,31},{1,32},{1,33},{1,34},{1,37},{1,38},{1,39},{1,40},{1,43},{1,44},{1,45},{1,46},{2,-44},{2,-43},
{2,-42},{2,-41},{2,-40},{2,-37},{2,-36},{2,-35},{2,-34},{2,-31},{2,-30},{2,-29},{2,-28},{2,-25},{2,-24},{2,-23},{2,-22},{2,-18},{2,-17},{2,-16},{2,-7},{2,-6},{2,-3},{2,-2},{2,-1},{2,0},{2,3},{2,4},{2,5},{2,6},{2,9},{2,10},
{2,19},{2,20},{2,21},{2,25},{2,26},{2,27},{2,28},{2,31},{2,32},{2,33},{2,34},{2,37},{2,38},{2,39},{2,40},{2,43},{2,44},{2,45},{2,46},{2,47},{3,-47},{3,-46},{3,-45},{3,-44},{3,-43},{3,-37},{3,-36},{3,-35},{3,-34},{3,-19},
{3,-18},{3,-17},{3,-13},{3,-12},{3,-11},{3,-10},{3,-2},{3,-1},{3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,13},{3,14},{3,15},{3,16},{3,20},{3,21},{3,22},{3,37},{3,38},{3,39},{3,40},{3,46},{3,47},{3,48},{3,49},{3,50},
{4,-47},{4,-46},{4,-45},{4,-44},{4,-37},{4,-36},{4,-35},{4,-34},{4,-19},{4,-18},{4,-13},{4,-12},{4,-11},{4,-10},{4,-1},{4,0},{4,1},{4,2},{4,3},{4,4},{4,13},{4,14},{4,15},{4,16},{4,21},{4,22},{4,37},{4,38},{4,39},{4,40},
{4,47},{4,48},{4,49},{4,50},{5,-46},{5,-45},{5,-44},{5,-39},{5,-38},{5,-37},{5,-36},{5,-35},{5,-31},{5,-30},{5,-25},{5,-24},{5,-23},{5,-22},{5,-12},{5,-11},{5,-10},{5,-6},{5,-5},{5,8},{5,9},{5,13},{5,14},{5,15},{5,25},{5,26},
{5,27},{5,28},{5,33},{5,34},{5,38},{5,39},{5,40},{5,41},{5,42},{5,47},{5,48},{5,49},{6,-45},{6,-44},{6,-39},{6,-38},{6,-37},{6,-36},{6,-31},{6,-30},{6,-29},{6,-25},{6,-24},{6,-23},{6,-22},{6,-21},{6,-11},{6,-10},{6,-7},{6,-6},
{6,-5},{6,-4},{6,7},{6,8},{6,9},{6,10},{6,13},{6,14},{6,24},{6,25},{6,26},{6,27},{6,28},{6,32},{6,33},{6,34},{6,39},{6,40},{6,41},{6,42},{6,47},{6,48},{7,-45},{7,-44},{7,-30},{7,-29},{7,-28},{7,-24},{7,-23},{7,-22},
{7,-21},{7,-20},{7,-17},{7,-16},{7,-15},{7,-14},{7,-7},{7,-6},{7,-5},{7,-4},{7,-1},{7,0},{7,1},{7,2},{7,3},{7,4},{7,7},{7,8},{7,9},{7,10},{7,17},{7,18},{7,19},{7,20},{7,23},{7,24},{7,25},{7,26},{7,27},{7,31},
{7,32},{7,33},{7,47},{7,48},{8,-45},{8,-44},{8,-43},{8,-29},{8,-28},{8,-27},{8,-23},{8,-22},{8,-21},{8,-20},{8,-17},{8,-16},{8,-15},{8,-14},{8,-13},{8,-8},{8,-7},{8,-6},{8,-5},{8,-1},{8,0},{8,1},{8,2},{8,3},{8,4},{8,8},
{8,9},{8,10},{8,11},{8,16},{8,17},{8,18},{8,19},{8,20},{8,23},{8,24},{8,25},{8,26},{8,30},{8,31},{8,32},{8,46},{8,47},{8,48},{9,-44},{9,-43},{9,-42},{9,-33},{9,-32},{9,-29},{9,-28},{9,-27},{9,-26},{9,-23},{9,-22},{9,-21},
{9,-20},{9,-17},{9,-16},{9,-15},{9,-14},{9,-13},{9,-12},{9,-9},{9,-8},{9,-7},{9,0},{9,1},{9,2},{9,3},{9,10},{9,11},{9,12},{9,15},{9,16},{9,17},{9,18},{9,19},{9,20},{9,23},{9,24},{9,25},{9,26},{9,29},{9,30},{9,31},
{9,32},{9,35},{9,36},{9,45},{9,46},{9,47},{10,-43},{10,-42},{10,-34},{10,-33},{10,-32},{10,-29},{10,-28},{10,-27},{10,-26},{10,-23},{10,-22},{10,-21},{10,-20},{10,-17},{10,-16},{10,-15},{10,-14},{10,-13},{10,-12},{10,-9},{10,-8},{10,1},{10,2},{10,11},
{10,12},{10,15},{10,16},{10,17},{10,18},{10,19},{10,20},{10,23},{10,24},{10,25},{10,26},{10,29},{10,30},{10,31},{10,32},{10,35},{10,36},{10,37},{10,45},{10,46},{11,-39},{11,-38},{11,-35},{11,-34},{11,-33},{11,-32},{11,-29},{11,-28},{11,-27},{11,-16},
{11,-15},{11,-14},{11,-13},{11,-5},{11,-4},{11,-3},{11,-2},{11,5},{11,6},{11,7},{11,8},{11,16},{11,17},{11,18},{11,19},{11,30},{11,31},{11,32},{11,35},{11,36},{11,37},{11,38},{11,41},{11,42},{12,-39},{12,-38},{12,-35},{12,-34},{12,-33},{12,-32},
{12,-29},{12,-28},{12,-15},{12,-14},{12,-5},{12,-4},{12,-3},{12,-2},{12,5},{12,6},{12,7},{12,8},{12,17},{12,18},{12,31},{12,32},{12,35},{12,36},{12,37},{12,38},{12,41},{12,42},{13,-43},{13,-42},{13,-39},{13,-38},{13,-37},{13,-36},{13,-35},{13,-34},
{13,-33},{13,-19},{13,-18},{13,-9},{13,-8},{13,-4},{13,-3},{13,-2},{13,1},{13,2},{13,5},{13,6},{13,7},{13,11},{13,12},{13,21},{13,22},{13,36},{13,37},{13,38},{13,39},{13,40},{13,41},{13,42},{13,45},{13,46},{14,-43},{14,-42},{14,-39},{14,-38},
{14,-37},{14,-36},{14,-35},{14,-34},{14,-20},{14,-19},{14,-18},{14,-17},{14,-10},{14,-9},{14,-8},{14,-7},{14,-3},{14,-2},{14,1},{14,2},{14,5},{14,6},{14,10},{14,11},{14,12},{14,13},{14,20},{14,21},{14,22},{14,23},{14,37},{14,38},{14,39},{14,40},
{14,41},{14,42},{14,45},{14,46},{15,-43},{15,-42},{15,-31},{15,-30},{15,-27},{15,-26},{15,-21},{15,-20},{15,-19},{15,-18},{15,-17},{15,-16},{15,-15},{15,-14},{15,-11},{15,-10},{15,-9},{15,-8},{15,-7},{15,-6},{15,1},{15,2},{15,9},{15,10},{15,11},{15,12},
{15,13},{15,14},{15,17},{15,18},{15,19},{15,20},{15,21},{15,22},{15,23},{15,24},{15,29},{15,30},{15,33},{15,34},{15,45},{15,46},{16,-43},{16,-42},{16,-32},{16,-31},{16,-30},{16,-27},{16,-26},{16,-25},{16,-21},{16,-20},{16,-19},{16,-18},{16,-17},{16,-16},
{16,-15},{16,-14},{16,-11},{16,-10},{16,-9},{16,-8},{16,-7},{16,-6},{16,0},{16,1},{16,2},{16,3},{16,9},{16,10},{16,11},{16,12},{16,13},{16,14},{16,17},{16,18},{16,19},{16,20},{16,21},{16,22},{16,23},{16,24},{16,28},{16,29},{16,30},{16,33},
{16,34},{16,35},{16,45},{16,46},{17,-43},{17,-42},{17,-35},{17,-34},{17,-33},{17,-32},{17,-31},{17,-26},{17,-25},{17,-24},{17,-15},{17,-14},{17,-10},{17,-9},{17,-8},{17,-7},{17,-6},{17,-1},{17,0},{17,1},{17,2},{17,3},{17,4},{17,9},{17,10},{17,11},
{17,12},{17,13},{17,17},{17,18},{17,27},{17,28},{17,29},{17,34},{17,35},{17,36},{17,37},{17,38},{17,45},{17,46},{18,-43},{18,-42},{18,-41},{18,-35},{18,-34},{18,-33},{18,-32},{18,-25},{18,-24},{18,-23},{18,-15},{18,-14},{18,-13},{18,-9},{18,-8},{18,-7},
{18,-6},{18,-2},{18,-1},{18,0},{18,1},{18,2},{18,3},{18,4},{18,5},{18,9},{18,10},{18,11},{18,12},{18,16},{18,17},{18,18},{18,26},{18,27},{18,28},{18,35},{18,36},{18,37},{18,38},{18,44},{18,45},{18,46},{19,-42},{19,-41},{19,-40},{19,-39},
{19,-38},{19,-29},{19,-28},{19,-25},{19,-24},{19,-23},{19,-22},{19,-21},{19,-20},{19,-19},{19,-18},{19,-15},{19,-14},{19,-13},{19,-12},{19,-3},{19,-2},{19,-1},{19,4},{19,5},{19,6},{19,15},{19,16},{19,17},{19,18},{19,21},{19,22},{19,23},{19,24},{19,25},
{19,26},{19,27},{19,28},{19,31},{19,32},{19,41},{19,42},{19,43},{19,44},{19,45},{20,-41},{20,-40},{20,-39},{20,-38},{20,-37},{20,-29},{20,-28},{20,-25},{20,-24},{20,-23},{20,-22},{20,-21},{20,-20},{20,-19},{20,-18},{20,-15},{20,-14},{20,-13},{20,-12},{20,-3},
{20,-2},{20,5},{20,6},{20,15},{20,16},{20,17},{20,18},{20,21},{20,22},{20,23},{20,24},{20,25},{20,26},{20,27},{20,28},{20,31},{20,32},{20,40},{20,41},{20,42},{20,43},{20,44},{21,-38},{21,-37},{21,-36},{21,-29},{21,-28},{21,-19},{21,-18},{21,-15},
{21,-14},{21,-13},{21,-9},{21,-8},{21,-7},{21,-6},{21,1},{21,2},{21,9},{21,10},{21,11},{21,12},{21,16},{21,17},{21,18},{21,21},{21,22},{21,31},{21,32},{21,39},{21,40},{21,41},{22,-37},{22,-36},{22,-30},{22,-29},{22,-28},{22,-19},{22,-18},{22,-15},
{22,-14},{22,-9},{22,-8},{22,-7},{22,-6},{22,-5},{22,0},{22,1},{22,2},{22,3},{22,8},{22,9},{22,10},{22,11},{22,12},{22,17},{22,18},{22,21},{22,22},{22,31},{22,32},{22,33},{22,39},{22,40},{23,-33},{23,-32},{23,-31},{23,-30},{23,-29},{23,-25},
{23,-24},{23,-23},{23,-22},{23,-19},{23,-18},{23,-9},{23,-8},{23,-7},{23,-6},{23,-5},{23,-4},{23,-1},{23,0},{23,1},{23,2},{23,3},{23,4},{23,7},{23,8},{23,9},{23,10},{23,11},{23,12},{23,21},{23,22},{23,25},{23,26},{23,27},{23,28},{23,32},
{23,33},{23,34},{23,35},{23,36},{24,-33},{24,-32},{24,-31},{24,-30},{24,-25},{24,-24},{24,-23},{24,-22},{24,-19},{24,-18},{24,-17},{24,-9},{24,-8},{24,-7},{24,-6},{24,-5},{24,-4},{24,-1},{24,0},{24,1},{24,2},{24,3},{24,4},{24,7},{24,8},{24,9},
{24,10},{24,11},{24,12},{24,20},{24,21},{24,22},{24,25},{24,26},{24,27},{24,28},{24,33},{24,34},{24,35},{24,36},{25,-39},{25,-38},{25,-37},{25,-36},{25,-24},{25,-23},{25,-22},{25,-19},{25,-18},{25,-17},{25,-16},{25,-6},{25,-5},{25,-4},{25,-1},{25,0},
{25,1},{25,2},{25,3},{25,4},{25,7},{25,8},{25,9},{25,19},{25,20},{25,21},{25,22},{25,25},{25,26},{25,27},{25,39},{25,40},{25,41},{25,42},{26,-39},{26,-38},{26,-37},{26,-36},{26,-23},{26,-22},{26,-19},{26,-18},{26,-17},{26,-16},{26,-15},{26,-5},
{26,-4},{26,-1},{26,0},{26,1},{26,2},{26,3},{26,4},{26,7},{26,8},{26,18},{26,19},{26,20},{26,21},{26,22},{26,25},{26,26},{26,39},{26,40},{26,41},{26,42},{27,-38},{27,-37},{27,-36},{27,-29},{27,-28},{27,-27},{27,-26},{27,-16},{27,-15},{27,-14},
{27,-9},{27,-8},{27,11},{27,12},{27,17},{27,18},{27,19},{27,29},{27,30},{27,31},{27,32},{27,39},{27,40},{27,41},{28,-37},{28,-36},{28,-30},{28,-29},{28,-28},{28,-27},{28,-26},{28,-15},{28,-14},{28,-10},{28,-9},{28,-8},{28,-7},{28,10},{28,11},{28,12},
{28,13},{28,17},{28,18},{28,29},{28,30},{28,31},{28,32},{28,33},{28,39},{28,40},{29,-33},{29,-32},{29,-31},{29,-30},{29,-29},{29,-28},{29,-27},{29,-26},{29,-21},{29,-20},{29,-19},{29,-18},{29,-11},{29,-10},{29,-9},{29,-8},{29,-7},{29,-6},{29,-1},{29,0},
{29,1},{29,2},{29,3},{29,4},{29,9},{29,10},{29,11},{29,12},{29,13},{29,14},{29,21},{29,22},{29,23},{29,24},{29,29},{29,30},{29,31},{29,32},{29,33},{29,34},{29,35},{29,36},{30,-33},{30,-32},{30,-31},{30,-30},{30,-29},{30,-28},{30,-27},{30,-26},
{30,-22},{30,-21},{30,-20},{30,-19},{30,-18},{30,-11},{30,-10},{30,-9},{30,-8},{30,-7},{30,-6},{30,-5},{30,-1},{30,0},{30,1},{30,2},{30,3},{30,4},{30,8},{30,9},{30,10},{30,11},{30,12},{30,13},{30,14},{30,21},{30,22},{30,23},{30,24},{30,25},
{30,29},{30,30},{30,31},{30,32},{30,33},{30,34},{30,35},{30,36},{31,-32},{31,-31},{31,-30},{31,-29},{31,-28},{31,-27},{31,-23},{31,-22},{31,-21},{31,-15},{31,-14},{31,-6},{31,-5},{31,-4},{31,-1},{31,0},{31,3},{31,4},{31,7},{31,8},{31,9},{31,17},
{31,18},{31,24},{31,25},{31,26},{31,30},{31,31},{31,32},{31,33},{31,34},{31,35},{32,-31},{32,-30},{32,-29},{32,-28},{32,-23},{32,-22},{32,-16},{32,-15},{32,-14},{32,-5},{32,-4},{32,-1},{32,0},{32,3},{32,4},{32,7},{32,8},{32,17},{32,18},{32,19},
{32,25},{32,26},{32,31},{32,32},{32,33},{32,34},{33,-30},{33,-29},{33,-28},{33,-23},{33,-22},{33,-17},{33,-16},{33,-15},{33,-11},{33,-10},{33,-9},{33,-8},{33,11},{33,12},{33,13},{33,14},{33,18},{33,19},{33,20},{33,25},{33,26},{33,31},{33,32},{33,33},
{34,-29},{34,-28},{34,-23},{34,-22},{34,-17},{34,-16},{34,-12},{34,-11},{34,-10},{34,-9},{34,-8},{34,11},{34,12},{34,13},{34,14},{34,15},{34,19},{34,20},{34,25},{34,26},{34,31},{34,32},{35,-17},{35,-16},{35,-13},{35,-12},{35,-11},{35,-10},{35,-9},{35,-3},
{35,-2},{35,-1},{35,0},{35,3},{35,4},{35,5},{35,6},{35,12},{35,13},{35,14},{35,15},{35,16},{35,19},{35,20},{36,-17},{36,-16},{36,-13},{36,-12},{36,-11},{36,-10},{36,-4},{36,-3},{36,-2},{36,-1},{36,0},{36,3},{36,4},{36,5},{36,6},{36,7},
{36,13},{36,14},{36,15},{36,16},{36,19},{36,20},{37,-27},{37,-26},{37,-25},{37,-24},{37,-21},{37,-20},{37,-13},{37,-12},{37,-5},{37,-4},{37,-3},{37,-2},{37,-1},{37,0},{37,1},{37,2},{37,3},{37,4},{37,5},{37,6},{37,7},{37,8},{37,15},{37,16},
{37,23},{37,24},{37,27},{37,28},{37,29},{37,30},{38,-27},{38,-26},{38,-25},{38,-24},{38,-21},{38,-20},{38,-19},{38,-13},{38,-12},{38,-5},{38,-4},{38,-3},{38,-2},{38,-1},{38,0},{38,1},{38,2},{38,3},{38,4},{38,5},{38,6},{38,7},{38,8},{38,15},
{38,16},{38,22},{38,23},{38,24},{38,27},{38,28},{38,29},{38,30},{39,-26},{39,-25},{39,-24},{39,-20},{39,-19},{39,-18},{39,-13},{39,-12},{39,-11},{39,-10},{39,-5},{39,-4},{39,7},{39,8},{39,13},{39,14},{39,15},{39,16},{39,21},{39,22},{39,23},{39,27},
{39,28},{39,29},{40,-25},{40,-24},{40,-19},{40,-18},{40,-13},{40,-12},{40,-11},{40,-10},{40,-5},{40,-4},{40,7},{40,8},{40,13},{40,14},{40,15},{40,16},{40,21},{40,22},{40,27},{40,28},{41,-19},{41,-18},{41,-1},{41,0},{41,1},{41,2},{41,3},{41,4},
{41,21},{41,22},{42,-19},{42,-18},{42,-17},{42,-1},{42,0},{42,1},{42,2},{42,3},{42,4},{42,20},{42,21},{42,22},{43,-18},{43,-17},{43,-16},{43,-15},{43,-14},{43,-13},{43,-12},{43,-9},{43,-8},{43,-1},{43,0},{43,1},{43,2},{43,3},{43,4},{43,11},
{43,12},{43,15},{43,16},{43,17},{43,18},{43,19},{43,20},{43,21},{44,-17},{44,-16},{44,-15},{44,-14},{44,-13},{44,-12},{44,-9},{44,-8},{44,-7},{44,-2},{44,-1},{44,0},{44,1},{44,2},{44,3},{44,4},{44,5},{44,10},{44,11},{44,12},{44,15},{44,16},
{44,17},{44,18},{44,19},{44,20},{45,-8},{45,-7},{45,-6},{45,-5},{45,-4},{45,-3},{45,-2},{45,-1},{45,4},{45,5},{45,6},{45,7},{45,8},{45,9},{45,10},{45,11},{46,-7},{46,-6},{46,-5},{46,-4},{46,-3},{46,-2},{46,5},{46,6},{46,7},{46,8},
{46,9},{46,10},{47,-4},{47,-3},{47,-2},{47,1},{47,2},{47,5},{47,6},{47,7},{48,-3},{48,-2},{48,1},{48,2},{48,5},{48,6}
}
{ -49, -3 }, { -49, -2 }, { -49, 1 }, { -49, 2 }, { -49, 5 }, { -49, 6 }, { -48, -4 }, { -48, -3 }, { -48, -2 }, { -48, 1 }, { -48, 2 }, { -48, 5 }, { -48, 6 }, { -48, 7 }, { -47, -7 }, { -47, -6 }, { -47, -5 }, { -47, -4 }, { -47, -3 }, { -47, -2 }, { -47, 5 }, { -47, 6 }, { -47, 7 }, { -47, 8 }, { -47, 9 }, { -47, 10 }, { -46, -8 }, { -46, -7 }, { -46, -6 }, { -46, -5 },
{ -46, -4 }, { -46, -3 }, { -46, -2 }, { -46, -1 }, { -46, 4 }, { -46, 5 }, { -46, 6 }, { -46, 7 }, { -46, 8 }, { -46, 9 }, { -46, 10 }, { -46, 11 }, { -45, -17 }, { -45, -16 }, { -45, -15 }, { -45, -14 }, { -45, -13 }, { -45, -12 }, { -45, -9 }, { -45, -8 }, { -45, -7 }, { -45, -2 }, { -45, -1 }, { -45, 0 }, { -45, 1 }, { -45, 2 }, { -45, 3 }, { -45, 4 }, { -45, 5 }, { -45, 10 },
{ -45, 11 }, { -45, 12 }, { -45, 15 }, { -45, 16 }, { -45, 17 }, { -45, 18 }, { -45, 19 }, { -45, 20 }, { -44, -18 }, { -44, -17 }, { -44, -16 }, { -44, -15 }, { -44, -14 }, { -44, -13 }, { -44, -12 }, { -44, -9 }, { -44, -8 }, { -44, -1 }, { -44, 0 }, { -44, 1 }, { -44, 2 }, { -44, 3 }, { -44, 4 }, { -44, 11 }, { -44, 12 }, { -44, 15 }, { -44, 16 }, { -44, 17 }, { -44, 18 }, { -44, 19 },
{ -44, 20 }, { -44, 21 }, { -43, -19 }, { -43, -18 }, { -43, -17 }, { -43, -1 }, { -43, 0 }, { -43, 1 }, { -43, 2 }, { -43, 3 }, { -43, 4 }, { -43, 20 }, { -43, 21 }, { -43, 22 }, { -42, -19 }, { -42, -18 }, { -42, -1 }, { -42, 0 }, { -42, 1 }, { -42, 2 }, { -42, 3 }, { -42, 4 }, { -42, 21 }, { -42, 22 }, { -41, -25 }, { -41, -24 }, { -41, -19 }, { -41, -18 }, { -41, -13 }, { -41, -12 },
{ -41, -11 }, { -41, -10 }, { -41, -5 }, { -41, -4 }, { -41, 7 }, { -41, 8 }, { -41, 13 }, { -41, 14 }, { -41, 15 }, { -41, 16 }, { -41, 21 }, { -41, 22 }, { -41, 27 }, { -41, 28 }, { -40, -26 }, { -40, -25 }, { -40, -24 }, { -40, -20 }, { -40, -19 }, { -40, -18 }, { -40, -13 }, { -40, -12 }, { -40, -11 }, { -40, -10 }, { -40, -5 }, { -40, -4 }, { -40, 7 }, { -40, 8 }, { -40, 13 }, { -40, 14 },
{ -40, 15 }, { -40, 16 }, { -40, 21 }, { -40, 22 }, { -40, 23 }, { -40, 27 }, { -40, 28 }, { -40, 29 }, { -39, -27 }, { -39, -26 }, { -39, -25 }, { -39, -24 }, { -39, -21 }, { -39, -20 }, { -39, -19 }, { -39, -13 }, { -39, -12 }, { -39, -5 }, { -39, -4 }, { -39, -3 }, { -39, -2 }, { -39, -1 }, { -39, 0 }, { -39, 1 }, { -39, 2 }, { -39, 3 }, { -39, 4 }, { -39, 5 }, { -39, 6 }, { -39, 7 },
{ -39, 8 }, { -39, 15 }, { -39, 16 }, { -39, 22 }, { -39, 23 }, { -39, 24 }, { -39, 27 }, { -39, 28 }, { -39, 29 }, { -39, 30 }, { -38, -27 }, { -38, -26 }, { -38, -25 }, { -38, -24 }, { -38, -21 }, { -38, -20 }, { -38, -13 }, { -38, -12 }, { -38, -5 }, { -38, -4 }, { -38, -3 }, { -38, -2 }, { -38, -1 }, { -38, 0 }, { -38, 1 }, { -38, 2 }, { -38, 3 }, { -38, 4 }, { -38, 5 }, { -38, 6 },
{ -38, 7 }, { -38, 8 }, { -38, 15 }, { -38, 16 }, { -38, 23 }, { -38, 24 }, { -38, 27 }, { -38, 28 }, { -38, 29 }, { -38, 30 }, { -37, -17 }, { -37, -16 }, { -37, -13 }, { -37, -12 }, { -37, -11 }, { -37, -10 }, { -37, -4 }, { -37, -3 }, { -37, -2 }, { -37, -1 }, { -37, 0 }, { -37, 3 }, { -37, 4 }, { -37, 5 }, { -37, 6 }, { -37, 7 }, { -37, 13 }, { -37, 14 }, { -37, 15 }, { -37, 16 },
{ -37, 19 }, { -37, 20 }, { -36, -17 }, { -36, -16 }, { -36, -13 }, { -36, -12 }, { -36, -11 }, { -36, -10 }, { -36, -9 }, { -36, -3 }, { -36, -2 }, { -36, -1 }, { -36, 0 }, { -36, 3 }, { -36, 4 }, { -36, 5 }, { -36, 6 }, { -36, 12 }, { -36, 13 }, { -36, 14 }, { -36, 15 }, { -36, 16 }, { -36, 19 }, { -36, 20 }, { -35, -29 }, { -35, -28 }, { -35, -23 }, { -35, -22 }, { -35, -17 }, { -35, -16 },
{ -35, -12 }, { -35, -11 }, { -35, -10 }, { -35, -9 }, { -35, -8 }, { -35, 11 }, { -35, 12 }, { -35, 13 }, { -35, 14 }, { -35, 15 }, { -35, 19 }, { -35, 20 }, { -35, 25 }, { -35, 26 }, { -35, 31 }, { -35, 32 }, { -34, -30 }, { -34, -29 }, { -34, -28 }, { -34, -23 }, { -34, -22 }, { -34, -17 }, { -34, -16 }, { -34, -15 }, { -34, -11 }, { -34, -10 }, { -34, -9 }, { -34, -8 }, { -34, 11 }, { -34, 12 },
{ -34, 13 }, { -34, 14 }, { -34, 18 }, { -34, 19 }, { -34, 20 }, { -34, 25 }, { -34, 26 }, { -34, 31 }, { -34, 32 }, { -34, 33 }, { -33, -31 }, { -33, -30 }, { -33, -29 }, { -33, -28 }, { -33, -23 }, { -33, -22 }, { -33, -16 }, { -33, -15 }, { -33, -14 }, { -33, -5 }, { -33, -4 }, { -33, -1 }, { -33, 0 }, { -33, 3 }, { -33, 4 }, { -33, 7 }, { -33, 8 }, { -33, 17 }, { -33, 18 }, { -33, 19 },
{ -33, 25 }, { -33, 26 }, { -33, 31 }, { -33, 32 }, { -33, 33 }, { -33, 34 }, { -32, -32 }, { -32, -31 }, { -32, -30 }, { -32, -29 }, { -32, -28 }, { -32, -27 }, { -32, -23 }, { -32, -22 }, { -32, -21 }, { -32, -15 }, { -32, -14 }, { -32, -6 }, { -32, -5 }, { -32, -4 }, { -32, -1 }, { -32, 0 }, { -32, 3 }, { -32, 4 }, { -32, 7 }, { -32, 8 }, { -32, 9 }, { -32, 17 }, { -32, 18 }, { -32, 24 },
{ -32, 25 }, { -32, 26 }, { -32, 30 }, { -32, 31 }, { -32, 32 }, { -32, 33 }, { -32, 34 }, { -32, 35 }, { -31, -33 }, { -31, -32 }, { -31, -31 }, { -31, -30 }, { -31, -29 }, { -31, -28 }, { -31, -27 }, { -31, -26 }, { -31, -22 }, { -31, -21 }, { -31, -20 }, { -31, -19 }, { -31, -18 }, { -31, -11 }, { -31, -10 }, { -31, -9 }, { -31, -8 }, { -31, -7 }, { -31, -6 }, { -31, -5 }, { -31, -1 }, { -31, 0 },
{ -31, 1 }, { -31, 2 }, { -31, 3 }, { -31, 4 }, { -31, 8 }, { -31, 9 }, { -31, 10 }, { -31, 11 }, { -31, 12 }, { -31, 13 }, { -31, 14 }, { -31, 21 }, { -31, 22 }, { -31, 23 }, { -31, 24 }, { -31, 25 }, { -31, 29 }, { -31, 30 }, { -31, 31 }, { -31, 32 }, { -31, 33 }, { -31, 34 }, { -31, 35 }, { -31, 36 }, { -30, -33 }, { -30, -32 }, { -30, -31 }, { -30, -30 }, { -30, -29 }, { -30, -28 },
{ -30, -27 }, { -30, -26 }, { -30, -21 }, { -30, -20 }, { -30, -19 }, { -30, -18 }, { -30, -11 }, { -30, -10 }, { -30, -9 }, { -30, -8 }, { -30, -7 }, { -30, -6 }, { -30, -1 }, { -30, 0 }, { -30, 1 }, { -30, 2 }, { -30, 3 }, { -30, 4 }, { -30, 9 }, { -30, 10 }, { -30, 11 }, { -30, 12 }, { -30, 13 }, { -30, 14 }, { -30, 21 }, { -30, 22 }, { -30, 23 }, { -30, 24 }, { -30, 29 }, { -30, 30 },
{ -30, 31 }, { -30, 32 }, { -30, 33 }, { -30, 34 }, { -30, 35 }, { -30, 36 }, { -29, -37 }, { -29, -36 }, { -29, -30 }, { -29, -29 }, { -29, -28 }, { -29, -27 }, { -29, -26 }, { -29, -15 }, { -29, -14 }, { -29, -10 }, { -29, -9 }, { -29, -8 }, { -29, -7 }, { -29, 10 }, { -29, 11 }, { -29, 12 }, { -29, 13 }, { -29, 17 }, { -29, 18 }, { -29, 29 }, { -29, 30 }, { -29, 31 }, { -29, 32 }, { -29, 33 },
{ -29, 39 }, { -29, 40 }, { -28, -38 }, { -28, -37 }, { -28, -36 }, { -28, -29 }, { -28, -28 }, { -28, -27 }, { -28, -26 }, { -28, -16 }, { -28, -15 }, { -28, -14 }, { -28, -9 }, { -28, -8 }, { -28, 11 }, { -28, 12 }, { -28, 17 }, { -28, 18 }, { -28, 19 }, { -28, 29 }, { -28, 30 }, { -28, 31 }, { -28, 32 }, { -28, 39 }, { -28, 40 }, { -28, 41 }, { -27, -39 }, { -27, -38 }, { -27, -37 }, { -27, -36 },
{ -27, -23 }, { -27, -22 }, { -27, -19 }, { -27, -18 }, { -27, -17 }, { -27, -16 }, { -27, -15 }, { -27, -5 }, { -27, -4 }, { -27, -1 }, { -27, 0 }, { -27, 1 }, { -27, 2 }, { -27, 3 }, { -27, 4 }, { -27, 7 }, { -27, 8 }, { -27, 18 }, { -27, 19 }, { -27, 20 }, { -27, 21 }, { -27, 22 }, { -27, 25 }, { -27, 26 }, { -27, 39 }, { -27, 40 }, { -27, 41 }, { -27, 42 }, { -26, -39 }, { -26, -38 },
{ -26, -37 }, { -26, -36 }, { -26, -24 }, { -26, -23 }, { -26, -22 }, { -26, -19 }, { -26, -18 }, { -26, -17 }, { -26, -16 }, { -26, -6 }, { -26, -5 }, { -26, -4 }, { -26, -1 }, { -26, 0 }, { -26, 1 }, { -26, 2 }, { -26, 3 }, { -26, 4 }, { -26, 7 }, { -26, 8 }, { -26, 9 }, { -26, 19 }, { -26, 20 }, { -26, 21 }, { -26, 22 }, { -26, 25 }, { -26, 26 }, { -26, 27 }, { -26, 39 }, { -26, 40 },
{ -26, 41 }, { -26, 42 }, { -25, -33 }, { -25, -32 }, { -25, -31 }, { -25, -30 }, { -25, -25 }, { -25, -24 }, { -25, -23 }, { -25, -22 }, { -25, -19 }, { -25, -18 }, { -25, -17 }, { -25, -9 }, { -25, -8 }, { -25, -7 }, { -25, -6 }, { -25, -5 }, { -25, -4 }, { -25, -1 }, { -25, 0 }, { -25, 1 }, { -25, 2 }, { -25, 3 }, { -25, 4 }, { -25, 7 }, { -25, 8 }, { -25, 9 }, { -25, 10 }, { -25, 11 },
{ -25, 12 }, { -25, 20 }, { -25, 21 }, { -25, 22 }, { -25, 25 }, { -25, 26 }, { -25, 27 }, { -25, 28 }, { -25, 33 }, { -25, 34 }, { -25, 35 }, { -25, 36 }, { -24, -33 }, { -24, -32 }, { -24, -31 }, { -24, -30 }, { -24, -29 }, { -24, -25 }, { -24, -24 }, { -24, -23 }, { -24, -22 }, { -24, -19 }, { -24, -18 }, { -24, -9 }, { -24, -8 }, { -24, -7 }, { -24, -6 }, { -24, -5 }, { -24, -4 }, { -24, -1 },
{ -24, 0 }, { -24, 1 }, { -24, 2 }, { -24, 3 }, { -24, 4 }, { -24, 7 }, { -24, 8 }, { -24, 9 }, { -24, 10 }, { -24, 11 }, { -24, 12 }, { -24, 21 }, { -24, 22 }, { -24, 25 }, { -24, 26 }, { -24, 27 }, { -24, 28 }, { -24, 32 }, { -24, 33 }, { -24, 34 }, { -24, 35 }, { -24, 36 }, { -23, -37 }, { -23, -36 }, { -23, -30 }, { -23, -29 }, { -23, -28 }, { -23, -19 }, { -23, -18 }, { -23, -15 },
{ -23, -14 }, { -23, -9 }, { -23, -8 }, { -23, -7 }, { -23, -6 }, { -23, -5 }, { -23, 0 }, { -23, 1 }, { -23, 2 }, { -23, 3 }, { -23, 8 }, { -23, 9 }, { -23, 10 }, { -23, 11 }, { -23, 12 }, { -23, 17 }, { -23, 18 }, { -23, 21 }, { -23, 22 }, { -23, 31 }, { -23, 32 }, { -23, 33 }, { -23, 39 }, { -23, 40 }, { -22, -38 }, { -22, -37 }, { -22, -36 }, { -22, -29 }, { -22, -28 }, { -22, -19 },
{ -22, -18 }, { -22, -15 }, { -22, -14 }, { -22, -13 }, { -22, -9 }, { -22, -8 }, { -22, -7 }, { -22, -6 }, { -22, 1 }, { -22, 2 }, { -22, 9 }, { -22, 10 }, { -22, 11 }, { -22, 12 }, { -22, 16 }, { -22, 17 }, { -22, 18 }, { -22, 21 }, { -22, 22 }, { -22, 31 }, { -22, 32 }, { -22, 39 }, { -22, 40 }, { -22, 41 }, { -21, -41 }, { -21, -40 }, { -21, -39 }, { -21, -38 }, { -21, -37 }, { -21, -29 },
{ -21, -28 }, { -21, -25 }, { -21, -24 }, { -21, -23 }, { -21, -22 }, { -21, -21 }, { -21, -20 }, { -21, -19 }, { -21, -18 }, { -21, -15 }, { -21, -14 }, { -21, -13 }, { -21, -12 }, { -21, -3 }, { -21, -2 }, { -21, 5 }, { -21, 6 }, { -21, 15 }, { -21, 16 }, { -21, 17 }, { -21, 18 }, { -21, 21 }, { -21, 22 }, { -21, 23 }, { -21, 24 }, { -21, 25 }, { -21, 26 }, { -21, 27 }, { -21, 28 }, { -21, 31 },
{ -21, 32 }, { -21, 40 }, { -21, 41 }, { -21, 42 }, { -21, 43 }, { -21, 44 }, { -20, -42 }, { -20, -41 }, { -20, -40 }, { -20, -39 }, { -20, -38 }, { -20, -29 }, { -20, -28 }, { -20, -25 }, { -20, -24 }, { -20, -23 }, { -20, -22 }, { -20, -21 }, { -20, -20 }, { -20, -19 }, { -20, -18 }, { -20, -15 }, { -20, -14 }, { -20, -13 }, { -20, -12 }, { -20, -3 }, { -20, -2 }, { -20, -1 }, { -20, 4 }, { -20, 5 },
{ -20, 6 }, { -20, 15 }, { -20, 16 }, { -20, 17 }, { -20, 18 }, { -20, 21 }, { -20, 22 }, { -20, 23 }, { -20, 24 }, { -20, 25 }, { -20, 26 }, { -20, 27 }, { -20, 28 }, { -20, 31 }, { -20, 32 }, { -20, 41 }, { -20, 42 }, { -20, 43 }, { -20, 44 }, { -20, 45 }, { -19, -43 }, { -19, -42 }, { -19, -41 }, { -19, -35 }, { -19, -34 }, { -19, -33 }, { -19, -32 }, { -19, -25 }, { -19, -24 }, { -19, -23 },
{ -19, -15 }, { -19, -14 }, { -19, -13 }, { -19, -9 }, { -19, -8 }, { -19, -7 }, { -19, -6 }, { -19, -2 }, { -19, -1 }, { -19, 0 }, { -19, 1 }, { -19, 2 }, { -19, 3 }, { -19, 4 }, { -19, 5 }, { -19, 9 }, { -19, 10 }, { -19, 11 }, { -19, 12 }, { -19, 16 }, { -19, 17 }, { -19, 18 }, { -19, 26 }, { -19, 27 }, { -19, 28 }, { -19, 35 }, { -19, 36 }, { -19, 37 }, { -19, 38 }, { -19, 44 },
{ -19, 45 }, { -19, 46 }, { -18, -43 }, { -18, -42 }, { -18, -35 }, { -18, -34 }, { -18, -33 }, { -18, -32 }, { -18, -31 }, { -18, -26 }, { -18, -25 }, { -18, -24 }, { -18, -15 }, { -18, -14 }, { -18, -10 }, { -18, -9 }, { -18, -8 }, { -18, -7 }, { -18, -6 }, { -18, -1 }, { -18, 0 }, { -18, 1 }, { -18, 2 }, { -18, 3 }, { -18, 4 }, { -18, 9 }, { -18, 10 }, { -18, 11 }, { -18, 12 }, { -18, 13 },
{ -18, 17 }, { -18, 18 }, { -18, 27 }, { -18, 28 }, { -18, 29 }, { -18, 34 }, { -18, 35 }, { -18, 36 }, { -18, 37 }, { -18, 38 }, { -18, 45 }, { -18, 46 }, { -17, -43 }, { -17, -42 }, { -17, -32 }, { -17, -31 }, { -17, -30 }, { -17, -27 }, { -17, -26 }, { -17, -25 }, { -17, -21 }, { -17, -20 }, { -17, -19 }, { -17, -18 }, { -17, -17 }, { -17, -16 }, { -17, -15 }, { -17, -14 }, { -17, -11 }, { -17, -10 },
{ -17, -9 }, { -17, -8 }, { -17, -7 }, { -17, -6 }, { -17, 0 }, { -17, 1 }, { -17, 2 }, { -17, 3 }, { -17, 9 }, { -17, 10 }, { -17, 11 }, { -17, 12 }, { -17, 13 }, { -17, 14 }, { -17, 17 }, { -17, 18 }, { -17, 19 }, { -17, 20 }, { -17, 21 }, { -17, 22 }, { -17, 23 }, { -17, 24 }, { -17, 28 }, { -17, 29 }, { -17, 30 }, { -17, 33 }, { -17, 34 }, { -17, 35 }, { -17, 45 }, { -17, 46 },
{ -16, -43 }, { -16, -42 }, { -16, -31 }, { -16, -30 }, { -16, -27 }, { -16, -26 }, { -16, -21 }, { -16, -20 }, { -16, -19 }, { -16, -18 }, { -16, -17 }, { -16, -16 }, { -16, -15 }, { -16, -14 }, { -16, -11 }, { -16, -10 }, { -16, -9 }, { -16, -8 }, { -16, -7 }, { -16, -6 }, { -16, 1 }, { -16, 2 }, { -16, 9 }, { -16, 10 }, { -16, 11 }, { -16, 12 }, { -16, 13 }, { -16, 14 }, { -16, 17 }, { -16, 18 },
{ -16, 19 }, { -16, 20 }, { -16, 21 }, { -16, 22 }, { -16, 23 }, { -16, 24 }, { -16, 29 }, { -16, 30 }, { -16, 33 }, { -16, 34 }, { -16, 45 }, { -16, 46 }, { -15, -43 }, { -15, -42 }, { -15, -39 }, { -15, -38 }, { -15, -37 }, { -15, -36 }, { -15, -35 }, { -15, -34 }, { -15, -20 }, { -15, -19 }, { -15, -18 }, { -15, -17 }, { -15, -10 }, { -15, -9 }, { -15, -8 }, { -15, -7 }, { -15, -3 }, { -15, -2 },
{ -15, 1 }, { -15, 2 }, { -15, 5 }, { -15, 6 }, { -15, 10 }, { -15, 11 }, { -15, 12 }, { -15, 13 }, { -15, 20 }, { -15, 21 }, { -15, 22 }, { -15, 23 }, { -15, 37 }, { -15, 38 }, { -15, 39 }, { -15, 40 }, { -15, 41 }, { -15, 42 }, { -15, 45 }, { -15, 46 }, { -14, -43 }, { -14, -42 }, { -14, -39 }, { -14, -38 }, { -14, -37 }, { -14, -36 }, { -14, -35 }, { -14, -34 }, { -14, -33 }, { -14, -19 },
{ -14, -18 }, { -14, -9 }, { -14, -8 }, { -14, -4 }, { -14, -3 }, { -14, -2 }, { -14, 1 }, { -14, 2 }, { -14, 5 }, { -14, 6 }, { -14, 7 }, { -14, 11 }, { -14, 12 }, { -14, 21 }, { -14, 22 }, { -14, 36 }, { -14, 37 }, { -14, 38 }, { -14, 39 }, { -14, 40 }, { -14, 41 }, { -14, 42 }, { -14, 45 }, { -14, 46 }, { -13, -39 }, { -13, -38 }, { -13, -35 }, { -13, -34 }, { -13, -33 }, { -13, -32 },
{ -13, -29 }, { -13, -28 }, { -13, -15 }, { -13, -14 }, { -13, -5 }, { -13, -4 }, { -13, -3 }, { -13, -2 }, { -13, 5 }, { -13, 6 }, { -13, 7 }, { -13, 8 }, { -13, 17 }, { -13, 18 }, { -13, 31 }, { -13, 32 }, { -13, 35 }, { -13, 36 }, { -13, 37 }, { -13, 38 }, { -13, 41 }, { -13, 42 }, { -12, -39 }, { -12, -38 }, { -12, -35 }, { -12, -34 }, { -12, -33 }, { -12, -32 }, { -12, -29 }, { -12, -28 },
{ -12, -27 }, { -12, -16 }, { -12, -15 }, { -12, -14 }, { -12, -13 }, { -12, -5 }, { -12, -4 }, { -12, -3 }, { -12, -2 }, { -12, 5 }, { -12, 6 }, { -12, 7 }, { -12, 8 }, { -12, 16 }, { -12, 17 }, { -12, 18 }, { -12, 19 }, { -12, 30 }, { -12, 31 }, { -12, 32 }, { -12, 35 }, { -12, 36 }, { -12, 37 }, { -12, 38 }, { -12, 41 }, { -12, 42 }, { -11, -43 }, { -11, -42 }, { -11, -34 }, { -11, -33 },
{ -11, -32 }, { -11, -29 }, { -11, -28 }, { -11, -27 }, { -11, -26 }, { -11, -23 }, { -11, -22 }, { -11, -21 }, { -11, -20 }, { -11, -17 }, { -11, -16 }, { -11, -15 }, { -11, -14 }, { -11, -13 }, { -11, -12 }, { -11, -9 }, { -11, -8 }, { -11, 1 }, { -11, 2 }, { -11, 11 }, { -11, 12 }, { -11, 15 }, { -11, 16 }, { -11, 17 }, { -11, 18 }, { -11, 19 }, { -11, 20 }, { -11, 23 }, { -11, 24 }, { -11, 25 },
{ -11, 26 }, { -11, 29 }, { -11, 30 }, { -11, 31 }, { -11, 32 }, { -11, 35 }, { -11, 36 }, { -11, 37 }, { -11, 45 }, { -11, 46 }, { -10, -44 }, { -10, -43 }, { -10, -42 }, { -10, -33 }, { -10, -32 }, { -10, -29 }, { -10, -28 }, { -10, -27 }, { -10, -26 }, { -10, -23 }, { -10, -22 }, { -10, -21 }, { -10, -20 }, { -10, -17 }, { -10, -16 }, { -10, -15 }, { -10, -14 }, { -10, -13 }, { -10, -12 }, { -10, -9 },
{ -10, -8 }, { -10, -7 }, { -10, 0 }, { -10, 1 }, { -10, 2 }, { -10, 3 }, { -10, 10 }, { -10, 11 }, { -10, 12 }, { -10, 15 }, { -10, 16 }, { -10, 17 }, { -10, 18 }, { -10, 19 }, { -10, 20 }, { -10, 23 }, { -10, 24 }, { -10, 25 }, { -10, 26 }, { -10, 29 }, { -10, 30 }, { -10, 31 }, { -10, 32 }, { -10, 35 }, { -10, 36 }, { -10, 45 }, { -10, 46 }, { -10, 47 }, { -9, -45 }, { -9, -44 },
{ -9, -43 }, { -9, -29 }, { -9, -28 }, { -9, -27 }, { -9, -23 }, { -9, -22 }, { -9, -21 }, { -9, -20 }, { -9, -17 }, { -9, -16 }, { -9, -15 }, { -9, -14 }, { -9, -13 }, { -9, -8 }, { -9, -7 }, { -9, -6 }, { -9, -5 }, { -9, -1 }, { -9, 0 }, { -9, 1 }, { -9, 2 }, { -9, 3 }, { -9, 4 }, { -9, 8 }, { -9, 9 }, { -9, 10 }, { -9, 11 }, { -9, 16 }, { -9, 17 }, { -9, 18 },
{ -9, 19 }, { -9, 20 }, { -9, 23 }, { -9, 24 }, { -9, 25 }, { -9, 26 }, { -9, 30 }, { -9, 31 }, { -9, 32 }, { -9, 46 }, { -9, 47 }, { -9, 48 }, { -8, -45 }, { -8, -44 }, { -8, -30 }, { -8, -29 }, { -8, -28 }, { -8, -24 }, { -8, -23 }, { -8, -22 }, { -8, -21 }, { -8, -20 }, { -8, -17 }, { -8, -16 }, { -8, -15 }, { -8, -14 }, { -8, -7 }, { -8, -6 }, { -8, -5 }, { -8, -4 },
{ -8, -1 }, { -8, 0 }, { -8, 1 }, { -8, 2 }, { -8, 3 }, { -8, 4 }, { -8, 7 }, { -8, 8 }, { -8, 9 }, { -8, 10 }, { -8, 17 }, { -8, 18 }, { -8, 19 }, { -8, 20 }, { -8, 23 }, { -8, 24 }, { -8, 25 }, { -8, 26 }, { -8, 27 }, { -8, 31 }, { -8, 32 }, { -8, 33 }, { -8, 47 }, { -8, 48 }, { -7, -45 }, { -7, -44 }, { -7, -39 }, { -7, -38 }, { -7, -37 }, { -7, -36 },
{ -7, -31 }, { -7, -30 }, { -7, -29 }, { -7, -25 }, { -7, -24 }, { -7, -23 }, { -7, -22 }, { -7, -21 }, { -7, -11 }, { -7, -10 }, { -7, -7 }, { -7, -6 }, { -7, -5 }, { -7, -4 }, { -7, 7 }, { -7, 8 }, { -7, 9 }, { -7, 10 }, { -7, 13 }, { -7, 14 }, { -7, 24 }, { -7, 25 }, { -7, 26 }, { -7, 27 }, { -7, 28 }, { -7, 32 }, { -7, 33 }, { -7, 34 }, { -7, 39 }, { -7, 40 },
{ -7, 41 }, { -7, 42 }, { -7, 47 }, { -7, 48 }, { -6, -46 }, { -6, -45 }, { -6, -44 }, { -6, -39 }, { -6, -38 }, { -6, -37 }, { -6, -36 }, { -6, -35 }, { -6, -31 }, { -6, -30 }, { -6, -25 }, { -6, -24 }, { -6, -23 }, { -6, -22 }, { -6, -12 }, { -6, -11 }, { -6, -10 }, { -6, -6 }, { -6, -5 }, { -6, 8 }, { -6, 9 }, { -6, 13 }, { -6, 14 }, { -6, 15 }, { -6, 25 }, { -6, 26 },
{ -6, 27 }, { -6, 28 }, { -6, 33 }, { -6, 34 }, { -6, 38 }, { -6, 39 }, { -6, 40 }, { -6, 41 }, { -6, 42 }, { -6, 47 }, { -6, 48 }, { -6, 49 }, { -5, -47 }, { -5, -46 }, { -5, -45 }, { -5, -44 }, { -5, -37 }, { -5, -36 }, { -5, -35 }, { -5, -34 }, { -5, -19 }, { -5, -18 }, { -5, -13 }, { -5, -12 }, { -5, -11 }, { -5, -10 }, { -5, -1 }, { -5, 0 }, { -5, 1 }, { -5, 2 },
{ -5, 3 }, { -5, 4 }, { -5, 13 }, { -5, 14 }, { -5, 15 }, { -5, 16 }, { -5, 21 }, { -5, 22 }, { -5, 37 }, { -5, 38 }, { -5, 39 }, { -5, 40 }, { -5, 47 }, { -5, 48 }, { -5, 49 }, { -5, 50 }, { -4, -47 }, { -4, -46 }, { -4, -45 }, { -4, -44 }, { -4, -43 }, { -4, -37 }, { -4, -36 }, { -4, -35 }, { -4, -34 }, { -4, -19 }, { -4, -18 }, { -4, -17 }, { -4, -13 }, { -4, -12 },
{ -4, -11 }, { -4, -10 }, { -4, -2 }, { -4, -1 }, { -4, 0 }, { -4, 1 }, { -4, 2 }, { -4, 3 }, { -4, 4 }, { -4, 5 }, { -4, 13 }, { -4, 14 }, { -4, 15 }, { -4, 16 }, { -4, 20 }, { -4, 21 }, { -4, 22 }, { -4, 37 }, { -4, 38 }, { -4, 39 }, { -4, 40 }, { -4, 46 }, { -4, 47 }, { -4, 48 }, { -4, 49 }, { -4, 50 }, { -3, -44 }, { -3, -43 }, { -3, -42 }, { -3, -41 },
{ -3, -40 }, { -3, -37 }, { -3, -36 }, { -3, -35 }, { -3, -34 }, { -3, -31 }, { -3, -30 }, { -3, -29 }, { -3, -28 }, { -3, -25 }, { -3, -24 }, { -3, -23 }, { -3, -22 }, { -3, -18 }, { -3, -17 }, { -3, -16 }, { -3, -7 }, { -3, -6 }, { -3, -3 }, { -3, -2 }, { -3, -1 }, { -3, 0 }, { -3, 3 }, { -3, 4 }, { -3, 5 }, { -3, 6 }, { -3, 9 }, { -3, 10 }, { -3, 19 }, { -3, 20 },
{ -3, 21 }, { -3, 25 }, { -3, 26 }, { -3, 27 }, { -3, 28 }, { -3, 31 }, { -3, 32 }, { -3, 33 }, { -3, 34 }, { -3, 37 }, { -3, 38 }, { -3, 39 }, { -3, 40 }, { -3, 43 }, { -3, 44 }, { -3, 45 }, { -3, 46 }, { -3, 47 }, { -2, -43 }, { -2, -42 }, { -2, -41 }, { -2, -40 }, { -2, -37 }, { -2, -36 }, { -2, -35 }, { -2, -34 }, { -2, -31 }, { -2, -30 }, { -2, -29 }, { -2, -28 },
{ -2, -25 }, { -2, -24 }, { -2, -23 }, { -2, -22 }, { -2, -21 }, { -2, -17 }, { -2, -16 }, { -2, -15 }, { -2, -8 }, { -2, -7 }, { -2, -6 }, { -2, -3 }, { -2, -2 }, { -2, -1 }, { -2, 0 }, { -2, 3 }, { -2, 4 }, { -2, 5 }, { -2, 6 }, { -2, 9 }, { -2, 10 }, { -2, 11 }, { -2, 18 }, { -2, 19 }, { -2, 20 }, { -2, 24 }, { -2, 25 }, { -2, 26 }, { -2, 27 }, { -2, 28 },
{ -2, 31 }, { -2, 32 }, { -2, 33 }, { -2, 34 }, { -2, 37 }, { -2, 38 }, { -2, 39 }, { -2, 40 }, { -2, 43 }, { -2, 44 }, { -2, 45 }, { -2, 46 }, { -1, -47 }, { -1, -46 }, { -1, -43 }, { -1, -42 }, { -1, -41 }, { -1, -40 }, { -1, -37 }, { -1, -36 }, { -1, -29 }, { -1, -28 }, { -1, -25 }, { -1, -24 }, { -1, -23 }, { -1, -22 }, { -1, -21 }, { -1, -20 }, { -1, -17 }, { -1, -16 },
{ -1, -15 }, { -1, -14 }, { -1, -13 }, { -1, -12 }, { -1, -9 }, { -1, -8 }, { -1, -7 }, { -1, -6 }, { -1, -3 }, { -1, -2 }, { -1, 5 }, { -1, 6 }, { -1, 9 }, { -1, 10 }, { -1, 11 }, { -1, 12 }, { -1, 15 }, { -1, 16 }, { -1, 17 }, { -1, 18 }, { -1, 19 }, { -1, 20 }, { -1, 23 }, { -1, 24 }, { -1, 25 }, { -1, 26 }, { -1, 27 }, { -1, 28 }, { -1, 31 }, { -1, 32 },
{ -1, 39 }, { -1, 40 }, { -1, 43 }, { -1, 44 }, { -1, 45 }, { -1, 46 }, { -1, 49 }, { -1, 50 }, { 0, -47 }, { 0, -46 }, { 0, -43 }, { 0, -42 }, { 0, -41 }, { 0, -40 }, { 0, -37 }, { 0, -36 }, { 0, -29 }, { 0, -28 }, { 0, -25 }, { 0, -24 }, { 0, -23 }, { 0, -22 }, { 0, -21 }, { 0, -20 }, { 0, -17 }, { 0, -16 }, { 0, -15 }, { 0, -14 }, { 0, -13 }, { 0, -12 },
{ 0, -9 }, { 0, -8 }, { 0, -7 }, { 0, -6 }, { 0, -3 }, { 0, -2 }, { 0, 5 }, { 0, 6 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 15 }, { 0, 16 }, { 0, 17 }, { 0, 18 }, { 0, 19 }, { 0, 20 }, { 0, 23 }, { 0, 24 }, { 0, 25 }, { 0, 26 }, { 0, 27 }, { 0, 28 }, { 0, 31 }, { 0, 32 }, { 0, 39 }, { 0, 40 }, { 0, 43 }, { 0, 44 },
{ 0, 45 }, { 0, 46 }, { 0, 49 }, { 0, 50 }, { 1, -43 }, { 1, -42 }, { 1, -41 }, { 1, -40 }, { 1, -37 }, { 1, -36 }, { 1, -35 }, { 1, -34 }, { 1, -31 }, { 1, -30 }, { 1, -29 }, { 1, -28 }, { 1, -25 }, { 1, -24 }, { 1, -23 }, { 1, -22 }, { 1, -21 }, { 1, -17 }, { 1, -16 }, { 1, -15 }, { 1, -8 }, { 1, -7 }, { 1, -6 }, { 1, -3 }, { 1, -2 }, { 1, -1 },
{ 1, 0 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 18 }, { 1, 19 }, { 1, 20 }, { 1, 24 }, { 1, 25 }, { 1, 26 }, { 1, 27 }, { 1, 28 }, { 1, 31 }, { 1, 32 }, { 1, 33 }, { 1, 34 }, { 1, 37 }, { 1, 38 }, { 1, 39 }, { 1, 40 }, { 1, 43 }, { 1, 44 }, { 1, 45 }, { 1, 46 }, { 2, -44 }, { 2, -43 },
{ 2, -42 }, { 2, -41 }, { 2, -40 }, { 2, -37 }, { 2, -36 }, { 2, -35 }, { 2, -34 }, { 2, -31 }, { 2, -30 }, { 2, -29 }, { 2, -28 }, { 2, -25 }, { 2, -24 }, { 2, -23 }, { 2, -22 }, { 2, -18 }, { 2, -17 }, { 2, -16 }, { 2, -7 }, { 2, -6 }, { 2, -3 }, { 2, -2 }, { 2, -1 }, { 2, 0 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 9 }, { 2, 10 },
{ 2, 19 }, { 2, 20 }, { 2, 21 }, { 2, 25 }, { 2, 26 }, { 2, 27 }, { 2, 28 }, { 2, 31 }, { 2, 32 }, { 2, 33 }, { 2, 34 }, { 2, 37 }, { 2, 38 }, { 2, 39 }, { 2, 40 }, { 2, 43 }, { 2, 44 }, { 2, 45 }, { 2, 46 }, { 2, 47 }, { 3, -47 }, { 3, -46 }, { 3, -45 }, { 3, -44 }, { 3, -43 }, { 3, -37 }, { 3, -36 }, { 3, -35 }, { 3, -34 }, { 3, -19 },
{ 3, -18 }, { 3, -17 }, { 3, -13 }, { 3, -12 }, { 3, -11 }, { 3, -10 }, { 3, -2 }, { 3, -1 }, { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 13 }, { 3, 14 }, { 3, 15 }, { 3, 16 }, { 3, 20 }, { 3, 21 }, { 3, 22 }, { 3, 37 }, { 3, 38 }, { 3, 39 }, { 3, 40 }, { 3, 46 }, { 3, 47 }, { 3, 48 }, { 3, 49 }, { 3, 50 },
{ 4, -47 }, { 4, -46 }, { 4, -45 }, { 4, -44 }, { 4, -37 }, { 4, -36 }, { 4, -35 }, { 4, -34 }, { 4, -19 }, { 4, -18 }, { 4, -13 }, { 4, -12 }, { 4, -11 }, { 4, -10 }, { 4, -1 }, { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 }, { 4, 13 }, { 4, 14 }, { 4, 15 }, { 4, 16 }, { 4, 21 }, { 4, 22 }, { 4, 37 }, { 4, 38 }, { 4, 39 }, { 4, 40 },
{ 4, 47 }, { 4, 48 }, { 4, 49 }, { 4, 50 }, { 5, -46 }, { 5, -45 }, { 5, -44 }, { 5, -39 }, { 5, -38 }, { 5, -37 }, { 5, -36 }, { 5, -35 }, { 5, -31 }, { 5, -30 }, { 5, -25 }, { 5, -24 }, { 5, -23 }, { 5, -22 }, { 5, -12 }, { 5, -11 }, { 5, -10 }, { 5, -6 }, { 5, -5 }, { 5, 8 }, { 5, 9 }, { 5, 13 }, { 5, 14 }, { 5, 15 }, { 5, 25 }, { 5, 26 },
{ 5, 27 }, { 5, 28 }, { 5, 33 }, { 5, 34 }, { 5, 38 }, { 5, 39 }, { 5, 40 }, { 5, 41 }, { 5, 42 }, { 5, 47 }, { 5, 48 }, { 5, 49 }, { 6, -45 }, { 6, -44 }, { 6, -39 }, { 6, -38 }, { 6, -37 }, { 6, -36 }, { 6, -31 }, { 6, -30 }, { 6, -29 }, { 6, -25 }, { 6, -24 }, { 6, -23 }, { 6, -22 }, { 6, -21 }, { 6, -11 }, { 6, -10 }, { 6, -7 }, { 6, -6 },
{ 6, -5 }, { 6, -4 }, { 6, 7 }, { 6, 8 }, { 6, 9 }, { 6, 10 }, { 6, 13 }, { 6, 14 }, { 6, 24 }, { 6, 25 }, { 6, 26 }, { 6, 27 }, { 6, 28 }, { 6, 32 }, { 6, 33 }, { 6, 34 }, { 6, 39 }, { 6, 40 }, { 6, 41 }, { 6, 42 }, { 6, 47 }, { 6, 48 }, { 7, -45 }, { 7, -44 }, { 7, -30 }, { 7, -29 }, { 7, -28 }, { 7, -24 }, { 7, -23 }, { 7, -22 },
{ 7, -21 }, { 7, -20 }, { 7, -17 }, { 7, -16 }, { 7, -15 }, { 7, -14 }, { 7, -7 }, { 7, -6 }, { 7, -5 }, { 7, -4 }, { 7, -1 }, { 7, 0 }, { 7, 1 }, { 7, 2 }, { 7, 3 }, { 7, 4 }, { 7, 7 }, { 7, 8 }, { 7, 9 }, { 7, 10 }, { 7, 17 }, { 7, 18 }, { 7, 19 }, { 7, 20 }, { 7, 23 }, { 7, 24 }, { 7, 25 }, { 7, 26 }, { 7, 27 }, { 7, 31 },
{ 7, 32 }, { 7, 33 }, { 7, 47 }, { 7, 48 }, { 8, -45 }, { 8, -44 }, { 8, -43 }, { 8, -29 }, { 8, -28 }, { 8, -27 }, { 8, -23 }, { 8, -22 }, { 8, -21 }, { 8, -20 }, { 8, -17 }, { 8, -16 }, { 8, -15 }, { 8, -14 }, { 8, -13 }, { 8, -8 }, { 8, -7 }, { 8, -6 }, { 8, -5 }, { 8, -1 }, { 8, 0 }, { 8, 1 }, { 8, 2 }, { 8, 3 }, { 8, 4 }, { 8, 8 },
{ 8, 9 }, { 8, 10 }, { 8, 11 }, { 8, 16 }, { 8, 17 }, { 8, 18 }, { 8, 19 }, { 8, 20 }, { 8, 23 }, { 8, 24 }, { 8, 25 }, { 8, 26 }, { 8, 30 }, { 8, 31 }, { 8, 32 }, { 8, 46 }, { 8, 47 }, { 8, 48 }, { 9, -44 }, { 9, -43 }, { 9, -42 }, { 9, -33 }, { 9, -32 }, { 9, -29 }, { 9, -28 }, { 9, -27 }, { 9, -26 }, { 9, -23 }, { 9, -22 }, { 9, -21 },
{ 9, -20 }, { 9, -17 }, { 9, -16 }, { 9, -15 }, { 9, -14 }, { 9, -13 }, { 9, -12 }, { 9, -9 }, { 9, -8 }, { 9, -7 }, { 9, 0 }, { 9, 1 }, { 9, 2 }, { 9, 3 }, { 9, 10 }, { 9, 11 }, { 9, 12 }, { 9, 15 }, { 9, 16 }, { 9, 17 }, { 9, 18 }, { 9, 19 }, { 9, 20 }, { 9, 23 }, { 9, 24 }, { 9, 25 }, { 9, 26 }, { 9, 29 }, { 9, 30 }, { 9, 31 },
{ 9, 32 }, { 9, 35 }, { 9, 36 }, { 9, 45 }, { 9, 46 }, { 9, 47 }, { 10, -43 }, { 10, -42 }, { 10, -34 }, { 10, -33 }, { 10, -32 }, { 10, -29 }, { 10, -28 }, { 10, -27 }, { 10, -26 }, { 10, -23 }, { 10, -22 }, { 10, -21 }, { 10, -20 }, { 10, -17 }, { 10, -16 }, { 10, -15 }, { 10, -14 }, { 10, -13 }, { 10, -12 }, { 10, -9 }, { 10, -8 }, { 10, 1 }, { 10, 2 }, { 10, 11 },
{ 10, 12 }, { 10, 15 }, { 10, 16 }, { 10, 17 }, { 10, 18 }, { 10, 19 }, { 10, 20 }, { 10, 23 }, { 10, 24 }, { 10, 25 }, { 10, 26 }, { 10, 29 }, { 10, 30 }, { 10, 31 }, { 10, 32 }, { 10, 35 }, { 10, 36 }, { 10, 37 }, { 10, 45 }, { 10, 46 }, { 11, -39 }, { 11, -38 }, { 11, -35 }, { 11, -34 }, { 11, -33 }, { 11, -32 }, { 11, -29 }, { 11, -28 }, { 11, -27 }, { 11, -16 },
{ 11, -15 }, { 11, -14 }, { 11, -13 }, { 11, -5 }, { 11, -4 }, { 11, -3 }, { 11, -2 }, { 11, 5 }, { 11, 6 }, { 11, 7 }, { 11, 8 }, { 11, 16 }, { 11, 17 }, { 11, 18 }, { 11, 19 }, { 11, 30 }, { 11, 31 }, { 11, 32 }, { 11, 35 }, { 11, 36 }, { 11, 37 }, { 11, 38 }, { 11, 41 }, { 11, 42 }, { 12, -39 }, { 12, -38 }, { 12, -35 }, { 12, -34 }, { 12, -33 }, { 12, -32 },
{ 12, -29 }, { 12, -28 }, { 12, -15 }, { 12, -14 }, { 12, -5 }, { 12, -4 }, { 12, -3 }, { 12, -2 }, { 12, 5 }, { 12, 6 }, { 12, 7 }, { 12, 8 }, { 12, 17 }, { 12, 18 }, { 12, 31 }, { 12, 32 }, { 12, 35 }, { 12, 36 }, { 12, 37 }, { 12, 38 }, { 12, 41 }, { 12, 42 }, { 13, -43 }, { 13, -42 }, { 13, -39 }, { 13, -38 }, { 13, -37 }, { 13, -36 }, { 13, -35 }, { 13, -34 },
{ 13, -33 }, { 13, -19 }, { 13, -18 }, { 13, -9 }, { 13, -8 }, { 13, -4 }, { 13, -3 }, { 13, -2 }, { 13, 1 }, { 13, 2 }, { 13, 5 }, { 13, 6 }, { 13, 7 }, { 13, 11 }, { 13, 12 }, { 13, 21 }, { 13, 22 }, { 13, 36 }, { 13, 37 }, { 13, 38 }, { 13, 39 }, { 13, 40 }, { 13, 41 }, { 13, 42 }, { 13, 45 }, { 13, 46 }, { 14, -43 }, { 14, -42 }, { 14, -39 }, { 14, -38 },
{ 14, -37 }, { 14, -36 }, { 14, -35 }, { 14, -34 }, { 14, -20 }, { 14, -19 }, { 14, -18 }, { 14, -17 }, { 14, -10 }, { 14, -9 }, { 14, -8 }, { 14, -7 }, { 14, -3 }, { 14, -2 }, { 14, 1 }, { 14, 2 }, { 14, 5 }, { 14, 6 }, { 14, 10 }, { 14, 11 }, { 14, 12 }, { 14, 13 }, { 14, 20 }, { 14, 21 }, { 14, 22 }, { 14, 23 }, { 14, 37 }, { 14, 38 }, { 14, 39 }, { 14, 40 },
{ 14, 41 }, { 14, 42 }, { 14, 45 }, { 14, 46 }, { 15, -43 }, { 15, -42 }, { 15, -31 }, { 15, -30 }, { 15, -27 }, { 15, -26 }, { 15, -21 }, { 15, -20 }, { 15, -19 }, { 15, -18 }, { 15, -17 }, { 15, -16 }, { 15, -15 }, { 15, -14 }, { 15, -11 }, { 15, -10 }, { 15, -9 }, { 15, -8 }, { 15, -7 }, { 15, -6 }, { 15, 1 }, { 15, 2 }, { 15, 9 }, { 15, 10 }, { 15, 11 }, { 15, 12 },
{ 15, 13 }, { 15, 14 }, { 15, 17 }, { 15, 18 }, { 15, 19 }, { 15, 20 }, { 15, 21 }, { 15, 22 }, { 15, 23 }, { 15, 24 }, { 15, 29 }, { 15, 30 }, { 15, 33 }, { 15, 34 }, { 15, 45 }, { 15, 46 }, { 16, -43 }, { 16, -42 }, { 16, -32 }, { 16, -31 }, { 16, -30 }, { 16, -27 }, { 16, -26 }, { 16, -25 }, { 16, -21 }, { 16, -20 }, { 16, -19 }, { 16, -18 }, { 16, -17 }, { 16, -16 },
{ 16, -15 }, { 16, -14 }, { 16, -11 }, { 16, -10 }, { 16, -9 }, { 16, -8 }, { 16, -7 }, { 16, -6 }, { 16, 0 }, { 16, 1 }, { 16, 2 }, { 16, 3 }, { 16, 9 }, { 16, 10 }, { 16, 11 }, { 16, 12 }, { 16, 13 }, { 16, 14 }, { 16, 17 }, { 16, 18 }, { 16, 19 }, { 16, 20 }, { 16, 21 }, { 16, 22 }, { 16, 23 }, { 16, 24 }, { 16, 28 }, { 16, 29 }, { 16, 30 }, { 16, 33 },
{ 16, 34 }, { 16, 35 }, { 16, 45 }, { 16, 46 }, { 17, -43 }, { 17, -42 }, { 17, -35 }, { 17, -34 }, { 17, -33 }, { 17, -32 }, { 17, -31 }, { 17, -26 }, { 17, -25 }, { 17, -24 }, { 17, -15 }, { 17, -14 }, { 17, -10 }, { 17, -9 }, { 17, -8 }, { 17, -7 }, { 17, -6 }, { 17, -1 }, { 17, 0 }, { 17, 1 }, { 17, 2 }, { 17, 3 }, { 17, 4 }, { 17, 9 }, { 17, 10 }, { 17, 11 },
{ 17, 12 }, { 17, 13 }, { 17, 17 }, { 17, 18 }, { 17, 27 }, { 17, 28 }, { 17, 29 }, { 17, 34 }, { 17, 35 }, { 17, 36 }, { 17, 37 }, { 17, 38 }, { 17, 45 }, { 17, 46 }, { 18, -43 }, { 18, -42 }, { 18, -41 }, { 18, -35 }, { 18, -34 }, { 18, -33 }, { 18, -32 }, { 18, -25 }, { 18, -24 }, { 18, -23 }, { 18, -15 }, { 18, -14 }, { 18, -13 }, { 18, -9 }, { 18, -8 }, { 18, -7 },
{ 18, -6 }, { 18, -2 }, { 18, -1 }, { 18, 0 }, { 18, 1 }, { 18, 2 }, { 18, 3 }, { 18, 4 }, { 18, 5 }, { 18, 9 }, { 18, 10 }, { 18, 11 }, { 18, 12 }, { 18, 16 }, { 18, 17 }, { 18, 18 }, { 18, 26 }, { 18, 27 }, { 18, 28 }, { 18, 35 }, { 18, 36 }, { 18, 37 }, { 18, 38 }, { 18, 44 }, { 18, 45 }, { 18, 46 }, { 19, -42 }, { 19, -41 }, { 19, -40 }, { 19, -39 },
{ 19, -38 }, { 19, -29 }, { 19, -28 }, { 19, -25 }, { 19, -24 }, { 19, -23 }, { 19, -22 }, { 19, -21 }, { 19, -20 }, { 19, -19 }, { 19, -18 }, { 19, -15 }, { 19, -14 }, { 19, -13 }, { 19, -12 }, { 19, -3 }, { 19, -2 }, { 19, -1 }, { 19, 4 }, { 19, 5 }, { 19, 6 }, { 19, 15 }, { 19, 16 }, { 19, 17 }, { 19, 18 }, { 19, 21 }, { 19, 22 }, { 19, 23 }, { 19, 24 }, { 19, 25 },
{ 19, 26 }, { 19, 27 }, { 19, 28 }, { 19, 31 }, { 19, 32 }, { 19, 41 }, { 19, 42 }, { 19, 43 }, { 19, 44 }, { 19, 45 }, { 20, -41 }, { 20, -40 }, { 20, -39 }, { 20, -38 }, { 20, -37 }, { 20, -29 }, { 20, -28 }, { 20, -25 }, { 20, -24 }, { 20, -23 }, { 20, -22 }, { 20, -21 }, { 20, -20 }, { 20, -19 }, { 20, -18 }, { 20, -15 }, { 20, -14 }, { 20, -13 }, { 20, -12 }, { 20, -3 },
{ 20, -2 }, { 20, 5 }, { 20, 6 }, { 20, 15 }, { 20, 16 }, { 20, 17 }, { 20, 18 }, { 20, 21 }, { 20, 22 }, { 20, 23 }, { 20, 24 }, { 20, 25 }, { 20, 26 }, { 20, 27 }, { 20, 28 }, { 20, 31 }, { 20, 32 }, { 20, 40 }, { 20, 41 }, { 20, 42 }, { 20, 43 }, { 20, 44 }, { 21, -38 }, { 21, -37 }, { 21, -36 }, { 21, -29 }, { 21, -28 }, { 21, -19 }, { 21, -18 }, { 21, -15 },
{ 21, -14 }, { 21, -13 }, { 21, -9 }, { 21, -8 }, { 21, -7 }, { 21, -6 }, { 21, 1 }, { 21, 2 }, { 21, 9 }, { 21, 10 }, { 21, 11 }, { 21, 12 }, { 21, 16 }, { 21, 17 }, { 21, 18 }, { 21, 21 }, { 21, 22 }, { 21, 31 }, { 21, 32 }, { 21, 39 }, { 21, 40 }, { 21, 41 }, { 22, -37 }, { 22, -36 }, { 22, -30 }, { 22, -29 }, { 22, -28 }, { 22, -19 }, { 22, -18 }, { 22, -15 },
{ 22, -14 }, { 22, -9 }, { 22, -8 }, { 22, -7 }, { 22, -6 }, { 22, -5 }, { 22, 0 }, { 22, 1 }, { 22, 2 }, { 22, 3 }, { 22, 8 }, { 22, 9 }, { 22, 10 }, { 22, 11 }, { 22, 12 }, { 22, 17 }, { 22, 18 }, { 22, 21 }, { 22, 22 }, { 22, 31 }, { 22, 32 }, { 22, 33 }, { 22, 39 }, { 22, 40 }, { 23, -33 }, { 23, -32 }, { 23, -31 }, { 23, -30 }, { 23, -29 }, { 23, -25 },
{ 23, -24 }, { 23, -23 }, { 23, -22 }, { 23, -19 }, { 23, -18 }, { 23, -9 }, { 23, -8 }, { 23, -7 }, { 23, -6 }, { 23, -5 }, { 23, -4 }, { 23, -1 }, { 23, 0 }, { 23, 1 }, { 23, 2 }, { 23, 3 }, { 23, 4 }, { 23, 7 }, { 23, 8 }, { 23, 9 }, { 23, 10 }, { 23, 11 }, { 23, 12 }, { 23, 21 }, { 23, 22 }, { 23, 25 }, { 23, 26 }, { 23, 27 }, { 23, 28 }, { 23, 32 },
{ 23, 33 }, { 23, 34 }, { 23, 35 }, { 23, 36 }, { 24, -33 }, { 24, -32 }, { 24, -31 }, { 24, -30 }, { 24, -25 }, { 24, -24 }, { 24, -23 }, { 24, -22 }, { 24, -19 }, { 24, -18 }, { 24, -17 }, { 24, -9 }, { 24, -8 }, { 24, -7 }, { 24, -6 }, { 24, -5 }, { 24, -4 }, { 24, -1 }, { 24, 0 }, { 24, 1 }, { 24, 2 }, { 24, 3 }, { 24, 4 }, { 24, 7 }, { 24, 8 }, { 24, 9 },
{ 24, 10 }, { 24, 11 }, { 24, 12 }, { 24, 20 }, { 24, 21 }, { 24, 22 }, { 24, 25 }, { 24, 26 }, { 24, 27 }, { 24, 28 }, { 24, 33 }, { 24, 34 }, { 24, 35 }, { 24, 36 }, { 25, -39 }, { 25, -38 }, { 25, -37 }, { 25, -36 }, { 25, -24 }, { 25, -23 }, { 25, -22 }, { 25, -19 }, { 25, -18 }, { 25, -17 }, { 25, -16 }, { 25, -6 }, { 25, -5 }, { 25, -4 }, { 25, -1 }, { 25, 0 },
{ 25, 1 }, { 25, 2 }, { 25, 3 }, { 25, 4 }, { 25, 7 }, { 25, 8 }, { 25, 9 }, { 25, 19 }, { 25, 20 }, { 25, 21 }, { 25, 22 }, { 25, 25 }, { 25, 26 }, { 25, 27 }, { 25, 39 }, { 25, 40 }, { 25, 41 }, { 25, 42 }, { 26, -39 }, { 26, -38 }, { 26, -37 }, { 26, -36 }, { 26, -23 }, { 26, -22 }, { 26, -19 }, { 26, -18 }, { 26, -17 }, { 26, -16 }, { 26, -15 }, { 26, -5 },
{ 26, -4 }, { 26, -1 }, { 26, 0 }, { 26, 1 }, { 26, 2 }, { 26, 3 }, { 26, 4 }, { 26, 7 }, { 26, 8 }, { 26, 18 }, { 26, 19 }, { 26, 20 }, { 26, 21 }, { 26, 22 }, { 26, 25 }, { 26, 26 }, { 26, 39 }, { 26, 40 }, { 26, 41 }, { 26, 42 }, { 27, -38 }, { 27, -37 }, { 27, -36 }, { 27, -29 }, { 27, -28 }, { 27, -27 }, { 27, -26 }, { 27, -16 }, { 27, -15 }, { 27, -14 },
{ 27, -9 }, { 27, -8 }, { 27, 11 }, { 27, 12 }, { 27, 17 }, { 27, 18 }, { 27, 19 }, { 27, 29 }, { 27, 30 }, { 27, 31 }, { 27, 32 }, { 27, 39 }, { 27, 40 }, { 27, 41 }, { 28, -37 }, { 28, -36 }, { 28, -30 }, { 28, -29 }, { 28, -28 }, { 28, -27 }, { 28, -26 }, { 28, -15 }, { 28, -14 }, { 28, -10 }, { 28, -9 }, { 28, -8 }, { 28, -7 }, { 28, 10 }, { 28, 11 }, { 28, 12 },
{ 28, 13 }, { 28, 17 }, { 28, 18 }, { 28, 29 }, { 28, 30 }, { 28, 31 }, { 28, 32 }, { 28, 33 }, { 28, 39 }, { 28, 40 }, { 29, -33 }, { 29, -32 }, { 29, -31 }, { 29, -30 }, { 29, -29 }, { 29, -28 }, { 29, -27 }, { 29, -26 }, { 29, -21 }, { 29, -20 }, { 29, -19 }, { 29, -18 }, { 29, -11 }, { 29, -10 }, { 29, -9 }, { 29, -8 }, { 29, -7 }, { 29, -6 }, { 29, -1 }, { 29, 0 },
{ 29, 1 }, { 29, 2 }, { 29, 3 }, { 29, 4 }, { 29, 9 }, { 29, 10 }, { 29, 11 }, { 29, 12 }, { 29, 13 }, { 29, 14 }, { 29, 21 }, { 29, 22 }, { 29, 23 }, { 29, 24 }, { 29, 29 }, { 29, 30 }, { 29, 31 }, { 29, 32 }, { 29, 33 }, { 29, 34 }, { 29, 35 }, { 29, 36 }, { 30, -33 }, { 30, -32 }, { 30, -31 }, { 30, -30 }, { 30, -29 }, { 30, -28 }, { 30, -27 }, { 30, -26 },
{ 30, -22 }, { 30, -21 }, { 30, -20 }, { 30, -19 }, { 30, -18 }, { 30, -11 }, { 30, -10 }, { 30, -9 }, { 30, -8 }, { 30, -7 }, { 30, -6 }, { 30, -5 }, { 30, -1 }, { 30, 0 }, { 30, 1 }, { 30, 2 }, { 30, 3 }, { 30, 4 }, { 30, 8 }, { 30, 9 }, { 30, 10 }, { 30, 11 }, { 30, 12 }, { 30, 13 }, { 30, 14 }, { 30, 21 }, { 30, 22 }, { 30, 23 }, { 30, 24 }, { 30, 25 },
{ 30, 29 }, { 30, 30 }, { 30, 31 }, { 30, 32 }, { 30, 33 }, { 30, 34 }, { 30, 35 }, { 30, 36 }, { 31, -32 }, { 31, -31 }, { 31, -30 }, { 31, -29 }, { 31, -28 }, { 31, -27 }, { 31, -23 }, { 31, -22 }, { 31, -21 }, { 31, -15 }, { 31, -14 }, { 31, -6 }, { 31, -5 }, { 31, -4 }, { 31, -1 }, { 31, 0 }, { 31, 3 }, { 31, 4 }, { 31, 7 }, { 31, 8 }, { 31, 9 }, { 31, 17 },
{ 31, 18 }, { 31, 24 }, { 31, 25 }, { 31, 26 }, { 31, 30 }, { 31, 31 }, { 31, 32 }, { 31, 33 }, { 31, 34 }, { 31, 35 }, { 32, -31 }, { 32, -30 }, { 32, -29 }, { 32, -28 }, { 32, -23 }, { 32, -22 }, { 32, -16 }, { 32, -15 }, { 32, -14 }, { 32, -5 }, { 32, -4 }, { 32, -1 }, { 32, 0 }, { 32, 3 }, { 32, 4 }, { 32, 7 }, { 32, 8 }, { 32, 17 }, { 32, 18 }, { 32, 19 },
{ 32, 25 }, { 32, 26 }, { 32, 31 }, { 32, 32 }, { 32, 33 }, { 32, 34 }, { 33, -30 }, { 33, -29 }, { 33, -28 }, { 33, -23 }, { 33, -22 }, { 33, -17 }, { 33, -16 }, { 33, -15 }, { 33, -11 }, { 33, -10 }, { 33, -9 }, { 33, -8 }, { 33, 11 }, { 33, 12 }, { 33, 13 }, { 33, 14 }, { 33, 18 }, { 33, 19 }, { 33, 20 }, { 33, 25 }, { 33, 26 }, { 33, 31 }, { 33, 32 }, { 33, 33 },
{ 34, -29 }, { 34, -28 }, { 34, -23 }, { 34, -22 }, { 34, -17 }, { 34, -16 }, { 34, -12 }, { 34, -11 }, { 34, -10 }, { 34, -9 }, { 34, -8 }, { 34, 11 }, { 34, 12 }, { 34, 13 }, { 34, 14 }, { 34, 15 }, { 34, 19 }, { 34, 20 }, { 34, 25 }, { 34, 26 }, { 34, 31 }, { 34, 32 }, { 35, -17 }, { 35, -16 }, { 35, -13 }, { 35, -12 }, { 35, -11 }, { 35, -10 }, { 35, -9 }, { 35, -3 },
{ 35, -2 }, { 35, -1 }, { 35, 0 }, { 35, 3 }, { 35, 4 }, { 35, 5 }, { 35, 6 }, { 35, 12 }, { 35, 13 }, { 35, 14 }, { 35, 15 }, { 35, 16 }, { 35, 19 }, { 35, 20 }, { 36, -17 }, { 36, -16 }, { 36, -13 }, { 36, -12 }, { 36, -11 }, { 36, -10 }, { 36, -4 }, { 36, -3 }, { 36, -2 }, { 36, -1 }, { 36, 0 }, { 36, 3 }, { 36, 4 }, { 36, 5 }, { 36, 6 }, { 36, 7 },
{ 36, 13 }, { 36, 14 }, { 36, 15 }, { 36, 16 }, { 36, 19 }, { 36, 20 }, { 37, -27 }, { 37, -26 }, { 37, -25 }, { 37, -24 }, { 37, -21 }, { 37, -20 }, { 37, -13 }, { 37, -12 }, { 37, -5 }, { 37, -4 }, { 37, -3 }, { 37, -2 }, { 37, -1 }, { 37, 0 }, { 37, 1 }, { 37, 2 }, { 37, 3 }, { 37, 4 }, { 37, 5 }, { 37, 6 }, { 37, 7 }, { 37, 8 }, { 37, 15 }, { 37, 16 },
{ 37, 23 }, { 37, 24 }, { 37, 27 }, { 37, 28 }, { 37, 29 }, { 37, 30 }, { 38, -27 }, { 38, -26 }, { 38, -25 }, { 38, -24 }, { 38, -21 }, { 38, -20 }, { 38, -19 }, { 38, -13 }, { 38, -12 }, { 38, -5 }, { 38, -4 }, { 38, -3 }, { 38, -2 }, { 38, -1 }, { 38, 0 }, { 38, 1 }, { 38, 2 }, { 38, 3 }, { 38, 4 }, { 38, 5 }, { 38, 6 }, { 38, 7 }, { 38, 8 }, { 38, 15 },
{ 38, 16 }, { 38, 22 }, { 38, 23 }, { 38, 24 }, { 38, 27 }, { 38, 28 }, { 38, 29 }, { 38, 30 }, { 39, -26 }, { 39, -25 }, { 39, -24 }, { 39, -20 }, { 39, -19 }, { 39, -18 }, { 39, -13 }, { 39, -12 }, { 39, -11 }, { 39, -10 }, { 39, -5 }, { 39, -4 }, { 39, 7 }, { 39, 8 }, { 39, 13 }, { 39, 14 }, { 39, 15 }, { 39, 16 }, { 39, 21 }, { 39, 22 }, { 39, 23 }, { 39, 27 },
{ 39, 28 }, { 39, 29 }, { 40, -25 }, { 40, -24 }, { 40, -19 }, { 40, -18 }, { 40, -13 }, { 40, -12 }, { 40, -11 }, { 40, -10 }, { 40, -5 }, { 40, -4 }, { 40, 7 }, { 40, 8 }, { 40, 13 }, { 40, 14 }, { 40, 15 }, { 40, 16 }, { 40, 21 }, { 40, 22 }, { 40, 27 }, { 40, 28 }, { 41, -19 }, { 41, -18 }, { 41, -1 }, { 41, 0 }, { 41, 1 }, { 41, 2 }, { 41, 3 }, { 41, 4 },
{ 41, 21 }, { 41, 22 }, { 42, -19 }, { 42, -18 }, { 42, -17 }, { 42, -1 }, { 42, 0 }, { 42, 1 }, { 42, 2 }, { 42, 3 }, { 42, 4 }, { 42, 20 }, { 42, 21 }, { 42, 22 }, { 43, -18 }, { 43, -17 }, { 43, -16 }, { 43, -15 }, { 43, -14 }, { 43, -13 }, { 43, -12 }, { 43, -9 }, { 43, -8 }, { 43, -1 }, { 43, 0 }, { 43, 1 }, { 43, 2 }, { 43, 3 }, { 43, 4 }, { 43, 11 },
{ 43, 12 }, { 43, 15 }, { 43, 16 }, { 43, 17 }, { 43, 18 }, { 43, 19 }, { 43, 20 }, { 43, 21 }, { 44, -17 }, { 44, -16 }, { 44, -15 }, { 44, -14 }, { 44, -13 }, { 44, -12 }, { 44, -9 }, { 44, -8 }, { 44, -7 }, { 44, -2 }, { 44, -1 }, { 44, 0 }, { 44, 1 }, { 44, 2 }, { 44, 3 }, { 44, 4 }, { 44, 5 }, { 44, 10 }, { 44, 11 }, { 44, 12 }, { 44, 15 }, { 44, 16 },
{ 44, 17 }, { 44, 18 }, { 44, 19 }, { 44, 20 }, { 45, -8 }, { 45, -7 }, { 45, -6 }, { 45, -5 }, { 45, -4 }, { 45, -3 }, { 45, -2 }, { 45, -1 }, { 45, 4 }, { 45, 5 }, { 45, 6 }, { 45, 7 }, { 45, 8 }, { 45, 9 }, { 45, 10 }, { 45, 11 }, { 46, -7 }, { 46, -6 }, { 46, -5 }, { 46, -4 }, { 46, -3 }, { 46, -2 }, { 46, 5 }, { 46, 6 }, { 46, 7 }, { 46, 8 },
{ 46, 9 }, { 46, 10 }, { 47, -4 }, { 47, -3 }, { 47, -2 }, { 47, 1 }, { 47, 2 }, { 47, 5 }, { 47, 6 }, { 47, 7 }, { 48, -3 }, { 48, -2 }, { 48, 1 }, { 48, 2 }, { 48, 5 }, { 48, 6 },
},
},
resource_tiles = {
enabled = false,
resources = {
{
enabled = false,
name = 'iron-ore',
name = "iron-ore",
amount = 4000,
size = {26, 27},
size = { 26, 27 },
-- offset = {-64,-32}
offset = {-64,-64}
offset = { -64, -64 },
},
{
enabled = false,
name = 'copper-ore',
name = "copper-ore",
amount = 4000,
size = {26, 27},
size = { 26, 27 },
-- offset = {-64, 0}
offset = {64, -64}
offset = { 64, -64 },
},
{
enabled = false,
name = 'stone',
name = "stone",
amount = 4000,
size = {22, 20},
size = { 22, 20 },
-- offset = {-64, 32}
offset = {-64, 64}
offset = { -64, 64 },
},
{
enabled = false,
name = 'coal',
name = "coal",
amount = 4000,
size = {22, 20},
size = { 22, 20 },
-- offset = {-64, -64}
offset = {64, 64}
offset = { 64, 64 },
},
{
enabled = false,
name = 'uranium-ore',
name = "uranium-ore",
amount = 4000,
size = {22, 20},
size = { 22, 20 },
-- offset = {-64, -96}
offset = {0, 64}
}
}
offset = { 0, 64 },
},
},
},
resource_patches = {
enabled = false,
resources = {
{
enabled = false,
name = 'crude-oil',
name = "crude-oil",
num_patches = 4,
amount = 4000000,
-- offset = {-80, -12},
offset = {-12, 64},
offset = { -12, 64 },
-- offset_next = {0, 6}
offset_next = {6, 0}
}
}
offset_next = { 6, 0 },
},
},
},
resource_refill_nearby = {
enabled = false,
range = 128,
resources_name = {
'iron-ore',
'copper-ore',
'stone',
'coal',
'uranium-ore'
"iron-ore",
"copper-ore",
"stone",
"coal",
"uranium-ore",
},
amount = {2500, 4000}
}
}
amount = { 2500, 4000 },
},
}

View File

@@ -7,5 +7,5 @@ return {
__x__
__y__
]]
station_name = '[L] __icon__'
}
station_name = "[L] __icon__",
}

View File

@@ -27,20 +27,20 @@ return {
JoinCount = e.on_player_joined_game,
TilesRemoved = e.on_player_mined_tile,
CapsulesUsed = e.on_player_used_capsule,
EntityRepaired= e.on_player_repaired_entity
EntityRepaired = e.on_player_repaired_entity,
},
display_order = { --- @setting display_order The order that the statistics should be shown in when in a gui or command
'Playtime', 'AfkTime',
'MapsPlayed', 'JoinCount',
'ChatMessages', 'CommandsUsed',
'RocketsLaunched', 'ResearchCompleted',
'MachinesBuilt', 'MachinesRemoved',
'TilesBuilt', 'TilesRemoved',
'TreesDestroyed', 'OreMined',
'ItemsCrafted', 'ItemsPickedUp',
'Kills', 'Deaths',
'DamageDealt', 'DistanceTravelled',
'CapsulesUsed', 'EntityRepaired',
'DeconstructionPlannerUsed', 'MapTagsMade'
}
}
"Playtime", "AfkTime",
"MapsPlayed", "JoinCount",
"ChatMessages", "CommandsUsed",
"RocketsLaunched", "ResearchCompleted",
"MachinesBuilt", "MachinesRemoved",
"TilesBuilt", "TilesRemoved",
"TreesDestroyed", "OreMined",
"ItemsCrafted", "ItemsPickedUp",
"Kills", "Deaths",
"DamageDealt", "DistanceTravelled",
"CapsulesUsed", "EntityRepaired",
"DeconstructionPlannerUsed", "MapTagsMade",
},
}

View File

@@ -10,7 +10,7 @@ return {
unlimited_surface_area = false, --- @setting unlimited_surface_area When true the vlayer has an unlimited surface area, landfill is not required
modded_auto_downgrade = false, --- @setting modded_auto_downgrade When true modded items will be converted into their base game equivalent, original items can not be recovered
mimic_surface = 'nauvis', --- @setting mimic_surface Surface name/index the vlayer will copy its settings from, use nil to use the settings below
mimic_surface = "nauvis", --- @setting mimic_surface Surface name/index the vlayer will copy its settings from, use nil to use the settings below
surface = { --- @setting surface When mimic_surface is nil these settings will be used instead, see LuaSurface for details
always_day = false,
solar_power_multiplier = 1,
@@ -20,14 +20,14 @@ return {
dusk = 0.25,
evening = 0.45,
morning = 0.55,
dawn = 0.75
dawn = 0.75,
},
interface_limit = { --- @setting interface_limit Sets the limit for the number of vlayer interfaces that can be created
energy = 1, -- >1 allows for disconnected power networks to receive power
circuit = 10, -- No caveats
storage_input = 10, -- No caveats
storage_output = 1 -- >0 allows for item teleportation (allowed_items only)
storage_output = 1, -- >0 allows for item teleportation (allowed_items only)
},
allowed_items = { --- @setting allowed_items List of all items allowed in vlayer storage and their properties
@@ -40,36 +40,36 @@ return {
capacity = 0: The energy capacity of the item in MJ, used for accumulators
surface_area = 0: The surface area provided by the item, used for landfill
]]
['solar-panel'] = {
["solar-panel"] = {
starting_value = 0,
required_area = 9,
production = 0.06 -- MW
production = 0.06, -- MW
},
['accumulator'] = {
["accumulator"] = {
starting_value = 0,
required_area = 4,
discharge = 0.3, -- MW
capacity = 5 -- MJ
capacity = 5, -- MJ
},
['landfill'] = {
["landfill"] = {
starting_value = 0,
required_area = 0,
surface_area = 6 -- Tiles
surface_area = 6, -- Tiles
},
['wood'] = {
["wood"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 2, -- MJ
power = true -- turn all wood to power to reduce trash
power = true, -- turn all wood to power to reduce trash
},
['coal'] = {
["coal"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 4, -- MJ
power = false -- turn all coal to power to reduce trash
}
power = false, -- turn all coal to power to reduce trash
},
--[[
['iron-ore'] = {
starting_value = 0,
@@ -100,75 +100,75 @@ return {
},
modded_items = { --- @setting modded_items List of all modded items allowed in vlayer storage and their base game equivalent
['solar-panel-2'] = {
["solar-panel-2"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 4
base_game_equivalent = "solar-panel",
multiplier = 4,
},
['solar-panel-3'] = {
["solar-panel-3"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 16
base_game_equivalent = "solar-panel",
multiplier = 16,
},
['solar-panel-4'] = {
["solar-panel-4"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 64
base_game_equivalent = "solar-panel",
multiplier = 64,
},
['solar-panel-5'] = {
["solar-panel-5"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 256
base_game_equivalent = "solar-panel",
multiplier = 256,
},
['solar-panel-6'] = {
["solar-panel-6"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 1024
base_game_equivalent = "solar-panel",
multiplier = 1024,
},
['solar-panel-7'] = {
["solar-panel-7"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 4096
base_game_equivalent = "solar-panel",
multiplier = 4096,
},
['solar-panel-8'] = {
["solar-panel-8"] = {
starting_value = 0,
base_game_equivalent = 'solar-panel',
multiplier = 16384
base_game_equivalent = "solar-panel",
multiplier = 16384,
},
['accumulator-2'] = {
["accumulator-2"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 4
base_game_equivalent = "accumulator",
multiplier = 4,
},
['accumulator-3'] = {
["accumulator-3"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 16
base_game_equivalent = "accumulator",
multiplier = 16,
},
['accumulator-4'] = {
["accumulator-4"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 64
base_game_equivalent = "accumulator",
multiplier = 64,
},
['accumulator-5'] = {
["accumulator-5"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 256
base_game_equivalent = "accumulator",
multiplier = 256,
},
['accumulator-6'] = {
["accumulator-6"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 1024
base_game_equivalent = "accumulator",
multiplier = 1024,
},
['accumulator-7'] = {
["accumulator-7"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 4096
base_game_equivalent = "accumulator",
multiplier = 4096,
},
['accumulator-8'] = {
["accumulator-8"] = {
starting_value = 0,
base_game_equivalent = 'accumulator',
multiplier = 16384
base_game_equivalent = "accumulator",
multiplier = 16384,
},
}
},
}

View File

@@ -4,18 +4,18 @@
return {
actions = { --- @setting actions what actions are taking at number of warnings
-- if a localized string is used then __1__ will by_player_name and __2__ will be the current warning count (auto inserted)
{'warnings.received',''},
{'warnings.received',''},
{'warnings.received',{'warnings.pre-kick'}},
function(player,by_player_name,number_of_warnings)
game.kick_player(player,{'warnings.received',by_player_name,number_of_warnings,{'warnings.kick'}})
{ "warnings.received", "" },
{ "warnings.received", "" },
{ "warnings.received", { "warnings.pre-kick" } },
function(player, by_player_name, number_of_warnings)
game.kick_player(player, { "warnings.received", by_player_name, number_of_warnings, { "warnings.kick" } })
end,
{ "warnings.received", { "warnings.pre-pre-ban" } },
{ "warnings.received", { "warnings.pre-ban" } },
function(player, by_player_name, number_of_warnings)
game.ban_player(player, { "warnings.received", by_player_name, number_of_warnings, { "warnings.ban", { "links.website" } } })
end,
{'warnings.received',{'warnings.pre-pre-ban'}},
{'warnings.received',{'warnings.pre-ban'}},
function(player,by_player_name,number_of_warnings)
game.ban_player(player,{'warnings.received',by_player_name,number_of_warnings,{'warnings.ban',{'links.website'}}})
end
},
script_warning_cool_down=30, --- @setting script_warning_cool_down time for a script warning (given by script) to be removed (in minutes)
script_warning_limit=5 --- @setting script_warning_limit the number of script warnings (given by script) that are allowed before full warnings are given
}
script_warning_cool_down = 30, --- @setting script_warning_cool_down time for a script warning (given by script) to be removed (in minutes)
script_warning_limit = 5, --- @setting script_warning_limit the number of script warnings (given by script) that are allowed before full warnings are given
}

View File

@@ -1,18 +1,17 @@
--- Please go to ./config if you want to change settings, each file is commented with what it does
-- if it is not in ./config then you should not attempt to change it unless you know what you are doing
-- all files which are loaded (including the config files) are present in ./config/file_loader.lua
-- this file is the landing point for all scenarios please DO NOT edit directly, further comments are to aid development
local _xpcall = xpcall
xpcall = function (func, error_handler, ...)
xpcall = function(func, error_handler, ...)
local rtn = { _xpcall(func, error_handler, ...) }
if not rtn[1] then error(rtn[2]) end
return table.unpack(rtn)
end
log('[START] -----| Explosive Gaming Scenario Loader |-----')
log('[INFO] Setting up lua environment')
log("[START] -----| Explosive Gaming Scenario Loader |-----")
log("[INFO] Setting up lua environment")
-- Require the global overrides
require("modules.exp_legacy.overrides.table") -- Adds alot more functions to the table module
@@ -20,38 +19,39 @@ storage.version = require("modules.exp_legacy.overrides.version") -- The current
_C = require("modules.exp_legacy.expcore.common") -- _C is used to store lots of common functions expected to be used
-- Please go to config/file_loader.lua to edit the files that are loaded
log('[INFO] Reading loader config')
log("[INFO] Reading loader config")
local files = require("modules.exp_legacy.config._file_loader")
-- Error handler for loading files
local errors = {}
local error_count = 0
local error_format = '[ERROR] %s :: %s'
local error_format = "[ERROR] %s :: %s"
local currently_loading = nil
local function error_handler(err)
error_count = error_count + 1
if err:find('module '..currently_loading..' not found;', nil, true) then
log('[ERROR] File not found: '..currently_loading)
if err:find("module " .. currently_loading .. " not found;", nil, true) then
log("[ERROR] File not found: " .. currently_loading)
errors[error_count] = error_format:format(currently_loading, err)
else
log('[ERROR] Failed to load: '..currently_loading)
log("[ERROR] Failed to load: " .. currently_loading)
errors[error_count] = debug.traceback(error_format:format(currently_loading, err))
end
end
-- Loads all files from the config and logs that they are loaded
local total_file_count = string.format('%3d', #files)
local total_file_count = string.format("%3d", #files)
for index, path in pairs(files) do
currently_loading = path
log(string.format('[INFO] Loading file %3d/%s (%s)', index, total_file_count, path))
log(string.format("[INFO] Loading file %3d/%s (%s)", index, total_file_count, path))
xpcall(require, error_handler, "modules.exp_legacy." .. path)
end
-- Logs all errors again to make it make it easy to find
log('[INFO] All files loaded with '..error_count..' errors:')
log("[INFO] All files loaded with " .. error_count .. " errors:")
for _, error in ipairs(errors) do log(error) end
log('[END] -----| Explosive Gaming Scenario Loader |-----')
log("[END] -----| Explosive Gaming Scenario Loader |-----")
--- Register all event handlers via clusterio
local Event = require("modules/exp_legacy/utils/event")
return Event.real_handlers
return Event.real_handlers

View File

@@ -191,9 +191,9 @@ local trace = debug.traceback
local Commands = {
--- Constant values used by the command system
defines = {
error = 'CommandError',
unauthorized = 'CommandErrorUnauthorized',
success = 'CommandSuccess'
error = "CommandError",
unauthorized = "CommandErrorUnauthorized",
success = "CommandSuccess",
},
--- An array of all custom commands that are registered
commands = {},
@@ -243,7 +243,7 @@ Commands.remove_authenticator(admin_authenticator)
]]
function Commands.remove_authenticator(authenticator)
if type(authenticator) == 'number' then
if type(authenticator) == "number" then
-- If a number is passed then it is assumed to be the index
if Commands.authenticators[authenticator] then
Commands.authenticators[authenticator] = nil
@@ -281,15 +281,15 @@ function Commands.authorize(player, command_name)
-- This is the reject function given to authenticators
local failure_message
local function reject(message)
failure_message = message or {'expcore-commands.unauthorized'}
failure_message = message or { "expcore-commands.unauthorized" }
return Commands.defines.unauthorized
end
-- This is the internal error function used when an authenticator errors
local function authenticator_error(err)
log('[ERROR] Authorization failed: '..trace(err))
log("[ERROR] Authorization failed: " .. trace(err))
if Commands.authorization_failure_on_error then
return reject('Internal Error')
return reject("Internal Error")
end
end
@@ -298,7 +298,7 @@ function Commands.authorize(player, command_name)
-- player: LuaPlayer, command: string, flags: table, reject: function(error_message: string)
local _, rtn = xpcall(authenticator, authenticator_error, player, command_name, command_data.flags, reject)
if rtn == false or rtn == Commands.defines.unauthorized or rtn == reject or failure_message ~= nil then
if failure_message == nil then failure_message = {'expcore-commands.unauthorized'} end
if failure_message == nil then failure_message = { "expcore-commands.unauthorized" } end
return false, failure_message
end
end
@@ -370,7 +370,10 @@ end)
function Commands.parse(name, input, player, reject, ...)
if not Commands.parsers[name] then return end
local success, rtn = pcall(Commands.parsers[name], input, player, reject, ...)
if not success then error(rtn, 2) return end
if not success then
error(rtn, 2)
return
end
if not rtn or rtn == Commands.defines.error then return end
return rtn
end
@@ -398,6 +401,7 @@ function Commands.get(player)
allowed[name] = command_data
end
end
return allowed
end
@@ -420,12 +424,13 @@ function Commands.search(keyword, player)
-- Loops over custom commands
for name, command_data in pairs(custom_commands) do
-- combines name help and aliases into one message to be searched
local search = string.format('%s %s %s %s', name, command_data.help, command_data.searchable_description, table.concat(command_data.aliases, ' '))
local search = string.format("%s %s %s %s", name, command_data.help, command_data.searchable_description, table.concat(command_data.aliases, " "))
if search:lower():match(keyword) then
matches[name] = command_data
end
end
-- Loops over the names of game commands
for name, description in pairs(commands.game_commands) do
if name:lower():match(keyword) then
@@ -433,11 +438,12 @@ function Commands.search(keyword, player)
matches[name] = {
name = name,
help = description,
description = '',
aliases = {}
description = "",
aliases = {},
}
end
end
return matches
end
@@ -458,16 +464,16 @@ function Commands.new_command(name, help, descr)
local command = setmetatable({
name = name,
help = help,
searchable_description = descr or '',
callback = function() Commands.internal_error(false, name, 'No callback registered') end,
searchable_description = descr or "",
callback = function() Commands.internal_error(false, name, "No callback registered") end,
auto_concat = false,
min_param_count = 0,
max_param_count = 0,
flags = {}, -- stores flags that can be used by auth
flags = {}, -- stores flags that can be used by auth
aliases = {}, -- stores aliases to this command
params = {}, -- [param_name] = {optional: boolean, default: any, parse: function, parse_args: table}
params = {}, -- [param_name] = {optional: boolean, default: any, parse: function, parse_args: table}
}, {
__index = Commands._prototype
__index = Commands._prototype,
})
Commands.commands[name] = command
return command
@@ -491,17 +497,17 @@ end)
]]
function Commands._prototype:add_param(name, optional, parse, ...)
local parse_args = {...}
if type(optional) ~= 'boolean' then
parse_args = {parse, ...}
local parse_args = { ... }
if type(optional) ~= "boolean" then
parse_args = { parse, ... }
parse = optional
optional = false
end
self.params[name] = {
optional = optional,
parse = parse or function(string) return string end,
parse_args = parse_args
optional = optional,
parse = parse or function(string) return string end,
parse_args = parse_args,
}
self.max_param_count = self.max_param_count + 1
@@ -532,6 +538,7 @@ function Commands._prototype:set_defaults(defaults)
self.params[name].default = value
end
end
return self
end
@@ -562,9 +569,10 @@ command:add_alias('name', 'rname')
]]
function Commands._prototype:add_alias(...)
local start_index = #self.aliases
for index, alias in ipairs{...} do
self.aliases[start_index+index] = alias
for index, alias in ipairs{ ... } do
self.aliases[start_index + index] = alias
end
return self
end
@@ -600,14 +608,15 @@ function Commands._prototype:register(callback)
self.callback = callback
-- Generates a description to be used
local description = ''
local description = ""
for param_name, param_details in pairs(self.params) do
if param_details.optional then
description = string.format('%s [%s]', description, param_name)
description = string.format("%s [%s]", description, param_name)
else
description = string.format('%s <%s>', description, param_name)
description = string.format("%s <%s>", description, param_name)
end
end
self.description = description
-- Last resort error handler for commands
@@ -622,7 +631,7 @@ function Commands._prototype:register(callback)
end
-- Registers the command under its own name
local help = {'expcore-commands.command-help', description, self.help}
local help = { "expcore-commands.command-help", description, self.help }
commands.add_command(self.name, help, command_callback)
-- Adds any aliases that it has
@@ -650,7 +659,7 @@ return 'Your message has been printed'
]]
function Commands.success(value)
if value ~= nil then player_return(value) end
player_return({'expcore-commands.command-ran'}, 'cyan')
player_return({ "expcore-commands.command-ran" }, "cyan")
return Commands.defines.success
end
@@ -675,11 +684,11 @@ return Commands.error('The player you selected is offline')
]]
function Commands.error(error_message, play_sound)
error_message = error_message or ''
player_return({'expcore-commands.command-fail', error_message}, 'orange_red')
error_message = error_message or ""
player_return({ "expcore-commands.command-fail", error_message }, "orange_red")
if play_sound ~= false then
play_sound = play_sound or 'utility/wire_pickup'
if game.player then game.player.play_sound{path=play_sound} end
play_sound = play_sound or "utility/wire_pickup"
if game.player then game.player.play_sound{ path = play_sound } end
end
return Commands.defines.error
end
@@ -700,22 +709,22 @@ end
]]
function Commands.internal_error(success, command_name, error_message)
if not success then
Commands.error('Internal Error, Please contact an admin', 'utility/cannot_build')
log{'expcore-commands.command-error-log-format', command_name, error_message}
Commands.error("Internal Error, Please contact an admin", "utility/cannot_build")
log{ "expcore-commands.command-error-log-format", command_name, error_message }
end
return not success
end
--- Logs command usage to file
local function command_log(player, command, comment, params, raw, details)
local player_name = player and player.name or '<Server>'
write_json('log/commands.log', {
player_name = player_name,
local player_name = player and player.name or "<Server>"
write_json("log/commands.log", {
player_name = player_name,
command_name = command.name,
comment = comment,
details = details,
params = params,
raw = raw
comment = comment,
details = details,
params = params,
raw = raw,
})
end
@@ -733,46 +742,46 @@ function Commands.run_command(command_event)
-- Check if the player is allowed to use the command
local authorized, auth_fail = Commands.authorize(player, command_data.name)
if not authorized then
command_log(player, command_data, 'Failed Auth', {}, command_event.parameter)
Commands.error(auth_fail, 'utility/cannot_build')
command_log(player, command_data, "Failed Auth", {}, command_event.parameter)
Commands.error(auth_fail, "utility/cannot_build")
return
end
-- Check for parameter being nil
if command_data.min_param_count > 0 and not command_event.parameter then
command_log(player, command_data, 'No Params Given', {}, command_event.parameter)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "No Params Given", {}, command_event.parameter)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
end
-- Extract quoted arguments
local raw_input = command_event.parameter or ''
local raw_input = command_event.parameter or ""
local quote_params = {}
local input_string = raw_input:gsub('"[^"]-"', function(word)
local no_spaces = word:gsub('%s', '%%s')
local no_spaces = word:gsub("%s", "%%s")
quote_params[no_spaces] = word:sub(2, -2)
return ' '..no_spaces..' '
return " " .. no_spaces .. " "
end)
-- Extract unquoted arguments
local raw_params = {}
local last_index = 0
local param_number = 0
for word in input_string:gmatch('%S+') do
for word in input_string:gmatch("%S+") do
param_number = param_number + 1
if param_number > command_data.max_param_count then
-- there are too many params given to the command
if not command_data.auto_concat then
-- error as they should not be more
command_log(player, command_data, 'Invalid Input: Too Many Params', raw_params, raw_input)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "Invalid Input: Too Many Params", raw_params, raw_input)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
else
-- concat to the last param
if quote_params[word] then
raw_params[last_index] = raw_params[last_index]..' "'..quote_params[word]..'"'
raw_params[last_index] = raw_params[last_index] .. ' "' .. quote_params[word] .. '"'
else
raw_params[last_index] = raw_params[last_index]..' '..word
raw_params[last_index] = raw_params[last_index] .. " " .. word
end
end
else
@@ -790,8 +799,8 @@ function Commands.run_command(command_event)
-- Check the param count
local param_count = #raw_params
if param_count < command_data.min_param_count then
command_log(player, command_data, 'Invalid Input: Not Enough Params', raw_params, raw_input)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "Invalid Input: Not Enough Params", raw_params, raw_input)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
end
@@ -801,48 +810,46 @@ function Commands.run_command(command_event)
for param_name, param_data in pairs(command_data.params) do
local parse_callback = param_data.parse
-- If its a string this get it from the parser table
if type(parse_callback) == 'string' then
if type(parse_callback) == "string" then
parse_callback = Commands.parsers[parse_callback]
end
-- If its not a function throw and error
if type(parse_callback) ~= 'function' then
Commands.internal_error(false, command_data.name, 'Invalid param parse '..tostring(param_data.parse))
command_log(player, command_data, 'Internal Error: Invalid Param Parse', params, raw_input, tostring(param_data.parse))
if type(parse_callback) ~= "function" then
Commands.internal_error(false, command_data.name, "Invalid param parse " .. tostring(param_data.parse))
command_log(player, command_data, "Internal Error: Invalid Param Parse", params, raw_input, tostring(param_data.parse))
return
end
-- This is the reject function given to parse callbacks
local function reject(error_message)
error_message = error_message or ''
command_log(player, command_data, 'Invalid Param Given', raw_params, input_string)
return Commands.error{'expcore-commands.invalid-param', param_name, error_message}
error_message = error_message or ""
command_log(player, command_data, "Invalid Param Given", raw_params, input_string)
return Commands.error{ "expcore-commands.invalid-param", param_name, error_message }
end
-- input: string, player: LuaPlayer, reject: function, ... extra args
local success, param_parsed = pcall(parse_callback, raw_params[index], player, reject, table.unpack(param_data.parse_args))
if Commands.internal_error(success, command_data.name, param_parsed) then
return command_log(player, command_data, 'Internal Error: Param Parse Fail', params, raw_input, param_parsed)
return command_log(player, command_data, "Internal Error: Param Parse Fail", params, raw_input, param_parsed)
end
if param_data.optional == true and raw_params[index] == nil then
-- If the param is optional and nil then it is set to default
param_parsed = param_data.default
if type(param_parsed) == 'function' then
if type(param_parsed) == "function" then
success, param_parsed = pcall(param_parsed, player)
if Commands.internal_error(success, command_data.name, param_parsed) then
return command_log(player, command_data, 'Internal Error: Default Value Fail', params, raw_input, param_parsed)
return command_log(player, command_data, "Internal Error: Default Value Fail", params, raw_input, param_parsed)
end
end
elseif param_parsed == nil or param_parsed == Commands.defines.error or param_parsed == reject then
-- No value was returned or error was returned, if nil then give generic error
if param_parsed ~= Commands.defines.error then
command_log(player, command_data, 'Invalid Param Given', raw_params, raw_input, param_name)
Commands.error{'expcore-commands.command-error-param-format', param_name, 'please make sure it is the correct type'}
command_log(player, command_data, "Invalid Param Given", raw_params, raw_input, param_name)
Commands.error{ "expcore-commands.command-error-param-format", param_name, "please make sure it is the correct type" }
end
return
end
-- Add the param to the table to be passed to the command callback
@@ -852,19 +859,19 @@ function Commands.run_command(command_event)
-- Run the command
-- player: LuaPlayer, ... command params, raw: string
params[command_data.max_param_count+1] = raw_input
params[command_data.max_param_count + 1] = raw_input
local success, rtn = pcall(command_data.callback, player, table.unpack(params))
if Commands.internal_error(success, command_data.name, rtn) then
return command_log(player, command_data, 'Internal Error: Command Callback Fail', raw_params, command_event.parameter, rtn)
return command_log(player, command_data, "Internal Error: Command Callback Fail", raw_params, command_event.parameter, rtn)
end
-- Give output to the player
if rtn == Commands.defines.error or rtn == Commands.error then
return command_log(player, command_data, 'Custom Error', raw_params, raw_input)
return command_log(player, command_data, "Custom Error", raw_params, raw_input)
elseif rtn ~= Commands.defines.success and rtn ~= Commands.success then
Commands.success(rtn)
end
command_log(player, command_data, 'Success', raw_params, raw_input)
command_log(player, command_data, "Success", raw_params, raw_input)
end
return Commands

View File

@@ -40,7 +40,7 @@ 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
level = level and level + 1 or 2
return Common.type_check(value, test_type) or error(error_message, level)
end
@@ -60,6 +60,7 @@ function Common.multi_type_check(value, test_types)
return true
end
end
return false
end
@@ -75,7 +76,7 @@ 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
level = level and level + 1 or 2
return Common.mult_type_check(value, test_types) or error(error_message, level)
end
@@ -95,12 +96,12 @@ 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 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)
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)
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
@@ -123,12 +124,12 @@ 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 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 '))
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 '))
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
@@ -139,8 +140,8 @@ end
-- @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)
local function_name = debug.getinfo(2, "n").name or "<anon>"
error(function_name .. " can not be called during runtime", 3)
end
end
@@ -171,7 +172,7 @@ local value = Common.resolve_value(self.defaut_value, self)
]]
function Common.resolve_value(value, ...)
return value and type(value) == 'function' and value(...) or value
return value and type(value) == "function" and value(...) or value
end
--- Converts a varible into its boolean value, nil and false return false
@@ -190,8 +191,8 @@ 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
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.
@@ -218,7 +219,7 @@ write_json('dump', tbl)
]]
function Common.write_json(path, tbl)
game.write_file(path, game.table_to_json(tbl)..'\n', true, 0)
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
@@ -232,8 +233,11 @@ 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
if success then
return rtn
else
return nil, rtn
end
end
--[[-- Returns a desync safe file path for the current file
@@ -246,7 +250,7 @@ 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)
return debug.getinfo(offset + 2, "S").short_src:sub(10, -5)
end
--[[-- Converts a table to an enum
@@ -264,18 +268,21 @@ local colors = enum{
function Common.enum(tbl)
local rtn = {}
for k, v in pairs(tbl) do
if type(k) ~= 'number' then
rtn[v]=k
if type(k) ~= "number" then
rtn[v] = k
end
end
for k, v in pairs(tbl) do
if type(k) == 'number' then
if type(k) == "number" then
table.insert(rtn, v)
end
end
for k, v in pairs(rtn) do
rtn[v]=k
rtn[v] = k
end
return rtn
end
@@ -297,7 +304,7 @@ 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
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
@@ -319,7 +326,7 @@ local player_name = get_actor()
]]
function Common.get_actor(player_name)
return game.player and game.player.name or player_name or '<server>'
return game.player and game.player.name or player_name or "<server>"
end
--[[-- Returns a message with valid chat tags to change its colour
@@ -333,8 +340,8 @@ 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)
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
@@ -348,8 +355,8 @@ local message = format_chat_colour_localized('Hello, World!', { r=355, g=100, b=
]]
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}
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
@@ -363,7 +370,7 @@ 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_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)
@@ -388,37 +395,41 @@ 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
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 returnAsString
if Common.type_check(value, 'table') or type(value) == 'userdata' then
if Common.type_check(value.__self, 'userdata') or type(value) == 'userdata' then
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
returnAsString = 'Cant Display Userdata'
elseif Common.type_check(value[1], 'string') and string.find(value[1], '.+[.].+') and not string.find(value[1], '%s') then
returnAsString = "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
returnAsString = value
elseif getmetatable(value) ~= nil and not tostring(value):find('table: 0x') then
elseif getmetatable(value) ~= nil and not tostring(value):find("table: 0x") then
-- value has a tostring meta method
returnAsString = tostring(value)
else
-- value is a table
returnAsString = table.inspect(value, {depth=5, indent=' ', newline='\n'})
returnAsString = table.inspect(value, { depth = 5, indent = " ", newline = "\n" })
end
elseif Common.type_check(value, 'function') then
elseif Common.type_check(value, "function") then
-- value is a function
returnAsString = 'Cant Display Functions'
else returnAsString = tostring(value) end
returnAsString = "Cant Display Functions"
else
returnAsString = 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
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.play_sound{ path = "utility/scenario_message" }
player.print(returnAsString, colour)
else rcon.print(returnAsString) end
else
rcon.print(returnAsString)
end
end
--[[-- Formats tick into a clean format, denominations from highest to lowest
@@ -444,78 +455,78 @@ local time = format_time(18000, { hours=true, minutes=true, seconds=true, string
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
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
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), math.floor(hours), math.floor(minutes), math.floor(seconds)
if not options.days then
rtn_hours = rtn_hours + rtn_days*24
rtn_hours = rtn_hours + rtn_days * 24
end
if not options.hours then
rtn_minutes = rtn_minutes + rtn_hours*60
rtn_minutes = rtn_minutes + rtn_hours * 60
end
if not options.minutes then
rtn_seconds = rtn_seconds + rtn_minutes*60
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='--'
rtn_days = "--"
rtn_hours = "--"
rtn_minutes = "--"
rtn_seconds = "--"
end
-- Format options
local suffix = 'time-symbol-'
local suffix_2 = '-short'
local suffix = "time-symbol-"
local suffix_2 = "-short"
if options.long then
suffix = ''
suffix_2 = ''
suffix = ""
suffix_2 = ""
end
local div = options.string and ' ' or 'time-format.simple-format-tagged'
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'
div = options.string and ":" or "time-format.simple-format-div"
suffix = false
end
-- Adds formatting
if suffix ~= false then
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'
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}
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)
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
rtn = rtn and rtn .. div .. value or value
elseif dom then
rtn = rtn and {div, rtn, value} or value
rtn = rtn and { div, rtn, value } or value
end
end
append(options.days, rtn_days)
@@ -542,51 +553,52 @@ 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
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
@@ -603,23 +615,23 @@ 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]
chest_type = chest_type or "steel-chest"
surface = surface or game.surfaces[1]
if position and type(position) ~= 'table' then
if position and type(position) ~= "table" then
return
end
if type(items) ~= 'table' then
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
-- 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
@@ -664,7 +676,7 @@ function Common.move_items_stack(items, surface, position, radius, chest_type)
]]
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'}
last_entity = surface.create_entity{ name = chest_type, position = pos, force = "neutral" }
count = count + 1
entities[count] = last_entity
@@ -675,63 +687,63 @@ function Common.move_items_stack(items, surface, position, radius, chest_type)
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
-- 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
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then
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
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
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
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
-- Inserts the items into the chests
local last_chest
for i=1,#items do
local item = items[i]
for i=1,#items do
local item = items[i]
if item.valid_for_read then
local chest = next_chest(item)
local chest = next_chest(item)
if not chest or not chest.valid then
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)
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
empty_stack.transfer_stack(item)
last_chest = chest
end
end
return last_chest
]]
@@ -753,34 +765,34 @@ 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 is_string = type(value) == "string"
local color = Colours.white
local text = value
if type(immutable) ~= 'boolean' then
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)
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}
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'
text = "0.00"
end
end
if not immutable then
local text_entity = surface.find_entity('flying-text', position)
local text_entity = surface.find_entity("flying-text", position)
if text_entity then
text_entity.text = text
@@ -790,10 +802,10 @@ function Common.print_grid_value(value, surface, position, scale, offset, immuta
end
surface.create_entity{
name = 'flying-text',
name = "flying-text",
color = color,
text = text,
position = position
position = position,
}.active = false
end
@@ -805,7 +817,7 @@ clear_flying_text(game.player.surface)
]]
function Common.clear_flying_text(surface)
local entities = surface.find_entities_filtered{name ='flying-text'}
local entities = surface.find_entities_filtered{ name = "flying-text" }
for _, entity in pairs(entities) do
if entity and entity.valid then
entity.destroy()

View File

@@ -169,8 +169,8 @@ end)
--- Metatable used on datastores
DatastoreManager.metatable = {
__index = function(self, key) return rawget(self.children, key) or rawget(Datastore, key) end,
__newidnex = function(_, _, _) error('Datastore can not be modified', 2) end,
__call = function(self, ...) return self:get(...) end
__newidnex = function(_, _, _) error("Datastore can not be modified", 2) end,
__call = function(self, ...) return self:get(...) end,
}
--[[-- Make a new datastore connection, if a connection already exists then it is returned
@@ -188,7 +188,7 @@ function DatastoreManager.connect(datastoreName, saveToDisk, autoSave, propagate
if Datastores[datastoreName] then return Datastores[datastoreName] end
if package.lifecycle ~= package.lifecycle_stage.control then
-- Only allow this function to be called during the control stage
error('New datastore connection can not be created during runtime', 2)
error("New datastore connection can not be created during runtime", 2)
end
local new_datastore = {
@@ -202,7 +202,7 @@ function DatastoreManager.connect(datastoreName, saveToDisk, autoSave, propagate
children = {},
metadata = {},
events = {},
data = {}
data = {},
}
Data[datastoreName] = new_datastore.data
@@ -220,7 +220,7 @@ local BarData = Datastore.combine('ExampleData', 'Bar')
]]
function DatastoreManager.combine(datastoreName, subDatastoreName)
local datastore = assert(Datastores[datastoreName], 'Datastore not found '..tostring(datastoreName))
local datastore = assert(Datastores[datastoreName], "Datastore not found " .. tostring(datastoreName))
return datastore:combine(subDatastoreName)
end
@@ -235,27 +235,23 @@ Datastore.ingest('request', 'ExampleData', 'TestKey', 'Foo')
]]
function DatastoreManager.ingest(action, datastoreName, key, valueJson)
local datastore = assert(Datastores[datastoreName], 'Datastore ingest error, Datastore not found '..tostring(datastoreName))
assert(type(action) == 'string', 'Datastore ingest error, Action is not a string got: '..type(action))
assert(type(key) == 'string', 'Datastore ingest error, Key is not a string got: '..type(key))
local datastore = assert(Datastores[datastoreName], "Datastore ingest error, Datastore not found " .. tostring(datastoreName))
assert(type(action) == "string", "Datastore ingest error, Action is not a string got: " .. type(action))
assert(type(key) == "string", "Datastore ingest error, Key is not a string got: " .. type(key))
if action == 'remove' then
if action == "remove" then
datastore:raw_set(key)
elseif action == 'message' then
elseif action == "message" then
local success, value = pcall(game.json_to_table, valueJson)
if not success or value == nil then value = tonumber(valueJson) or valueJson end
datastore:raise_event('on_message', key, value)
elseif action == 'propagate' or action == 'request' then
datastore:raise_event("on_message", key, value)
elseif action == "propagate" or action == "request" then
local success, value = pcall(game.json_to_table, valueJson)
if not success or value == nil then value = tonumber(valueJson) or valueJson end
local old_value = datastore:raw_get(key)
value = datastore:raise_event('on_load', key, value, old_value)
value = datastore:raise_event("on_load", key, value, old_value)
datastore:set(key, value)
end
end
--[[-- Debug, Use to get all datastores, or return debug info on a datastore
@@ -270,7 +266,7 @@ local debug_info = Datastore.debug('ExampleData')
]]
function DatastoreManager.debug(datastoreName)
if not datastoreName then return Datastores end
local datastore = assert(Datastores[datastoreName], 'Datastore not found '..tostring(datastoreName))
local datastore = assert(Datastores[datastoreName], "Datastore not found " .. tostring(datastoreName))
return datastore:debug()
end
@@ -308,11 +304,13 @@ function Datastore:debug()
end
local children = {}
for name in pairs(self.children) do children[#children+1] = name end
for name in pairs(self.children) do children[#children + 1] = name end
if #children > 0 then debug_info.children = children end
local events = {}
for name, handlers in pairs(self.events) do events[name] = #handlers end
if next(events) then debug_info.events = events end
if next(self.metadata) then debug_info.metadata = self.metadata end
@@ -334,7 +332,7 @@ function Datastore:raw_get(key, fromChild)
local data = self.data
if self.parent then
data = self.parent:raw_get(key, true)
key = self.value_name
key = self.value_name
end
local value = data[key]
if value ~= nil then return value end
@@ -360,7 +358,7 @@ function Datastore:raw_set(key, value)
end
end
local function serialize_error(err) error('An error ocurred in a datastore serializer: '..trace(err)) end
local function serialize_error(err) error("An error ocurred in a datastore serializer: " .. trace(err)) end
--[[-- Internal, Return the serialized key
@tparam any rawKey The key that needs to be serialized, if it is already a string then it is returned
@treturn string The key after it has been serialized
@@ -370,8 +368,8 @@ key = self:serialize(key)
]]
function Datastore:serialize(rawKey)
if type(rawKey) == 'string' then return rawKey end
assert(self.serializer, 'Datastore does not have a serializer and received non string key')
if type(rawKey) == "string" then return rawKey end
assert(self.serializer, "Datastore does not have a serializer and received non string key")
local success, key = xpcall(self.serializer, serialize_error, rawKey)
return success and key or nil
end
@@ -389,11 +387,11 @@ self:write_action('save', 'TestKey', 'Foo')
]]
function Datastore:write_action(action, key, value)
local data = {action, self.name, key}
local data = { action, self.name, key }
if value ~= nil then
data[4] = type(value) == 'table' and game.table_to_json(value) or value
data[4] = type(value) == "table" and game.table_to_json(value) or value
end
game.write_file('ext/datastore.out', table.concat(data, ' ')..'\n', true, 0)
game.write_file("ext/datastore.out", table.concat(data, " ") .. "\n", true, 0)
end
----- Datastore Local
@@ -409,7 +407,7 @@ local BarData = ExampleData:combine('Bar')
]]
function Datastore:combine(subDatastoreName)
local new_datastore = DatastoreManager.connect(self.name..'.'..subDatastoreName)
local new_datastore = DatastoreManager.connect(self.name .. "." .. subDatastoreName)
self.children[subDatastoreName] = new_datastore
new_datastore.value_name = subDatastoreName
new_datastore.serializer = self.serializer
@@ -431,7 +429,7 @@ end)
]]
function Datastore:set_serializer(callback)
assert(type(callback) == 'function', 'Callback must be a function')
assert(type(callback) == "function", "Callback must be a function")
self.serializer = callback
end
@@ -501,7 +499,7 @@ function Datastore:set(key, value)
else
self:raw_set(key, value)
end
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
return value
end
@@ -521,7 +519,7 @@ function Datastore:increment(key, delta)
return self:set(key, value + (delta or 1))
end
local function update_error(err) log('An error occurred in datastore update:\n\t'..trace(err)) end
local function update_error(err) log("An error occurred in datastore update:\n\t" .. trace(err)) end
--[[-- Use a function to update the value locally, will trigger on_update then on_save, save_to_disk and auto_save is required for on_save
@tparam any key The key that you want to apply the update to, must be a string unless a serializer is set
@tparam function callback The function that will be used to update the value at this key
@@ -546,7 +544,7 @@ function Datastore:update(key, callback)
elseif raw_value == nil then
self:set(key, value)
else
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
end
end
@@ -563,12 +561,12 @@ function Datastore:remove(key)
key = self:serialize(key)
local old_value = self:raw_get(key)
self:raw_set(key)
self:raise_event('on_update', key, nil, old_value)
if self.save_to_disk then self:write_action('remove', key) end
self:raise_event("on_update", key, nil, old_value)
if self.save_to_disk then self:write_action("remove", key) end
if self.parent and self.parent.auto_save then return self.parent:save(key) end
end
local function filter_error(err) log('An error ocurred in a datastore filter:\n\t'..trace(err)) end
local function filter_error(err) log("An error ocurred in a datastore filter:\n\t" .. trace(err)) end
--[[-- Internal, Used to filter elements from a table
@tparam table tbl The table that will have the filter applied to it
@tparam[opt] function callback The function that will be used as a filter, if none giving then the provided table is returned
@@ -587,6 +585,7 @@ local function filter(tbl, callback)
local success, add = xpcall(callback, filter_error, key, value)
if success and add then rtn[key] = value end
end
return rtn
end
@@ -613,6 +612,7 @@ function Datastore:get_all(callback)
for key, value in pairs(self.parent:get_all()) do
data[key] = value[value_name]
end
return filter(data, callback)
end
end
@@ -635,7 +635,7 @@ function Datastore:update_all(callback)
if success and new_value ~= nil then
self:set(key, new_value)
else
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
end
end
@@ -655,7 +655,7 @@ ExampleData:request('TestKey')
function Datastore:request(key)
if self.parent then return self.parent:request(key) end
key = self:serialize(key)
self:write_action('request', key)
self:write_action("request", key)
end
--[[-- Save a value to an external source, will trigger on_save before data is saved, save_to_disk must be set to true
@@ -670,8 +670,8 @@ function Datastore:save(key)
if self.parent then self.parent:save(key) end
if not self.save_to_disk then return end
key = self:serialize(key)
local value = self:raise_event('on_save', key, copy(self:raw_get(key)))
local action = self.propagate_changes and 'propagate' or 'save'
local value = self:raise_event("on_save", key, copy(self:raw_get(key)))
local action = self.propagate_changes and "propagate" or "save"
self:write_action(action, key, value)
end
@@ -686,7 +686,7 @@ ExampleData:unload('TestKey')
function Datastore:unload(key)
if self.parent then return self.parent:unload(key) end
key = self:serialize(key)
self:raise_event('on_unload', key, copy(self:raw_get(key)))
self:raise_event("on_unload", key, copy(self:raw_get(key)))
self:save(key)
self:raw_set(key)
end
@@ -702,7 +702,7 @@ ExampleData:message('TestKey', 'Foo')
]]
function Datastore:message(key, message)
key = self:serialize(key)
self:write_action('message', key, message)
self:write_action("message", key, message)
end
--[[-- Save all the keys in the datastore, optional filter callback
@@ -746,7 +746,7 @@ end
----- Events
-- @section events
local function event_error(err) log('An error ocurred in a datastore event handler:\n\t'..trace(err)) end
local function event_error(err) log("An error ocurred in a datastore event handler:\n\t" .. trace(err)) end
--[[-- Internal, Raise an event on this datastore
@tparam string event_name The name of the event to raise for this datastore
@tparam string key The key that this event is being raised for
@@ -761,11 +761,11 @@ value = self:raise_event('on_save', key, value)
]]
function Datastore:raise_event(event_name, key, value, old_value, source)
-- Raise the event for the children of this datastore
if source ~= 'child' and next(self.children) then
if type(value) ~= 'table' then value = {} end
if source ~= "child" and next(self.children) then
if type(value) ~= "table" then value = {} end
for value_name, child in pairs(self.children) do
local old_child_value = old_value and old_value[value_name] or nil
value[value_name] = child:raise_event(event_name, key, value[value_name], old_child_value, 'parent')
value[value_name] = child:raise_event(event_name, key, value[value_name], old_child_value, "parent")
end
end
@@ -779,13 +779,13 @@ function Datastore:raise_event(event_name, key, value, old_value, source)
end
-- Raise the event for the parent of this datastore
if source ~= 'parent' and self.parent then
if source ~= "parent" and self.parent then
local parent_value = self.parent:raw_get(key, true)
self.parent:raise_event(event_name, key, parent_value, parent_value, 'child')
self.parent:raise_event(event_name, key, parent_value, parent_value, "child")
end
-- If this is the save event and the table is empty then return nil
if event_name == 'on_save' and next(self.children) and not next(value) then return end
if event_name == "on_save" and next(self.children) and not next(value) then return end
return value
end
@@ -799,12 +799,12 @@ Datastore.on_load = event_factory('on_load')
]]
local function event_factory(event_name)
return function(self, callback)
assert(type(callback) == 'function', 'Handler must be a function')
assert(type(callback) == "function", "Handler must be a function")
local handlers = self.events[event_name]
if not handlers then
self.events[event_name] = { callback }
else
handlers[#handlers+1] = callback
handlers[#handlers + 1] = callback
end
end
end
@@ -817,7 +817,7 @@ ExampleData:on_load(function(key, value)
game.print('Test data loaded for: '..key)
end)
]]
Datastore.on_load = event_factory('on_load')
Datastore.on_load = event_factory("on_load")
--[[-- Register a callback that triggers before data is saved, returned value is saved externally
@tparam function callback The handler that will be registered to the on_load event
@@ -827,7 +827,7 @@ ExampleData:on_save(function(key, value)
game.print('Test data saved for: '..key)
end)
]]
Datastore.on_save = event_factory('on_save')
Datastore.on_save = event_factory("on_save")
--[[-- Register a callback that triggers before data is unloaded, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -837,7 +837,7 @@ ExampleData:on_load(function(key, value)
game.print('Test data unloaded for: '..key)
end)
]]
Datastore.on_unload = event_factory('on_unload')
Datastore.on_unload = event_factory("on_unload")
--[[-- Register a callback that triggers when a message is received, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -847,7 +847,7 @@ ExampleData:on_message(function(key, value)
game.print('Test data message for: '..key)
end)
]]
Datastore.on_message = event_factory('on_message')
Datastore.on_message = event_factory("on_message")
--[[-- Register a callback that triggers any time a value is changed, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -857,7 +857,7 @@ ExampleData:on_update(function(key, value)
game.print('Test data updated for: '..key)
end)
]]
Datastore.on_update = event_factory('on_update')
Datastore.on_update = event_factory("on_update")
----- Module Return
return DatastoreManager

View File

@@ -47,8 +47,8 @@ local servers = External.get_servers()
]]
function External.get_servers()
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
return assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
return assert(ext.servers, "No server list was found, please ensure that the external service is running")
end
--[[-- Gets a table of all the servers filtered by name, key is the server id, value is the server details
@@ -60,14 +60,15 @@ local servers = External.get_servers_filtered(public)
]]
function External.get_servers_filtered(search)
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local found_servers = {}
search = search:lower()
for server_id, server in pairs(servers) do
local str = concat{server.name, server.short_name, server.id}
local str = concat{ server.name, server.short_name, server.id }
if str:lower():find(search, 1, true) then found_servers[server_id] = server end
end
return found_servers
end
@@ -79,9 +80,9 @@ local server = External.get_current_server()
]]
function External.get_current_server()
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
local server_id = assert(ext.current, 'No current id was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local server_id = assert(ext.current, "No current id was found, please ensure that the external service is running")
return servers[server_id]
end
@@ -94,8 +95,8 @@ local server = External.get_server_details('eu-01')
]]
function External.get_server_details(server_id)
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
return servers[server_id]
end
@@ -109,10 +110,10 @@ local status = External.get_server_status('eu-01')
]]
function External.get_server_status(server_id, raw)
assert(var, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(var.status, 'No server status was found, please ensure that the external service is running')
local current = assert(ext.current, 'No current id was found, please ensure that the external service is running')
return not raw and server_id == current and 'Current' or servers[server_id]
assert(var, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(var.status, "No server status was found, please ensure that the external service is running")
local current = assert(ext.current, "No current id was found, please ensure that the external service is running")
return not raw and server_id == current and "Current" or servers[server_id]
end
--[[-- Gets the ups of the current server
@@ -121,8 +122,8 @@ local server_ups = External.get_server_ups()
]]
function External.get_server_ups()
assert(var, 'No external data was found, use External.valid() to ensure external data exists.')
return assert(var.server_ups, 'No server ups was found, please ensure that the external service is running')
assert(var, "No external data was found, use External.valid() to ensure external data exists.")
return assert(var.server_ups, "No server ups was found, please ensure that the external service is running")
end
--[[-- Connect a player to the given server
@@ -138,16 +139,16 @@ External.request_connection(player, 'eu-01', true)
]]
function External.request_connection(player, server_id, self_requested)
local server = { address = server_id, name = 'Unknown Server', description = 'This server is not ran by us, please check the address of the server.' }
local server = { address = server_id, name = "Unknown Server", description = "This server is not ran by us, please check the address of the server." }
if ext and ext.servers and ext.servers[server_id] then server = ext.servers[server_id] end
local message = 'Please press the connect button below to join.'
if not self_requested then message = 'You have been asked to switch to a different server.\n'..message end
local message = "Please press the connect button below to join."
if not self_requested then message = "You have been asked to switch to a different server.\n" .. message end
player.connect_to_server{
address = server.address,
name = '\n[color=orange][font=heading-1]'..server.name..'[/font][/color]\n',
description = server.description..'\n'..message
name = "\n[color=orange][font=heading-1]" .. server.name .. "[/font][/color]\n",
description = server.description .. "\n" .. message,
}
end
--- Module return
return External
return External

View File

@@ -132,13 +132,12 @@ local Roles = _C.opt_require("modules.exp_legacy.expcore.roles")
local Event = _C.opt_require("modules/exp_legacy/utils/event")
if Roles and Event then
Event.add(Roles.events.on_role_assigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_unassigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_assigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_unassigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
end
return Gui
return Gui

View File

@@ -12,61 +12,61 @@ local Event = require("modules/exp_legacy/utils/event")
--- Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible
-- @element hide_top_flow
local hide_top_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/preset',
style = 'tool_button',
tooltip = {'gui_util.button_tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -2,
width = 18,
height = 36
}
:on_click(function(player, _,_)
Gui.toggle_top_flow(player, false)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/preset",
style = "tool_button",
tooltip = { "gui_util.button_tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -2,
width = 18,
height = 36,
}
:on_click(function(player, _, _)
Gui.toggle_top_flow(player, false)
end)
Gui.core_defines.hide_top_flow = hide_top_flow
--- Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden
-- @element show_top_flow
local show_top_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/preset',
style = 'tool_button',
tooltip = {'gui_util.button_tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -2,
width = 18,
height = 20
}
:on_click(function(player, _,_)
Gui.toggle_top_flow(player, true)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/preset",
style = "tool_button",
tooltip = { "gui_util.button_tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -2,
width = 18,
height = 20,
}
:on_click(function(player, _, _)
Gui.toggle_top_flow(player, true)
end)
Gui.core_defines.show_top_flow = show_top_flow
--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible
-- @element hide_left_flow
local hide_left_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/close_black',
style = 'tool_button',
tooltip = {'expcore-gui.left-button-tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -3,
width = 18,
height = 20
}
:on_click(function(player, _,_)
Gui.hide_left_flow(player)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/close_black",
style = "tool_button",
tooltip = { "expcore-gui.left-button-tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -3,
width = 18,
height = 20,
}
:on_click(function(player, _, _)
Gui.hide_left_flow(player)
end)
Gui.core_defines.hide_left_flow = hide_left_flow
--- Draw the core elements when a player joins the game
@@ -80,10 +80,10 @@ Event.add(defines.events.on_player_created, function(event)
-- Draw the left flow
local left_flow = Gui.get_left_flow(player)
local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' }
local button_flow = left_flow.add{ type = "flow", name = "gui_core_buttons", direction = "vertical" }
local show_top = show_top_flow(button_flow)
local hide_left = hide_left_flow(button_flow)
show_top.visible = false
hide_left.visible = false
Gui.draw_left_flow(player)
end)
end)

View File

@@ -24,19 +24,19 @@ local alignment = Gui.alignment(element, 'example_center_top_alignment', 'center
]]
Gui.alignment =
Gui.element(function(_, parent, name, _,_)
return parent.add{
name = name or 'alignment',
type = 'flow',
}
end)
:style(function(style, _,_, horizontal_align, vertical_align)
style.padding = {1, 2}
style.vertical_align = vertical_align or 'center'
style.horizontal_align = horizontal_align or 'right'
style.vertically_stretchable = style.vertical_align ~= 'center'
style.horizontally_stretchable = style.horizontal_align ~= 'center'
end)
Gui.element(function(_, parent, name, _, _)
return parent.add{
name = name or "alignment",
type = "flow",
}
end)
:style(function(style, _, _, horizontal_align, vertical_align)
style.padding = { 1, 2 }
style.vertical_align = vertical_align or "center"
style.horizontal_align = horizontal_align or "right"
style.vertically_stretchable = style.vertical_align ~= "center"
style.horizontally_stretchable = style.horizontal_align ~= "center"
end)
--[[-- Draw a scroll pane that has a table inside of it
@element Gui.scroll_table
@@ -51,42 +51,42 @@ local scroll_table = Gui.scroll_table(element, 200, 3)
]]
Gui.scroll_table =
Gui.element(function(_, parent, height, column_count, name)
-- Draw the scroll
local scroll_pane =
parent.add{
name = name or 'scroll',
type = 'scroll-pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto',
style = 'scroll_pane_under_subheader'
Gui.element(function(_, parent, height, column_count, name)
-- Draw the scroll
local scroll_pane =
parent.add{
name = name or "scroll",
type = "scroll-pane",
direction = "vertical",
horizontal_scroll_policy = "never",
vertical_scroll_policy = "auto",
style = "scroll_pane_under_subheader",
}
-- Set the style of the scroll pane
local scroll_style = scroll_pane.style
scroll_style.padding = { 1, 3 }
scroll_style.maximal_height = height
scroll_style.horizontally_stretchable = true
-- Draw the table
local scroll_table =
scroll_pane.add{
type = "table",
name = "table",
column_count = column_count,
}
-- Return the scroll table
return scroll_table
end)
:style{
padding = 0,
cell_padding = 0,
vertical_align = "center",
horizontally_stretchable = true,
}
-- Set the style of the scroll pane
local scroll_style = scroll_pane.style
scroll_style.padding = {1, 3}
scroll_style.maximal_height = height
scroll_style.horizontally_stretchable = true
-- Draw the table
local scroll_table =
scroll_pane.add{
type = 'table',
name = 'table',
column_count = column_count
}
-- Return the scroll table
return scroll_table
end)
:style{
padding = 0,
cell_padding = 0,
vertical_align = 'center',
horizontally_stretchable = true
}
--[[-- Used to add a frame with the header style, has the option for a right alignment flow for buttons
@element Gui.header
@tparam LuaGuiElement parent the parent element to which the header will be added
@@ -105,35 +105,35 @@ local header = Gui.header(
]]
Gui.header =
Gui.element(function(_, parent, caption, tooltip, add_alignment, name, label_name)
-- Draw the header
local header =
parent.add{
name = name or 'header',
type = 'frame',
style = 'subheader_frame'
}
Gui.element(function(_, parent, caption, tooltip, add_alignment, name, label_name)
-- Draw the header
local header =
parent.add{
name = name or "header",
type = "frame",
style = "subheader_frame",
}
-- Change the style of the header
local style = header.style
style.padding = {2, 4}
style.use_header_filler = false
style.horizontally_stretchable = true
-- Change the style of the header
local style = header.style
style.padding = { 2, 4 }
style.use_header_filler = false
style.horizontally_stretchable = true
-- Draw the caption label
if caption then
header.add{
name = label_name or 'header_label',
type = 'label',
style = 'frame_title',
caption = caption,
tooltip = tooltip
}
end
-- Draw the caption label
if caption then
header.add{
name = label_name or "header_label",
type = "label",
style = "frame_title",
caption = caption,
tooltip = tooltip,
}
end
-- Return either the header or the added alignment
return add_alignment and Gui.alignment(header) or header
end)
-- Return either the header or the added alignment
return add_alignment and Gui.alignment(header) or header
end)
--[[-- Used to add a frame with the footer style, has the option for a right alignment flow for buttons
@element Gui.footer
@@ -153,35 +153,35 @@ local footer = Gui.footer(
]]
Gui.footer =
Gui.element(function(_, parent, caption, tooltip, add_alignment, name)
-- Draw the header
local footer =
parent.add{
name = name or 'footer',
type = 'frame',
style = 'subfooter_frame'
}
Gui.element(function(_, parent, caption, tooltip, add_alignment, name)
-- Draw the header
local footer =
parent.add{
name = name or "footer",
type = "frame",
style = "subfooter_frame",
}
-- Change the style of the footer
local style = footer.style
style.padding = {2, 4}
style.use_header_filler = false
style.horizontally_stretchable = true
-- Change the style of the footer
local style = footer.style
style.padding = { 2, 4 }
style.use_header_filler = false
style.horizontally_stretchable = true
-- Draw the caption label
if caption then
footer.add{
name = 'footer_label',
type = 'label',
style = 'frame_title',
caption = caption,
tooltip = tooltip
}
end
-- Draw the caption label
if caption then
footer.add{
name = "footer_label",
type = "label",
style = "frame_title",
caption = caption,
tooltip = tooltip,
}
end
-- Return either the footer or the added alignment
return add_alignment and Gui.alignment(footer) or footer
end)
-- Return either the footer or the added alignment
return add_alignment and Gui.alignment(footer) or footer
end)
--[[-- Used for left frames to give them a nice boarder
@element Gui.container
@@ -194,29 +194,29 @@ local container = Gui.container(parent, 'my_container', 200)
]]
Gui.container =
Gui.element(function(_, parent, name, _)
-- Draw the external container
local frame =
parent.add{
name = name,
type = 'frame'
}
frame.style.horizontally_stretchable = false
Gui.element(function(_, parent, name, _)
-- Draw the external container
local frame =
parent.add{
name = name,
type = "frame",
}
frame.style.horizontally_stretchable = false
-- Return the container
return frame.add{
name = 'container',
type = 'frame',
direction = 'vertical',
style = 'inside_shallow_frame_packed'
}
end)
:style(function(style, element, _,width)
style.vertically_stretchable = false
local frame_style = element.parent.style
frame_style.padding = 2
frame_style.minimal_width = width
end)
-- Return the container
return frame.add{
name = "container",
type = "frame",
direction = "vertical",
style = "inside_shallow_frame_packed",
}
end)
:style(function(style, element, _, width)
style.vertically_stretchable = false
local frame_style = element.parent.style
frame_style.padding = 2
frame_style.minimal_width = width
end)
--[[-- Used to make a solid white bar in a gui
@element Gui.bar
@@ -228,19 +228,22 @@ local bar = Gui.bar(parent, 100)
]]
Gui.bar =
Gui.element(function(_, parent)
return parent.add{
type = 'progressbar',
size = 1,
value = 1
}
end)
:style(function(style, _,width)
style.height = 3
style.color = {r=255, g=255, b=255}
if width then style.width = width
else style.horizontally_stretchable = true end
end)
Gui.element(function(_, parent)
return parent.add{
type = "progressbar",
size = 1,
value = 1,
}
end)
:style(function(style, _, width)
style.height = 3
style.color = { r = 255, g = 255, b = 255 }
if width then
style.width = width
else
style.horizontally_stretchable = true
end
end)
--[[-- Used to make a label which is centered and of a certian size
@element Gui.centered_label
@@ -254,20 +257,20 @@ local label = Gui.centered_label(parent, 100, 'This is centered')
]]
Gui.centered_label =
Gui.element(function(_, parent, width, caption, tooltip)
local label = parent.add{
type = 'label',
caption = caption,
tooltip = tooltip,
}
Gui.element(function(_, parent, width, caption, tooltip)
local label = parent.add{
type = "label",
caption = caption,
tooltip = tooltip,
}
local style = label.style
style.horizontal_align = 'center'
style.single_line = false
style.width = width
local style = label.style
style.horizontal_align = "center"
style.single_line = false
style.width = width
return label
end)
return label
end)
--[[-- Used to make a title which has two bars on either side
@element Gui.title_label
@@ -281,18 +284,18 @@ local label = Gui.centered_label(parent, 100, 'This is centered')
]]
Gui.title_label =
Gui.element(function(_, parent, width, caption, tooltip)
local title_flow = parent.add{ type='flow' }
title_flow.style.vertical_align = 'center'
Gui.element(function(_, parent, width, caption, tooltip)
local title_flow = parent.add{ type = "flow" }
title_flow.style.vertical_align = "center"
Gui.bar(title_flow, width)
local title_label = title_flow.add{
type = 'label',
caption = caption,
tooltip = tooltip,
style = 'frame_title'
}
Gui.bar(title_flow)
Gui.bar(title_flow, width)
local title_label = title_flow.add{
type = "label",
caption = caption,
tooltip = tooltip,
style = "frame_title",
}
Gui.bar(title_flow)
return title_label
end)
return title_label
end)

View File

@@ -88,4 +88,4 @@ function Gui.sprite_style(size, padding, style)
style.height = size
style.width = size
return style
end
end

View File

@@ -4,7 +4,7 @@
]]
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
local mod_gui = require 'mod-gui'
local mod_gui = require "mod-gui"
local hide_left_flow = Gui.core_defines.hide_left_flow.name
@@ -12,7 +12,7 @@ local hide_left_flow = Gui.core_defines.hide_left_flow.name
-- @section leftFlow
-- Triggered when a user changed the visibility of a left flow element by clicking a button
Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click'
Gui.events.on_visibility_changed_by_click = "on_visibility_changed_by_click"
--- Contains the uids of the elements that will shown on the left flow and their join functions
-- @table left_elements
@@ -68,7 +68,7 @@ function Gui.left_toolbar_button(sprite, tooltip, element_define, authenticator)
button:raise_event{
name = Gui.events.on_visibility_changed_by_click,
element = Gui.get_top_element(player, button),
state = Gui.toggle_left_element(player, element_define)
state = Gui.toggle_left_element(player, element_define),
}
end)
@@ -90,8 +90,8 @@ function Gui.inject_left_flow_order(provider)
Gui.get_left_flow_order = provider
local debug_info = debug.getinfo(2, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
Gui._left_flow_order_src = file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
Gui._left_flow_order_src = file_name .. ":" .. func_name
end
--[[-- Draw all the left elements onto the left flow, internal use only with on join
@@ -121,17 +121,17 @@ function Gui.draw_left_flow(player)
end, debug.traceback)
if not draw_success then
log('There as been an error with an element draw function: '..element_define.defined_at..'\n\t'..left_element)
log("There as been an error with an element draw function: " .. element_define.defined_at .. "\n\t" .. left_element)
goto continue
end
-- Check if it should be open by default
local open_on_join = element_define.open_on_join
local visible = type(open_on_join) == 'boolean' and open_on_join or false
if type(open_on_join) == 'function' then
local visible = type(open_on_join) == "boolean" and open_on_join or false
if type(open_on_join) == "function" then
local success, err = xpcall(open_on_join, debug.traceback, player)
if not success then
log('There as been an error with an open on join hander for a gui element:\n\t'..err)
log("There as been an error with an open on join hander for a gui element:\n\t" .. err)
goto continue
end
visible = err
@@ -166,7 +166,7 @@ function Gui.reorder_left_flow(player)
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
for index, element_define in ipairs(flow_order) do
local element = left_flow[element_define.name]
left_flow.swap_children(index+1, element.get_index_in_parent())
left_flow.swap_children(index + 1, element.get_index_in_parent())
end
end
@@ -188,6 +188,7 @@ function Gui.update_left_flow(player)
return true
end
end
hide_button.visible = false
return false
end
@@ -220,7 +221,7 @@ function Gui.hide_left_flow(player)
element_define.toolbar_button:raise_event{
name = Gui.events.on_visibility_changed_by_click,
element = button,
state = false
state = false,
}
end
end
@@ -272,4 +273,4 @@ function Gui.toggle_left_element(player, element_define, state)
Gui.toggle_toolbar_button(player, element_define.toolbar_button, state)
end
return state
end
end

View File

@@ -23,7 +23,7 @@ local Gui = {
--- The prototype used to store the functions of an element define
_prototype_element = {},
--- The prototype metatable applied to new element defines
_mt_element = {}
_mt_element = {},
}
--- Allow access to the element prototype methods
@@ -37,14 +37,14 @@ function Gui._mt_element.__call(self, parent, ...)
-- Asserts to catch common errors
if element then
if self.name and self.name ~= element.name then
error("Static name \""..self.name.."\" expected but got: "..tostring(element.name))
error("Static name \"" .. self.name .. "\" expected but got: " .. tostring(element.name))
end
local event_triggers = element.tags and element.tags.ExpGui_event_triggers
if event_triggers and table.array_contains(event_triggers, self.uid) then
error("Element::triggers_events should not be called on the value you return from the definition")
end
elseif self.name then
error("Static name \""..self.name.."\" expected but no element was returned from the definition")
error("Static name \"" .. self.name .. "\" expected but no element was returned from the definition")
end
-- Register events by default, but allow skipping them
@@ -59,8 +59,8 @@ end
local function get_defined_at(level)
local debug_info = debug.getinfo(level, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
return file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
return file_name .. ":" .. func_name
end
--- Element Define.
@@ -115,19 +115,20 @@ function Gui.element(element_define)
local uid = Gui.uid + 1
Gui.uid = uid
element.uid = uid
Gui.debug_info[uid] = { draw = 'None', style = 'None', events = {} }
Gui.debug_info[uid] = { draw = "None", style = "None", events = {} }
-- Add the definition function
if type(element_define) == 'table' then
if type(element_define) == "table" then
Gui.debug_info[uid].draw = element_define
if element_define.name == Gui.unique_static_name then
element_define.name = "ExpGui_"..tostring(uid)
element_define.name = "ExpGui_" .. tostring(uid)
end
for k, v in pairs(element_define) do
if element[k] == nil then
element[k] = v
end
end
element._draw = function(_, parent)
return parent.add(element_define)
end
@@ -183,7 +184,7 @@ end)
function Gui._prototype_element:style(style_define)
_C.error_if_runtime()
-- Add the definition function
if type(style_define) == 'table' then
if type(style_define) == "table" then
Gui.debug_info[self.uid].style = style_define
self._style = function(style)
for key, value in pairs(style_define) do
@@ -206,7 +207,7 @@ end
function Gui._prototype_element:static_name(name)
_C.error_if_runtime()
if name == Gui.unique_static_name then
self.name = "ExpGui_"..tostring(self.uid)
self.name = "ExpGui_" .. tostring(self.uid)
else
self.name = name
end
@@ -295,7 +296,7 @@ function Gui._prototype_element:raise_event(event)
local success, err = xpcall(handler, debug.traceback, player, element, event)
if not success then
error('There as been an error with an event handler for a gui element:\n\t'..err)
error("There as been an error with an event handler for a gui element:\n\t" .. err)
end
return self
end
@@ -328,84 +329,84 @@ end
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_open(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_open = event_handler_factory(defines.events.on_gui_opened)
--- Called when the player closes the GUI they have open.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_close(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_close = event_handler_factory(defines.events.on_gui_closed)
--- Called when LuaGuiElement is clicked.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_click(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click)
--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_confirmed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed)
--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_checked_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed)
--- Called when LuaGuiElement element value is changed (related to choose element buttons).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_elem_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed)
--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_location_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed)
--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_tab_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed)
--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_selection_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed)
--- Called when LuaGuiElement switch state is changed (related to switches).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_switch_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed)
--- Called when LuaGuiElement text is changed by the player.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_text_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed)
--- Called when LuaGuiElement slider value is changed (related to the slider element).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_value_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed)
-- Module return

View File

@@ -4,7 +4,7 @@
]]
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
local toolbar_button_size = 36
local hide_top_flow = Gui.core_defines.hide_top_flow.name
@@ -14,7 +14,7 @@ local show_top_flow = Gui.core_defines.show_top_flow.name
-- @section topFlow
-- Triggered when a user changed the visibility of a left flow element by clicking a button
Gui.events.on_toolbar_button_toggled = 'on_toolbar_button_toggled'
Gui.events.on_toolbar_button_toggled = "on_toolbar_button_toggled"
--- Contains the uids of the elements that will shown on the top flow and their auth functions
-- @table top_elements
@@ -26,7 +26,7 @@ Gui.top_flow_button_style = mod_gui.button_style
--- The style that should be used for buttons on the top flow when their flow is visible
-- @field Gui.top_flow_button_toggled_style
Gui.top_flow_button_toggled_style = 'menu_button_continue'
Gui.top_flow_button_toggled_style = "menu_button_continue"
--[[-- Styles a top flow button depending on the state given
@tparam LuaGuiElement button the button element to style
@@ -40,7 +40,7 @@ Gui.toolbar_button_style(button, false)
]]
function Gui.toolbar_button_style(button, state, size)
---@cast button LuaGuiElement
--- @cast button LuaGuiElement
if state then
button.style = Gui.top_flow_button_toggled_style
else
@@ -108,8 +108,8 @@ function Gui.inject_top_flow_order(provider)
Gui.get_top_flow_order = provider
local debug_info = debug.getinfo(2, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
Gui._top_flow_order_src = file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
Gui._top_flow_order_src = file_name .. ":" .. func_name
end
--[[-- Updates the visible state of all the elements on the players top flow, uses authenticator
@@ -137,12 +137,12 @@ function Gui.update_top_flow(player)
if not element then
element = element_define(top_flow)
else
top_flow.swap_children(index+1, element.get_index_in_parent())
top_flow.swap_children(index + 1, element.get_index_in_parent())
end
-- Set the visible state
local allowed = element_define.authenticator
if type(allowed) == 'function' then allowed = allowed(player) end
if type(allowed) == "function" then allowed = allowed(player) end
element.visible = allowed or false
-- If its not visible and there is a left element, then hide it
@@ -176,7 +176,7 @@ function Gui.reorder_top_flow(player)
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
for index, element_define in ipairs(flow_order) do
local element = top_flow[element_define.name]
top_flow.swap_children(index+1, element.get_index_in_parent())
top_flow.swap_children(index + 1, element.get_index_in_parent())
end
end
@@ -243,7 +243,7 @@ function Gui.toggle_toolbar_button(player, element_define, state)
name = Gui.events.on_toolbar_button_toggled,
element = toolbar_button,
player = player,
state = state
state = state,
}
return state
end
@@ -262,18 +262,18 @@ end)
]]
function Gui.toolbar_button(sprite, tooltip, authenticator)
return Gui.element{
type = 'sprite-button',
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2
}
:add_to_top_flow(authenticator)
type = "sprite-button",
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name,
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2,
}
:add_to_top_flow(authenticator)
end
--[[-- Creates a toggle button on the top flow with consistent styling
@@ -293,23 +293,23 @@ end)
]]
function Gui.toolbar_toggle_button(sprite, tooltip, authenticator)
local button =
Gui.element{
type = 'sprite-button',
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2
}
:add_to_top_flow(authenticator)
Gui.element{
type = "sprite-button",
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name,
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2,
}
:add_to_top_flow(authenticator)
button:on_click(function(player, _, _)
Gui.toggle_toolbar_button(player, button)
end)
return button
end
end

View File

@@ -23,28 +23,27 @@ Permission_Groups.new_group('Restricted') -- this defines a new group called "Re
]]
local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Async = require("modules/exp_util/async")
local Permissions_Groups = {
groups={}, -- store for the different groups that are created
_prototype={} -- stores functions that are used on group instances
groups = {}, -- store for the different groups that are created
_prototype = {}, -- stores functions that are used on group instances
}
-- Async function to add players to permission groups
local add_to_permission_group_async =
Async.register(function(permission_group, player)
permission_group.add_player(player)
end)
Async.register(function(permission_group, player)
permission_group.add_player(player)
end)
Permissions_Groups.add_to_permission_group_async = add_to_permission_group_async
-- Async function to remove players from permission groups
local remove_from_permission_group_async =
Async.register(function(permission_group, player)
permission_group.remove_player(player)
end)
Async.register(function(permission_group, player)
permission_group.remove_player(player)
end)
Permissions_Groups.remove_from_permission_group_async = remove_from_permission_group_async
--- Getters.
@@ -61,11 +60,11 @@ Groups.new_group('Admin')
]]
function Permissions_Groups.new_group(name)
local group = setmetatable({
name=name,
actions={},
allow_all_actions=true
name = name,
actions = {},
allow_all_actions = true,
}, {
__index= Permissions_Groups._prototype
__index = Permissions_Groups._prototype,
})
Permissions_Groups.groups[name] = group
return group
@@ -149,7 +148,7 @@ group:set_action('toggle_map_editor', false)
function Permissions_Groups._prototype:set_action(action, state)
local input_action = defines.input_action[action]
if input_action == nil then input_action = action end
assert(type(input_action) == 'number', tostring(action)..' is not a valid input action')
assert(type(input_action) == "number", tostring(action) .. " is not a valid input action")
self.actions[input_action] = state
return self
end
@@ -165,12 +164,13 @@ group:allow{
]]
function Permissions_Groups._prototype:allow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in pairs(actions) do
self:set_action(action, true)
end
return self
end
@@ -189,12 +189,13 @@ group:disallow{
]]
function Permissions_Groups._prototype:disallow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in pairs(actions) do
self:set_action(action, false)
end
return self
end
@@ -231,7 +232,7 @@ local allowed = group:is_allowed('write_to_console')
]]
function Permissions_Groups._prototype:is_allowed(action)
if type(action) == 'string' then
if type(action) == "string" then
action = defines.input_action[action]
end
local state = self.actions[action]
@@ -260,6 +261,7 @@ function Permissions_Groups._prototype:create()
for _, action in pairs(defines.input_action) do
group.set_allows_action(action, self:is_allowed(action))
end
return group
end
@@ -347,6 +349,7 @@ function Permissions_Groups._prototype:print(message)
for _, player in pairs(players) do
player.print(message)
end
return #players
end
@@ -355,4 +358,4 @@ Event.on_init(function()
Permissions_Groups.reload_permissions()
end)
return Permissions_Groups
return Permissions_Groups

View File

@@ -48,58 +48,59 @@ local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore
require("modules.exp_legacy.config.expcore.command_general_parse") --- @dep config.expcore.command_general_parse
--- Common player data that acts as the root store for player data
local PlayerData = Datastore.connect('PlayerData', true) -- saveToDisk
local PlayerData = Datastore.connect("PlayerData", true) -- saveToDisk
PlayerData:set_serializer(Datastore.name_serializer) -- use player name
--- Store and enum for the data saving preference
local DataSavingPreference = PlayerData:combine('DataSavingPreference')
local PreferenceEnum = { 'All', 'Statistics', 'Settings', 'Required' }
for k,v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default('All')
local DataSavingPreference = PlayerData:combine("DataSavingPreference")
local PreferenceEnum = { "All", "Statistics", "Settings", "Required" }
for k, v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default("All")
DataSavingPreference:set_metadata{
name = {'expcore-data.preference'},
tooltip = {'expcore-data.preference-tooltip'},
value_tooltip ={'expcore-data.preference-value-tooltip'}
name = { "expcore-data.preference" },
tooltip = { "expcore-data.preference-tooltip" },
value_tooltip = { "expcore-data.preference-value-tooltip" },
}
--- Sets your data saving preference
-- @command set-data-preference
Commands.new_command('set-preference', 'Allows you to set your data saving preference')
:add_param('option', false, 'string-options', PreferenceEnum)
:register(function(player, option)
DataSavingPreference:set(player, option)
return {'expcore-data.set-preference', option}
end)
Commands.new_command("set-preference", "Allows you to set your data saving preference")
:add_param("option", false, "string-options", PreferenceEnum)
:register(function(player, option)
DataSavingPreference:set(player, option)
return { "expcore-data.set-preference", option }
end)
--- Gets your data saving preference
-- @command data-preference
Commands.new_command('preference', 'Shows you what your current data saving preference is')
:register(function(player)
return {'expcore-data.get-preference', DataSavingPreference:get(player)}
end)
Commands.new_command("preference", "Shows you what your current data saving preference is")
:register(function(player)
return { "expcore-data.get-preference", DataSavingPreference:get(player) }
end)
--- Gets your data and writes it to a file
Commands.new_command('save-data', 'Writes all your player data to a file on your computer')
:register(function(player)
player.print{'expcore-data.get-data'}
game.write_file('expgaming_player_data.json', game.table_to_json(PlayerData:get(player, {})), false, player.index)
end)
Commands.new_command("save-data", "Writes all your player data to a file on your computer")
:register(function(player)
player.print{ "expcore-data.get-data" }
game.write_file("expgaming_player_data.json", game.table_to_json(PlayerData:get(player, {})), false, player.index)
end)
--- Async function called after 5 seconds with no player data loaded
local check_data_loaded_async =
Async.register(function(player)
local player_data = PlayerData:get(player)
if not player_data or not player_data.valid then
player.print{'expcore-data.data-failed'}
Datastore.ingest('request', 'PlayerData', player.name, '{"valid":false}')
end
end)
Async.register(function(player)
local player_data = PlayerData:get(player)
if not player_data or not player_data.valid then
player.print{ "expcore-data.data-failed" }
Datastore.ingest("request", "PlayerData", player.name, '{"valid":false}')
end
end)
--- When player data loads tell the player if the load had failed previously
PlayerData:on_load(function(player_name, player_data, existing_data)
if not player_data or player_data.valid == false then return end
if existing_data and existing_data.valid == false then
game.players[player_name].print{'expcore-data.data-restore'}
game.players[player_name].print{ "expcore-data.data-restore" }
end
player_data.valid = true
end)
@@ -122,7 +123,7 @@ end)
--- Display your data preference when your data loads
DataSavingPreference:on_load(function(player_name, dataPreference)
game.players[player_name].print{'expcore-data.get-preference', dataPreference or DataSavingPreference.default}
game.players[player_name].print{ "expcore-data.get-preference", dataPreference or DataSavingPreference.default }
end)
--- Load player data when they join
@@ -139,15 +140,17 @@ Event.add(defines.events.on_player_left_game, function(event)
local player_data = PlayerData:get(player)
if player_data and player_data.valid == true then
PlayerData:unload(player)
else PlayerData:raw_set(player.name) end
else
PlayerData:raw_set(player.name)
end
end)
----- Module Return -----
return {
All = PlayerData, -- Root for all of a players data
Statistics = PlayerData:combine('Statistics'), -- Common place for stats
Settings = PlayerData:combine('Settings'), -- Common place for settings
Required = PlayerData:combine('Required'), -- Common place for required data
Statistics = PlayerData:combine("Statistics"), -- Common place for stats
Settings = PlayerData:combine("Settings"), -- Common place for settings
Required = PlayerData:combine("Required"), -- Common place for required data
DataSavingPreference = DataSavingPreference, -- Stores what data groups will be saved
PreferenceEnum = PreferenceEnum -- Enum for the allowed options for data saving preference
}
PreferenceEnum = PreferenceEnum, -- Enum for the allowed options for data saving preference
}

View File

@@ -119,24 +119,24 @@ local write_json = _C.write_json --- @dep expcore.common
local Roles = {
_prototype = {},
config = {
order = {}, -- Contains the order of the roles, lower index is better
roles = {}, -- Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
auto_assign = {}, -- Contains references to all roles which have auto assign conditions
order = {}, -- Contains the order of the roles, lower index is better
roles = {}, -- Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
auto_assign = {}, -- Contains references to all roles which have auto assign conditions
deferred_roles = {}, -- Contains the roles that are to be assigned to players when they are unjailed
},
events = {
on_role_assigned = script.generate_event_name(),
on_role_assigned = script.generate_event_name(),
on_role_unassigned = script.generate_event_name(),
}
},
}
--- When global is loaded it will have the metatable re-assigned to the roles
Storage.register({
Roles.config.players,
Roles.config.deferred_roles
Roles.config.deferred_roles,
}, function(tbl)
Roles.config.players = tbl[1]
Roles.config.deferred_roles = tbl[2]
@@ -150,12 +150,12 @@ end)
-- this is the raw internal trigger as the other function is called at other times
-- there is a second half called role_update which triggers after the event call, it also is called when a player joins
local function emit_player_roles_updated(player, type, roles, by_player_name, skip_game_print)
by_player_name = by_player_name or game.player and game.player.name or '<server>'
by_player_name = by_player_name or game.player and game.player.name or "<server>"
local by_player = game.players[by_player_name]
local by_player_index = by_player and by_player.index or 0
-- get the event id from the type of emit
local event = Roles.events.on_role_assigned
if type == 'unassign' then
if type == "unassign" then
event = Roles.events.on_role_unassigned
end
-- Get the names of the roles
@@ -163,27 +163,28 @@ local function emit_player_roles_updated(player, type, roles, by_player_name, sk
for index, role in ipairs(roles) do
role_names[index] = role.name
end
-- output to all the different locations: game print, player sound, event trigger and role log
if not skip_game_print then
game.print({'expcore-roles.game-message-'..type, player.name, table.concat(role_names, ', '), by_player_name}, Colours.cyan)
game.print({ "expcore-roles.game-message-" .. type, player.name, table.concat(role_names, ", "), by_player_name }, Colours.cyan)
end
if type == 'assign' then
player.play_sound{path='utility/achievement_unlocked'}
if type == "assign" then
player.play_sound{ path = "utility/achievement_unlocked" }
else
player.play_sound{path='utility/game_lost'}
player.play_sound{ path = "utility/game_lost" }
end
script.raise_event(event, {
name=event,
tick=game.tick,
player_index=player.index,
by_player_index=by_player_index,
roles=role_names
name = event,
tick = game.tick,
player_index = player.index,
by_player_index = by_player_index,
roles = role_names,
})
write_json('log/roles.log', {
player_name=player.name,
by_player_name=by_player_name,
type=type,
roles_changed=role_names
write_json("log/roles.log", {
player_name = player.name,
by_player_name = by_player_name,
type = type,
roles_changed = role_names,
})
end
@@ -195,13 +196,14 @@ game.player.print(Roles.debug())
]]
function Roles.debug()
local output = ''
local output = ""
for index, role_name in ipairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
local color = role.custom_color or Colours.white
color = string.format('[color=%d, %d, %d]', color.r, color.g, color.b)
output = output..string.format('\n%s %s) %s[/color]', color, index, serpent.line(role))
color = string.format("[color=%d, %d, %d]", color.r, color.g, color.b)
output = output .. string.format("\n%s %s) %s[/color]", color, index, serpent.line(role))
end
return output
end
@@ -234,9 +236,10 @@ function Roles.print_to_roles_higher(role, message)
local roles = {}
for index, role_name in ipairs(Roles.config.order) do
if index <= role.index and role_name ~= Roles.config.internal.default then
roles[#roles+1] = role_name
roles[#roles + 1] = role_name
end
end
Roles.print_to_roles(roles, message)
end
@@ -254,9 +257,10 @@ function Roles.print_to_roles_lower(role, message)
local roles = {}
for index, role_name in ipairs(Roles.config.order) do
if index >= role.index and role_name ~= Roles.config.internal.default then
roles[#roles+1] = role_name
roles[#roles + 1] = role_name
end
end
Roles.print_to_roles(roles, message)
end
@@ -296,12 +300,12 @@ local role = Roles.get_role_from_any('Moderator')
]]
function Roles.get_role_from_any(any)
local t_any = type(any)
if t_any == 'number' or tonumber(any) then
if t_any == "number" or tonumber(any) then
any = tonumber(any)
return Roles.get_role_by_order(any)
elseif t_any == 'string' then
elseif t_any == "string" then
return Roles.get_role_by_name(any)
elseif t_any == 'table' then
elseif t_any == "table" then
return Roles.get_role_by_name(any.name)
end
end
@@ -316,13 +320,14 @@ local roles = Roles.get_player_roles(game.player)
]]
function Roles.get_player_roles(player)
player = Game.get_player_from_any(player)
if not player then return {Roles.config.roles[Roles.config.internal.root]} end
if not player then return { Roles.config.roles[Roles.config.internal.root] } end
local roles = Roles.config.players[player.name] or {}
local default = Roles.config.roles[Roles.config.internal.default]
local rtn = {default}
local rtn = { default }
for index, role_name in ipairs(roles) do
rtn[index+1] = Roles.config.roles[role_name]
rtn[index + 1] = Roles.config.roles[role_name]
end
return rtn
end
@@ -343,6 +348,7 @@ function Roles.get_player_highest_role(player)
highest = role
end
end
return highest
end
@@ -370,7 +376,7 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
if not player then return end
-- 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
roles = { roles }
end
@@ -394,10 +400,11 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
end
else
assign_later[role.name] = {
count = 1, by_player_name = by_player_name or "<server>", silent = silent
count = 1, by_player_name = by_player_name or "<server>", silent = silent,
}
end
end
Roles.config.deferred_roles[valid_player.name] = assign_later
return
end
@@ -407,7 +414,7 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
end
if valid_player then
emit_player_roles_updated(valid_player, 'assign', role_objects, by_player_name, silent)
emit_player_roles_updated(valid_player, "assign", role_objects, by_player_name, silent)
end
end
@@ -431,7 +438,7 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
if not player then return end
-- 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
roles = { roles }
end
@@ -456,10 +463,11 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
end
else
assign_later[role.name] = {
count = -1, by_player_name = by_player_name or "<server>", silent = silent
count = -1, by_player_name = by_player_name or "<server>", silent = silent,
}
end
end
Roles.config.deferred_roles[valid_player.name] = assign_later
end
@@ -490,17 +498,20 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
end
end
end
for assign_by_player_name, assign_roles in pairs(assigns) do
if #assign_roles > 0 then emit_player_roles_updated(valid_player, 'assign', assign_roles, assign_by_player_name) end
if #assign_roles > 0 then emit_player_roles_updated(valid_player, "assign", assign_roles, assign_by_player_name) end
end
for unassign_by_player_name, unassign_roles in pairs(unassigns) do
if #unassign_roles > 0 then emit_player_roles_updated(valid_player, 'unassign', unassign_roles, unassign_by_player_name) end
if #unassign_roles > 0 then emit_player_roles_updated(valid_player, "unassign", unassign_roles, unassign_by_player_name) end
end
Roles.config.deferred_roles[player.name] = nil
end
if valid_player and #role_changes > 0 then
emit_player_roles_updated(valid_player, 'unassign', role_changes, by_player_name, silent)
emit_player_roles_updated(valid_player, "unassign", role_changes, by_player_name, silent)
end
end
@@ -518,10 +529,11 @@ Roles.override_player_roles{
}
]]
function Roles.override_player_roles(player_name,roles)
function Roles.override_player_roles(player_name, roles)
local player_roles = Roles.config.players
if not roles then
for k in pairs(player_roles) do player_roles[k] = nil end
for k, new_roles in pairs(player_name) do player_roles[k] = new_roles end
else
Roles.config.players[player_name] = roles
@@ -549,6 +561,7 @@ function Roles.player_has_role(player, search_role)
for _, role in ipairs(roles) do
if role.name == search_role.name then return true end
end
return false
end
@@ -569,6 +582,7 @@ function Roles.player_has_flag(player, flag_name)
return true
end
end
return false
end
@@ -589,6 +603,7 @@ function Roles.player_allowed(player, action)
return true
end
end
return false
end
@@ -616,7 +631,7 @@ function Roles.define_role_order(order)
Roles.config.order = {}
local done = {}
for index, role in ipairs(order) do
if type(role) == 'table' and role.name then
if type(role) == "table" and role.name then
done[role.name] = true
Roles.config.order[index] = role.name
else
@@ -624,22 +639,24 @@ function Roles.define_role_order(order)
Roles.config.order[index] = role
end
end
-- Check no roles were missed
for role_name in pairs(Roles.config.roles) do
if not done[role_name] then
error('Role missing '..role_name..' from role order, all defined roles must be included.', 2)
error("Role missing " .. role_name .. " from role order, all defined roles must be included.", 2)
end
end
-- Re-links roles to they parents as this is called at the end of the config
for index, role_name in pairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
if not role then
error('Role with name '..role_name..' has not beed defined, either define it or remove it from the order list.', 2)
error("Role with name " .. role_name .. " has not beed defined, either define it or remove it from the order list.", 2)
end
role.index = index
local parent = Roles.config.roles[role.parent]
if parent then
setmetatable(role.allowed_actions, {__index=parent.allowed_actions})
setmetatable(role.allowed_actions, { __index = parent.allowed_actions })
end
end
end
@@ -696,14 +713,14 @@ local role = Roles.new_role('Moderator', 'Mod')
]]
function Roles.new_role(name, short_hand)
_C.error_if_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({
name=name,
short_hand=short_hand or name,
allowed_actions={},
allow_all_actions=false,
flags={}
}, {__index=Roles._prototype})
name = name,
short_hand = short_hand or name,
allowed_actions = {},
allow_all_actions = false,
flags = {},
}, { __index = Roles._prototype })
Roles.config.roles[name] = role
return role
end
@@ -738,12 +755,13 @@ role:allow{
]]
function Roles._prototype:allow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in ipairs(actions) do
self.allowed_actions[action]=true
self.allowed_actions[action] = true
end
return self
end
@@ -759,12 +777,13 @@ role:disallow{
]]
function Roles._prototype:disallow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in ipairs(actions) do
self.allowed_actions[action]=false
self.allowed_actions[action] = false
end
return self
end
@@ -850,7 +869,7 @@ role:set_custom_color{ r=255, g=100, b=100}
]]
function Roles._prototype:set_custom_color(color)
if type(color) ~= 'table' then
if type(color) ~= "table" then
color = Colours[color]
end
self.custom_color = color
@@ -869,7 +888,7 @@ role:set_permission_group('Admin')
function Roles._prototype:set_permission_group(name, use_factorio_api)
_C.error_if_runtime()
if use_factorio_api then
self.permission_group = {true, name}
self.permission_group = { true, name }
else
local group = Groups.get_group_by_name(name)
if not group then return end
@@ -892,7 +911,7 @@ function Roles._prototype:set_parent(role)
self.parent = role
role = Roles.get_role_from_any(role)
if not role then return self end
setmetatable(self.allowed_actions, {__index=role.allowed_actions})
setmetatable(self.allowed_actions, { __index = role.allowed_actions })
return self
end
@@ -972,13 +991,14 @@ function Roles._prototype:add_player(player, skip_check, skip_event)
for _, role_name in ipairs(player_roles) do
if role_name == self.name then return false end
end
player_roles[#player_roles+1] = self.name
player_roles[#player_roles + 1] = self.name
else
Roles.config.players[player_name] = {self.name}
Roles.config.players[player_name] = { self.name }
end
-- Emits event if required
if valid_player and not skip_event then
emit_player_roles_updated(valid_player, 'assign', {self})
emit_player_roles_updated(valid_player, "assign", { self })
end
return true
end
@@ -1018,13 +1038,14 @@ function Roles._prototype:remove_player(player, skip_check, skip_event)
break
end
end
if #player_roles == 0 then
Roles.config.players[player_name] = nil
end
end
-- Emits event if required
if valid_player and not skip_event then
emit_player_roles_updated(valid_player, 'unassign', {self})
emit_player_roles_updated(valid_player, "unassign", { self })
end
return found
end
@@ -1049,12 +1070,13 @@ function Roles._prototype:get_players(online)
local player = game.players[player_name]
-- Filter by online state if required
if player and (online == nil or player.connected == online) then
players[#players+1] = player
players[#players + 1] = player
end
break
end
end
end
return players
end
@@ -1071,6 +1093,7 @@ function Roles._prototype:print(message)
for _, player in ipairs(players) do
player.print(message)
end
return #players
end
@@ -1082,6 +1105,7 @@ local function role_update(event)
local state = Roles.player_has_flag(player, flag)
async_function(player, state)
end
-- Updates the players permission group
local highest = Roles.get_player_highest_role(player)
if highest.permission_group then
@@ -1114,7 +1138,7 @@ local function auto_assign(event)
if not lookup[role] then
local success, rtn = pcall(condition, player)
if not success then
log{'expcore-roles.error-log-format-assign', role.name, rtn}
log{ "expcore-roles.error-log-format-assign", role.name, rtn }
elseif rtn == true then
ctn = ctn + 1
assigns[ctn] = role
@@ -1139,6 +1163,5 @@ Event.on_nth_tick(3600, function()
end
end)
-- Return Roles
return Roles
return Roles

View File

@@ -13,42 +13,42 @@ Event.add(defines.events.on_player_created, function(event)
game.map_settings.enemy_expansion.enabled = config.enemy_expansion
local r = config.chart_radius
local p = player.position
player.force.chart(player.surface, {{p.x-r, p.y-r}, {p.x+r, p.y+r}})
player.force.chart(player.surface, { { p.x - r, p.y - r }, { p.x + r, p.y + r } })
end
-- spawn items
for item, callback in pairs(items) do
if type(callback) == 'function' then
if type(callback) == "function" then
local stats = player.force.get_item_production_statistics(player.surface)
local made = stats.get_input_count(item)
local success, count = pcall(callback, made, stats.get_input_count, player)
count = math.floor(count)
if success and count > 0 then
player.insert{name=item, count=count}
player.insert{ name = item, count = count }
end
end
end
if config.armor.enable then
player.insert{name=config.armor.main, count=1}
player.insert{ name = config.armor.main, count = 1 }
for _, item in pairs(config.armor.item) do
player.insert{name=item.equipment, count=item.count}
player.insert{ name = item.equipment, count = item.count }
end
end
end)
Event.on_init(function()
remote.call('freeplay', 'set_created_items', {})
remote.call('freeplay', 'set_chart_distance', 0)
remote.call('freeplay', 'set_skip_intro', config.skip_intro)
remote.call("freeplay", "set_created_items", {})
remote.call("freeplay", "set_chart_distance", 0)
remote.call("freeplay", "set_skip_intro", config.skip_intro)
if config.research_queue_from_start then
for _, force in pairs(game.forces) do
--force.research_queue_enabled = true
-- force.research_queue_enabled = true
end
end
if not config.disable_base_game_silo_script then
if config.skip_victory then
remote.call('silo_script', 'set_no_victory', true)
remote.call("silo_script", "set_no_victory", true)
end
end
end)
end)

View File

@@ -20,10 +20,10 @@ end)
--- Kicks an afk player, used to add a delay so the gui has time to appear
local kick_player_async =
Async.register(function(player)
if game.tick - primitives.last_active < config.kick_time then return end -- Safety Catch
game.kick_player(player, 'AFK while no active players on the server')
end)
Async.register(function(player)
if game.tick - primitives.last_active < config.kick_time then return end -- Safety Catch
game.kick_player(player, "AFK while no active players on the server")
end)
--- Check for an active player every update_time number of ticks
Event.on_nth_tick(config.update_time, function()
@@ -48,10 +48,10 @@ Event.on_nth_tick(config.update_time, function()
local res = player.display_resolution
local uis = player.display_scale
player.gui.screen.add{
type = 'frame',
name = 'afk-kick',
caption = {'afk-kick.message'},
}.location = { x=res.width*(0.5 - 0.11*uis), y=res.height*(0.5 - 0.14*uis) }
type = "frame",
name = "afk-kick",
caption = { "afk-kick.message" },
}.location = { x = res.width * (0.5 - 0.11 * uis), y = res.height * (0.5 - 0.14 * uis) }
-- Kick the player, some delay needed because network delay
kick_player_async:start_after(10, player)

View File

@@ -18,7 +18,7 @@ Event.add(defines.events.on_console_chat, function(event)
-- Sends the message as text above them
if config.show_player_messages then
send_text(player, {'chat-popup.message', player.name, event.message})
send_text(player, { "chat-popup.message", player.name, event.message })
end
if not config.show_player_mentions then return end
@@ -30,9 +30,8 @@ Event.add(defines.events.on_console_chat, function(event)
for _, mentioned_player in pairs(game.connected_players) do
if mentioned_player.index ~= player.index then
if search_string:find(mentioned_player.name:lower(), 1, true) then
send_text(mentioned_player, {'chat-popup.ping', player.name})
send_text(mentioned_player, { "chat-popup.ping", player.name })
end
end
end
end)
end)

View File

@@ -17,17 +17,17 @@ Event.add(defines.events.on_console_chat, function(event)
local prefix = config.command_prefix
for key_word, reply in pairs(config.messages) do
if message:find(key_word) then
local is_command = message:find(prefix..key_word)
if type(reply) == 'function' then
local is_command = message:find(prefix .. key_word)
if type(reply) == "function" then
reply = reply(player, is_command)
end
if is_command and allowed then
game.print{'chat-bot.reply', reply}
game.print{ "chat-bot.reply", reply }
elseif is_command then
player.print{'chat-bot.disallow'}
player.print{ "chat-bot.disallow" }
elseif not allowed then
player.print{'chat-bot.reply', reply}
player.print{ "chat-bot.reply", reply }
end
end
end
@@ -35,18 +35,16 @@ Event.add(defines.events.on_console_chat, function(event)
if not allowed then return end
for key_word, reply in pairs(config.commands) do
if message:find(prefix..key_word) then
if type(reply) == 'function' then
if message:find(prefix .. key_word) then
if type(reply) == "function" then
local msg = reply(player, true)
if reply then
game.print{'chat-bot.reply', msg}
game.print{ "chat-bot.reply", msg }
end
else
game.print{'chat-bot.reply', reply}
game.print{ "chat-bot.reply", reply }
end
end
end
end)
end)

View File

@@ -9,33 +9,33 @@ local messages = config.messages
local locations = config.locations
local Public = {
compilatrons={},
current_messages={}
compilatrons = {},
current_messages = {},
}
Storage.register({
compilatrons = Public.compilatrons,
current_messages = Public.current_messages
current_messages = Public.current_messages,
}, function(tbl)
Public.compilatrons = tbl.compilatrons
Public.current_messages = tbl.current_messages
end)
local speech_bubble_async =
Async.register(function(data)
local message =
data.ent.surface.create_entity{
name = 'compi-speech-bubble',
text = messages[data.name][data.msg_number],
source = data.ent,
position = {0, 0},
}
Async.register(function(data)
local message =
data.ent.surface.create_entity{
name = "compi-speech-bubble",
text = messages[data.name][data.msg_number],
source = data.ent,
position = { 0, 0 },
}
Public.current_messages[data.name] = {
message = message,
msg_number = data.msg_number
}
end)
Public.current_messages[data.name] = {
message = message,
msg_number = data.msg_number,
}
end)
--- This will move the messages onto the next message in the loop
local function circle_messages()
@@ -57,7 +57,7 @@ local function circle_messages()
msg_number = 1
end
-- this calls the callback above to re-spawn the message after some time
speech_bubble_async:start_after(300, {ent = ent, name = name, msg_number = msg_number})
speech_bubble_async:start_after(300, { ent = ent, name = name, msg_number = msg_number })
end
end
@@ -77,10 +77,10 @@ function Public.add_compilatron(entity, name)
Public.compilatrons[name] = entity
local message =
entity.surface.create_entity(
{name = 'compi-speech-bubble', text = messages[name][1], position = {0, 0}, source = entity}
)
Public.current_messages[name] = {message = message, msg_number = 1}
entity.surface.create_entity
{ name = "compi-speech-bubble", text = messages[name][1], position = { 0, 0 }, source = entity }
Public.current_messages[name] = { message = message, msg_number = 1 }
end
--- This spawns a new compilatron on a surface with the given location tag (not a position)
@@ -88,8 +88,8 @@ end
-- @tparam string location the location tag that is in the config file
function Public.spawn_compilatron(surface, location)
local position = locations[location]
local pos = surface.find_non_colliding_position('small-biter', position, 1.5, 0.5)
local compi = surface.create_entity {name='small-biter', position=pos, force=game.forces.neutral}
local pos = surface.find_non_colliding_position("small-biter", position, 1.5, 0.5)
local compi = surface.create_entity{ name = "small-biter", position = pos, force = game.forces.neutral }
Public.add_compilatron(compi, location)
end

View File

@@ -12,21 +12,21 @@ Event.add(defines.events.on_entity_damaged, function(event)
local damage = math.floor(event.original_damage_amount)
local health = math.floor(entity.health)
local health_percentage = entity.get_health_ratio()
local text_colour = {r=1-health_percentage, g=health_percentage, b=0}
local text_colour = { r = 1 - health_percentage, g = health_percentage, b = 0 }
-- Gets the location of the text
local size = entity.get_radius()
if size < 1 then size = 1 end
local r = (math.random()-0.5)*size*config.damage_location_variance
local r = (math.random() - 0.5) * size * config.damage_location_variance
local p = entity.position
local position = {x=p.x+r, y=p.y-size}
local position = { x = p.x + r, y = p.y - size }
-- Sets the message
local message
if entity.name == 'character' and config.show_player_health then
message = {'damage-popup.player-health', health}
elseif entity.name ~= 'character' and cause and cause.name == 'character' and config.show_player_damage then
message = {'damage-popup.player-damage', damage}
if entity.name == "character" and config.show_player_health then
message = { "damage-popup.player-health", health }
elseif entity.name ~= "character" and cause and cause.name == "character" and config.show_player_damage then
message = { "damage-popup.player-damage", damage }
end
-- Outputs the message as floating text
@@ -38,5 +38,4 @@ Event.add(defines.events.on_entity_damaged, function(event)
text_colour
)
end
end)
end)

View File

@@ -7,11 +7,11 @@ local config = require("modules.exp_legacy.config.death_logger") --- @dep config
local format_time, move_items = _C.format_time, _C.move_items_stack --- @dep expcore.common
-- Max amount of ticks a corpse can be alive
local corpse_lifetime = 60*60*15
local corpse_lifetime = 60 * 60 * 15
local deaths = {
archive={} -- deaths moved here after body is gone
--{player_name='Cooldude2606', time_of_death='15H 15M', position={x=0, y=0}, corpse=LuaEntity, tag=LuaCustomChartTag}
archive = {}, -- deaths moved here after body is gone
-- {player_name='Cooldude2606', time_of_death='15H 15M', position={x=0, y=0}, corpse=LuaEntity, tag=LuaCustomChartTag}
}
Storage.register(deaths, function(tbl)
deaths = tbl
@@ -20,15 +20,15 @@ end)
--- Creates a new death marker and saves it to the given death
local function create_map_tag(death)
local player = game.players[death.player_name]
local message = player.name..' died'
local message = player.name .. " died"
if config.include_time_of_death then
local time = format_time(death.time_of_death, {hours=true, minutes=true, string=true})
message = message..' at '..time
local time = format_time(death.time_of_death, { hours = true, minutes = true, string = true })
message = message .. " at " .. time
end
death.tag = player.force.add_chart_tag(player.surface, {
position=death.position,
icon=config.map_icon,
text=message
position = death.position,
icon = config.map_icon,
text = message,
})
end
@@ -62,7 +62,7 @@ end
-- when a player dies a new death is added to the records and a map marker is made
Event.add(defines.events.on_player_died, function(event)
local player = game.players[event.player_index]
local corpse = player.surface.find_entity('character-corpse', player.position)
local corpse = player.surface.find_entity("character-corpse", player.position)
if config.use_chests_as_bodies then
local items = corpse.get_inventory(defines.inventory.character_corpse)
local chest = move_items(items, corpse.surface, corpse.position)
@@ -74,7 +74,7 @@ Event.add(defines.events.on_player_died, function(event)
player_name = player.name,
time_of_death = event.tick,
position = player.position,
corpse = corpse
corpse = corpse,
}
if config.show_map_markers then
create_map_tag(death)
@@ -84,11 +84,11 @@ Event.add(defines.events.on_player_died, function(event)
-- Draw a light attached to the corpse with the player color
if config.show_light_at_corpse then
rendering.draw_light{
sprite = 'utility/light_medium',
sprite = "utility/light_medium",
color = player.color,
target = corpse,
force = player.force,
surface = player.surface
surface = player.surface,
}
end
end)
@@ -122,7 +122,7 @@ if config.show_line_to_corpse then
dash_length = 1,
gap_length = 1,
surface = player.surface,
draw_on_ground = true
draw_on_ground = true,
}
end
end
@@ -131,7 +131,7 @@ end
-- every 5 min all bodies are checked for valid map tags
if config.show_map_markers then
local check_period = 60*60*5 -- five minutes
local check_period = 60 * 60 * 5 -- five minutes
Event.on_nth_tick(check_period, function()
check_map_tags()
end)
@@ -141,9 +141,9 @@ if config.auto_collect_bodies then
Event.add(defines.events.on_character_corpse_expired, function(event)
local corpse = event.corpse
local items = corpse.get_inventory(defines.inventory.character_corpse)
move_items(items, corpse.surface, {x=0, y=0})
move_items(items, corpse.surface, { x = 0, y = 0 })
end)
end
-- this is so other modules can access the logs
return deaths
return deaths

View File

@@ -10,19 +10,19 @@ local config = require("modules.exp_legacy.config.deconlog") --- @dep config.dec
local filepath = "log/decon.log"
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
local function get_secs()
return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true })
return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true })
end
local function pos_to_string(pos)
return tostring(pos.x) .. "," .. tostring(pos.y)
return tostring(pos.x) .. "," .. tostring(pos.y)
end
local function pos_to_gps_string(pos)
return '[gps=' .. string.format('%.1f', pos.x) .. ',' .. string.format('%.1f', pos.y) .. ']'
return "[gps=" .. string.format("%.1f", pos.x) .. "," .. string.format("%.1f", pos.y) .. "]"
end
--- Print a message to all players who match the value of admin
@@ -35,107 +35,107 @@ local function print_to_players(admin, message)
end
Event.on_init(function()
game.write_file(filepath, "\n", false, 0) -- write data
game.write_file(filepath, "\n", false, 0) -- write data
end)
if config.decon_area then
Event.add(defines.events.on_player_deconstructed_area, function(e)
if e.alt then
return
end
Event.add(defines.events.on_player_deconstructed_area, function(e)
if e.alt then
return
end
local player = game.get_player(e.player_index)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, 'deconlog-bypass') then
return
end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local items = e.surface.find_entities_filtered{area=e.area, force=player.force}
local items = e.surface.find_entities_filtered{ area = e.area, force = player.force }
if #items > 250 then
print_to_players(true, {'deconlog.decon', player.name, e.surface.name, pos_to_gps_string(e.area.left_top), pos_to_gps_string(e.area.right_bottom), format_number(#items)})
end
if #items > 250 then
print_to_players(true, { "deconlog.decon", player.name, e.surface.name, pos_to_gps_string(e.area.left_top), pos_to_gps_string(e.area.right_bottom), format_number(#items) })
end
add_log(get_secs() .. ',' .. player.name .. ',decon_area,' .. e.surface.name .. ',' .. pos_to_string(e.area.left_top) .. ',' .. pos_to_string(e.area.right_bottom))
end)
add_log(get_secs() .. "," .. player.name .. ",decon_area," .. e.surface.name .. "," .. pos_to_string(e.area.left_top) .. "," .. pos_to_string(e.area.right_bottom))
end)
end
if config.built_entity then
Event.add(defines.events.on_built_entity, function (e)
if not e.player_index then return end
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.created_entity
add_log(get_secs() .. "," .. player.name .. ",built_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
Event.add(defines.events.on_built_entity, function(e)
if not e.player_index then return end
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.created_entity
add_log(get_secs() .. "," .. player.name .. ",built_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.mined_entity then
Event.add(defines.events.on_player_mined_entity, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.entity
add_log(get_secs() .. "," .. player.name .. ",mined_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
Event.add(defines.events.on_player_mined_entity, function(e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.entity
add_log(get_secs() .. "," .. player.name .. ",mined_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.fired_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
Event.add(defines.events.on_player_ammo_inventory_changed, function(e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end
if config.fired_explosive_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
Event.add(defines.events.on_player_ammo_inventory_changed, function(e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "explosive-rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-explosive-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "explosive-rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-explosive-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end
if config.fired_nuke then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
Event.add(defines.events.on_player_ammo_inventory_changed, function(e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then
return
end
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "atomic-bomb" then
add_log(get_secs() .. "," .. player.name .. ",shot-nuke," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
if item.name == "atomic-bomb" then
add_log(get_secs() .. "," .. player.name .. ",shot-nuke," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end

View File

@@ -6,7 +6,7 @@ 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 playtime_format = {hours = true, minutes = true, short = true, string = true}
local playtime_format = { hours = true, minutes = true, short = true, string = true }
local function append_playtime(player_name)
if not config.show_playtime then
@@ -19,7 +19,7 @@ local function append_playtime(player_name)
return player_name
end
return player.name ..' (' .. format_time(player.online_time, playtime_format) .. ')'
return player.name .. " (" .. format_time(player.online_time, playtime_format) .. ")"
end
local function get_player_name(event)
@@ -28,27 +28,27 @@ local function get_player_name(event)
end
local function to_hex(color)
local hex_digits = '0123456789ABCDEF'
local hex_digits = "0123456789ABCDEF"
local function hex(bit)
local major, minor = math.modf(bit/16)
major, minor = major+1, minor*16+1
local major, minor = math.modf(bit / 16)
major, minor = major + 1, minor * 16 + 1
return hex_digits:sub(major, major) .. hex_digits:sub(minor, minor)
end
return '0x' .. hex(color.r) .. hex(color.g) .. hex(color.b)
return "0x" .. hex(color.r) .. hex(color.g) .. hex(color.b)
end
local function emit_event(args)
local title = args.title or ''
local color = args.color or '0x0'
local description = args.description or ''
local title = args.title or ""
local color = args.color or "0x0"
local description = args.description or ""
if type(color) == 'table' then
if type(color) == "table" then
color = to_hex(color)
end
local tick = args.tick or game.tick
local tick_formatted = format_time(tick, {days = false, hours = true, minutes = true, short = true, string = true})
local tick_formatted = format_time(tick, { days = false, hours = true, minutes = true, short = true, string = true })
local players_online = 0
local admins_online = 0
@@ -61,22 +61,22 @@ local function emit_event(args)
end
end
local done = {title=true, color=true, description=true}
local fields = {{
name='Server Details',
value=string.format('Server: ${serverName} Time: %s\nTotal: %d Online: %d Admins: %d', tick_formatted, #game.players, players_online, admins_online)
}}
local done = { title = true, color = true, description = true }
local fields = { {
name = "Server Details",
value = string.format("Server: ${serverName} Time: %s\nTotal: %d Online: %d Admins: %d", tick_formatted, #game.players, players_online, admins_online),
} }
for key, value in pairs(args) do
if not done[key] then
done[key] = true
local field = {
name=key,
value=value,
inline=false
name = key,
value = value,
inline = false,
}
local new_value, inline = value:gsub('<inline>', '', 1)
local new_value, inline = value:gsub("<inline>", "", 1)
if inline > 0 then
field.value = new_value
field.inline = true
@@ -86,11 +86,11 @@ local function emit_event(args)
end
end
write_json('ext/discord.out',{
title=title,
description=description,
color=color,
fields=fields
write_json("ext/discord.out", {
title = title,
description = description,
color = color,
fields = fields,
})
end
@@ -100,12 +100,12 @@ if config.entity_protection then
Event.add(EntityProtection.events.on_repeat_violation, function(event)
local player_name = get_player_name(event)
emit_event{
title='Entity Protection',
description='A player removed protected entities',
color=Colors.yellow,
['Player']='<inline>' .. append_playtime(player_name),
['Entity']='<inline>' .. event.entity.name,
['Location']='X ' .. event.entity.position.x .. ' Y ' .. event.entity.position.y
title = "Entity Protection",
description = "A player removed protected entities",
color = Colors.yellow,
["Player"] = "<inline>" .. append_playtime(player_name),
["Entity"] = "<inline>" .. event.entity.name,
["Location"] = "X " .. event.entity.position.x .. " Y " .. event.entity.position.y,
}
end)
end
@@ -116,25 +116,25 @@ if config.player_reports then
Event.add(Reports.events.on_player_reported, function(event)
local player_name, by_player_name = get_player_name(event)
emit_event{
title='Report',
description='A player was reported',
color=Colors.yellow,
['Player']='<inline>' .. append_playtime(player_name),
['By']='<inline>' .. append_playtime(by_player_name),
['Report Count']='<inline>' .. Reports.count_reports(player_name),
['Reason']=event.reason
title = "Report",
description = "A player was reported",
color = Colors.yellow,
["Player"] = "<inline>" .. append_playtime(player_name),
["By"] = "<inline>" .. append_playtime(by_player_name),
["Report Count"] = "<inline>" .. Reports.count_reports(player_name),
["Reason"] = event.reason,
}
end)
Event.add(Reports.events.on_report_removed, function(event)
if event.batch ~= 1 then return end
local player_name = get_player_name(event)
emit_event{
title='Reports Removed',
description='A player has a report removed',
color=Colors.green,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. event.removed_by_name,
['Report Count']='<inline>' .. event.batch_count
title = "Reports Removed",
description = "A player has a report removed",
color = Colors.green,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. event.removed_by_name,
["Report Count"] = "<inline>" .. event.batch_count,
}
end)
end
@@ -146,25 +146,25 @@ if config.player_warnings then
local player_name, by_player_name = get_player_name(event)
local player = game.get_player(player_name)
emit_event{
title='Warning',
description='A player has been given a warning',
color=Colors.yellow,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name,
['Warning Count']='<inline>' .. Warnings.count_warnings(player),
['Reason']=event.reason
title = "Warning",
description = "A player has been given a warning",
color = Colors.yellow,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. by_player_name,
["Warning Count"] = "<inline>" .. Warnings.count_warnings(player),
["Reason"] = event.reason,
}
end)
Event.add(Warnings.events.on_warning_removed, function(event)
if event.batch ~= 1 then return end
local player_name = get_player_name(event)
emit_event{
title='Warnings Removed',
description='A player has a warning removed',
color=Colors.green,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. event.removed_by_name,
['Warning Count']='<inline>' .. event.batch_count
title = "Warnings Removed",
description = "A player has a warning removed",
color = Colors.green,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. event.removed_by_name,
["Warning Count"] = "<inline>" .. event.batch_count,
}
end)
end
@@ -175,22 +175,22 @@ if config.player_jail then
Event.add(Jail.events.on_player_jailed, function(event)
local player_name, by_player_name = get_player_name(event)
emit_event{
title='Jail',
description='A player has been jailed',
color=Colors.yellow,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name,
['Reason']=event.reason
title = "Jail",
description = "A player has been jailed",
color = Colors.yellow,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. by_player_name,
["Reason"] = event.reason,
}
end)
Event.add(Jail.events.on_player_unjailed, function(event)
local player_name, by_player_name = get_player_name(event)
emit_event{
title='Unjail',
description='A player has been unjailed',
color=Colors.green,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name
title = "Unjail",
description = "A player has been unjailed",
color = Colors.green,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. by_player_name,
}
end)
end
@@ -201,12 +201,12 @@ if config.player_bans then
if event.by_player then
local by_player = game.players[event.by_player]
emit_event{
title='Banned',
description='A player has been banned',
color=Colors.red,
['Player']='<inline>' .. event.player_name,
['By']='<inline>' .. by_player.name,
['Reason']=event.reason
title = "Banned",
description = "A player has been banned",
color = Colors.red,
["Player"] = "<inline>" .. event.player_name,
["By"] = "<inline>" .. by_player.name,
["Reason"] = event.reason,
}
end
end)
@@ -214,11 +214,11 @@ if config.player_bans then
if event.by_player then
local by_player = game.players[event.by_player]
emit_event{
title='Un-Banned',
description='A player has been un-banned',
color=Colors.green,
['Player']='<inline>' .. event.player_name,
['By']='<inline>' .. by_player.name
title = "Un-Banned",
description = "A player has been un-banned",
color = Colors.green,
["Player"] = "<inline>" .. event.player_name,
["By"] = "<inline>" .. by_player.name,
}
end
end)
@@ -229,19 +229,19 @@ if config.player_mutes then
Event.add(defines.events.on_player_muted, function(event)
local player_name = get_player_name(event)
emit_event{
title='Muted',
description='A player has been muted',
color=Colors.yellow,
['Player']='<inline>' .. player_name
title = "Muted",
description = "A player has been muted",
color = Colors.yellow,
["Player"] = "<inline>" .. player_name,
}
end)
Event.add(defines.events.on_player_unmuted, function(event)
local player_name = get_player_name(event)
emit_event{
title='Un-Muted',
description='A player has been un-muted',
color=Colors.green,
['Player']='<inline>' .. player_name
title = "Un-Muted",
description = "A player has been un-muted",
color = Colors.green,
["Player"] = "<inline>" .. player_name,
}
end)
end
@@ -253,12 +253,12 @@ if config.player_kicks then
local player_name = get_player_name(event)
local by_player = game.players[event.by_player]
emit_event{
title='Kick',
description='A player has been kicked',
color=Colors.orange,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player.name,
['Reason']=event.reason
title = "Kick",
description = "A player has been kicked",
color = Colors.orange,
["Player"] = "<inline>" .. player_name,
["By"] = "<inline>" .. by_player.name,
["Reason"] = event.reason,
}
end
end)
@@ -269,19 +269,19 @@ if config.player_promotes then
Event.add(defines.events.on_player_promoted, function(event)
local player_name = get_player_name(event)
emit_event{
title='Promote',
description='A player has been promoted',
color=Colors.green,
['Player']='<inline>' .. player_name
title = "Promote",
description = "A player has been promoted",
color = Colors.green,
["Player"] = "<inline>" .. player_name,
}
end)
Event.add(defines.events.on_player_demoted, function(event)
local player_name = get_player_name(event)
emit_event{
title='Demote',
description='A player has been demoted',
color=Colors.yellow,
['Player']='<inline>' .. player_name
title = "Demote",
description = "A player has been demoted",
color = Colors.yellow,
["Player"] = "<inline>" .. player_name,
}
end)
end
@@ -292,11 +292,11 @@ Event.add(defines.events.on_console_command, function(event)
local player_name = get_player_name(event)
if config[event.command] then
emit_event{
title=event.command:gsub('^%l', string.upper),
description='/' .. event.command .. ' was used',
color=Colors.grey,
['By']='<inline>' .. player_name,
['Details'] = event.parameters ~= '' and event.parameters or nil
title = event.command:gsub("^%l", string.upper),
description = "/" .. event.command .. " was used",
color = Colors.grey,
["By"] = "<inline>" .. player_name,
["Details"] = event.parameters ~= "" and event.parameters or nil,
}
end
end

View File

@@ -5,15 +5,15 @@ local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
-- Clear the file on startup to minimize its size
Event.on_init(function()
game.write_file("fagc-actions.txt", "", false, 0)
game.write_file("fagc-actions.txt", "", false, 0)
end)
Event.add(defines.events.on_player_banned, function(e)
local text = "ban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
local text = "ban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
end)
Event.add(defines.events.on_player_unbanned, function(e)
local text = "unban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
local text = "unban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
end)

View File

@@ -1,23 +1,23 @@
local Event = require("modules/exp_legacy/utils/event")
local controllers_with_inventory = {
[defines.controllers.character] = true,
[defines.controllers.god] = true,
[defines.controllers.editor] = true,
[defines.controllers.character] = true,
[defines.controllers.god] = true,
[defines.controllers.editor] = true,
}
Event.add(defines.events.on_player_mined_entity, function(event)
if (not event.entity.valid) or (event.entity.type ~= 'inserter') or event.entity.drop_target then
if (not event.entity.valid) or (event.entity.type ~= "inserter") or event.entity.drop_target then
return
end
local item_entity = event.entity.surface.find_entity('item-on-ground', event.entity.drop_position)
local item_entity = event.entity.surface.find_entity("item-on-ground", event.entity.drop_position)
if item_entity then
local player = game.get_player(event.player_index)
if item_entity then
local player = game.get_player(event.player_index)
if controllers_with_inventory[player.controller_type] then
player.mine_entity(item_entity)
end
end
if controllers_with_inventory[player.controller_type] then
player.mine_entity(item_entity)
end
end
end)

View File

@@ -8,52 +8,52 @@ local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local config = require("modules.exp_legacy.config.lawnmower") --- @dep config.lawnmower
require("modules.exp_legacy.config.expcore.command_general_parse")
Commands.new_command('lawnmower', {'expcom-lawnmower.description'}, 'Clean up biter corpse, decoratives and nuclear hole')
:add_param('range', false, 'integer-range', 1, 200)
:register(function(player, range)
local tile_to_do = {}
Commands.new_command("lawnmower", "Clean up biter corpse, decoratives and nuclear hole")
:add_param("range", false, "integer-range", 1, 200)
:register(function(player, range)
local tile_to_do = {}
player.surface.destroy_decoratives({position=player.position, radius=range})
player.surface.destroy_decoratives{ position = player.position, radius = range }
local entities = player.surface.find_entities_filtered{position=player.position, radius=range, type='corpse'}
local entities = player.surface.find_entities_filtered{ position = player.position, radius = range, type = "corpse" }
for _, entity in pairs(entities) do
if (entity.name ~= 'transport-caution-corpse' and entity.name ~= 'invisible-transport-caution-corpse') then
entity.destroy()
end
end
for _, entity in pairs(entities) do
if (entity.name ~= "transport-caution-corpse" and entity.name ~= "invisible-transport-caution-corpse") then
entity.destroy()
end
end
local tiles = player.surface.find_tiles_filtered{position=player.position, radius=range, name={'nuclear-ground'}}
local tiles = player.surface.find_tiles_filtered{ position = player.position, radius = range, name = { "nuclear-ground" } }
for _, tile in pairs(tiles) do
table.insert(tile_to_do, {name='grass-1', position=tile.position})
end
for _, tile in pairs(tiles) do
table.insert(tile_to_do, { name = "grass-1", position = tile.position })
end
player.surface.set_tiles(tile_to_do)
player.surface.set_tiles(tile_to_do)
return Commands.success
end)
return Commands.success
end)
local function destroy_decoratives(entity)
if entity.type ~= 'entity-ghost' and entity.type ~= 'tile-ghost' and entity.prototype.selectable_in_game then
entity.surface.destroy_decoratives{area=entity.selection_box}
if entity.type ~= "entity-ghost" and entity.type ~= "tile-ghost" and entity.prototype.selectable_in_game then
entity.surface.destroy_decoratives{ area = entity.selection_box }
end
end
if config.destroy_decoratives then
Event.add(defines.events.on_built_entity, function(event)
destroy_decoratives(event.created_entity)
end)
Event.add(defines.events.on_built_entity, function(event)
destroy_decoratives(event.created_entity)
end)
Event.add(defines.events.on_robot_built_entity, function(event)
destroy_decoratives(event.created_entity)
end)
Event.add(defines.events.on_robot_built_entity, function(event)
destroy_decoratives(event.created_entity)
end)
Event.add(defines.events.script_raised_built, function(event)
destroy_decoratives(event.entity)
end)
Event.add(defines.events.script_raised_built, function(event)
destroy_decoratives(event.entity)
end)
Event.add(defines.events.script_raised_revive, function(event)
destroy_decoratives(event.entity)
end)
Event.add(defines.events.script_raised_revive, function(event)
destroy_decoratives(event.entity)
end)
end

View File

@@ -7,17 +7,14 @@ local config = require("modules.exp_legacy.config.logging") --- @dep config.logg
local config_res = require("modules.exp_legacy.config.research") --- @dep config.research
local function add_log(data)
game.write_file(config.file_name, data, true, 0)
game.write_file(config.file_name, '\n', true, 0)
game.write_file(config.file_name, data, true, 0)
game.write_file(config.file_name, "\n", true, 0)
end
Event.add(defines.events.on_rocket_launched, function(event)
if event and event.rocket and event.rocket.force and event.rocket.force.rockets_launched then
if event.rocket.force.rockets_launched >= config.rocket_launch_display_rate and event.rocket.force.rockets_launched % config.rocket_launch_display_rate == 0 then
add_log('[ROCKET] ' .. event.rocket.force.rockets_launched .. ' rockets launched')
elseif config.rocket_launch_display[event.rocket.force.rockets_launched] then
add_log('[ROCKET] ' .. event.rocket.force.rockets_launched .. ' rockets launched')
if config.rocket_launch_display[event.rocket.force.rockets_launched] then
add_log("[ROCKET] " .. event.rocket.force.rockets_launched .. " rockets launched")
end
end
end)
@@ -25,15 +22,13 @@ end)
Event.add(defines.events.on_pre_player_died, function(event)
if event and event.player_index then
if event.cause then
if event.cause.type and event.cause.type == 'character' and event.cause.player and event.cause.player.index then
add_log('[DEATH] ' .. game.players[event.player_index].name .. ' died because of ' .. (game.players[event.cause.player.index].name or 'unknown reason'))
if event.cause.type and event.cause.type == "character" and event.cause.player and event.cause.player.index then
add_log("[DEATH] " .. game.players[event.player_index].name .. " died because of " .. (game.players[event.cause.player.index].name or "unknown reason"))
else
add_log('[DEATH] ' .. game.players[event.player_index].name .. ' died because of ' .. (event.cause.name or 'unknown reason'))
add_log("[DEATH] " .. game.players[event.player_index].name .. " died because of " .. (event.cause.name or "unknown reason"))
end
else
add_log('[DEATH] ' .. game.players[event.player_index].name .. ' died because of unknown reason')
add_log("[DEATH] " .. game.players[event.player_index].name .. " died because of unknown reason")
end
end
end)
@@ -45,27 +40,25 @@ Event.add(defines.events.on_research_finished, function(event)
end
if (event.research.level and config_res.inf_res[event.research.name]) and (event.research.level >= config_res.inf_res[event.research.name]) then
add_log({'logging.add-l', event.research.prototype.localised_name, event.research.level - 1})
add_log{ "logging.add-l", event.research.prototype.localised_name, event.research.level - 1 }
else
add_log({'logging.add-n', event.research.prototype.localised_name})
add_log{ "logging.add-n", event.research.prototype.localised_name }
end
end
end)
Event.add(defines.events.on_player_joined_game, function(event)
if event and event.player_index then
add_log('[JOIN] ' .. game.players[event.player_index].name .. ' joined the game')
add_log("[JOIN] " .. game.players[event.player_index].name .. " joined the game")
end
end)
Event.add(defines.events.on_player_left_game, function(event)
if event and event.player_index then
if event.reason then
add_log('[LEAVE] ' .. game.players[event.player_index].name .. config.disconnect_reason[event.reason])
add_log("[LEAVE] " .. game.players[event.player_index].name .. config.disconnect_reason[event.reason])
else
add_log('[LEAVE] ' .. game.players[event.player_index].name .. config.disconnect_reason[defines.disconnect_reason.quit])
add_log("[LEAVE] " .. game.players[event.player_index].name .. config.disconnect_reason[defines.disconnect_reason.quit])
end
end
end)

View File

@@ -12,9 +12,8 @@ miner_data.queue = {}
local function drop_target(entity)
if entity.drop_target then
return entity.drop_target
else
local entities = entity.surface.find_entities_filtered{position=entity.drop_position}
local entities = entity.surface.find_entities_filtered{ position = entity.drop_position }
if #entities > 0 then
return entities[1]
@@ -43,7 +42,7 @@ local function check_entity(entity)
return true
end
if entity.has_flag('not-deconstructable') then
if entity.has_flag("not-deconstructable") then
-- if it can deconstruct
return true
end
@@ -58,13 +57,13 @@ local function chest_check(entity)
return
end
if target.type ~= 'logistic-container' and target.type ~= 'container' then
if target.type ~= "logistic-container" and target.type ~= "container" then
-- not a chest
return
end
local radius = 2
local entities = target.surface.find_entities_filtered{area={{target.position.x - radius, target.position.y - radius}, {target.position.x + radius, target.position.y + radius}}, type={'mining-drill', 'inserter'}}
local entities = target.surface.find_entities_filtered{ area = { { target.position.x - radius, target.position.y - radius }, { target.position.x + radius, target.position.y + radius } }, type = { "mining-drill", "inserter" } }
for _, e in pairs(entities) do
if drop_target(e) == target then
@@ -75,7 +74,7 @@ local function chest_check(entity)
end
if check_entity(target) then
table.insert(miner_data.queue, {t=game.tick + 10, e=target})
table.insert(miner_data.queue, { t = game.tick + 10, e = target })
end
end
@@ -85,7 +84,7 @@ local function miner_check(entity)
local ef = entity.force
local er = entity.prototype.mining_drill_radius
for _, r in pairs(entity.surface.find_entities_filtered{area={{x=ep.x - er, y=ep.y - er}, {x=ep.x + er, y=ep.y + er}}, type='resource'}) do
for _, r in pairs(entity.surface.find_entities_filtered{ area = { { x = ep.x - er, y = ep.y - er }, { x = ep.x + er, y = ep.y + er } }, type = "resource" }) do
if r.amount > 0 then
return
end
@@ -103,35 +102,32 @@ local function miner_check(entity)
if config.fluid and entity.fluidbox and #entity.fluidbox > 0 then
-- if require fluid to mine
table.insert(pipe_build, {x=0, y=0})
table.insert(pipe_build, { x = 0, y = 0 })
local half = math.floor(entity.get_radius())
local r = 1 + er
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 = es.find_entities_filtered{ area = { { ep.x - r, ep.y - r }, { ep.x + r, ep.y + r } }, type = { "mining-drill", "pipe", "pipe-to-ground" } }
local entities_t = es.find_entities_filtered{ area = { { ep.x - r, ep.y - r }, { ep.x + r, ep.y + r } }, ghost_type = { "pipe", "pipe-to-ground" } }
table.array_insert(entities, entities_t)
for _, e in pairs(entities) do
if (e.position.x > ep.x) and (e.position.y == ep.y) then
for h=1, half do
table.insert(pipe_build, {x=h, y=0})
for h = 1, half do
table.insert(pipe_build, { x = h, y = 0 })
end
elseif (e.position.x < ep.x) and (e.position.y == ep.y) then
for h=1, half do
table.insert(pipe_build, {x=-h, y=0})
for h = 1, half do
table.insert(pipe_build, { x = -h, y = 0 })
end
elseif (e.position.x == ep.x) and (e.position.y > ep.y) then
for h=1, half do
table.insert(pipe_build, {x=0, y=h})
for h = 1, half do
table.insert(pipe_build, { x = 0, y = h })
end
elseif (e.position.x == ep.x) and (e.position.y < ep.y) then
for h=1, half do
table.insert(pipe_build, {x=0, y=-h})
for h = 1, half do
table.insert(pipe_build, { x = 0, y = -h })
end
end
end
@@ -141,10 +137,10 @@ local function miner_check(entity)
chest_check(entity)
end
table.insert(miner_data.queue, {t=game.tick + 5, e=entity})
table.insert(miner_data.queue, { t = game.tick + 5, e = entity })
for _, pos in ipairs(pipe_build) do
es.create_entity{name='entity-ghost', position={x=ep.x + pos.x, y=ep.y + pos.y}, force=ef, inner_name='pipe', raise_built=true}
es.create_entity{ name = "entity-ghost", position = { x = ep.x + pos.x, y = ep.y + pos.y }, force = ef, inner_name = "pipe", raise_built = true }
end
end
@@ -153,7 +149,7 @@ Event.add(defines.events.on_resource_depleted, function(event)
return
end
local entities = event.entity.surface.find_entities_filtered{area={{event.entity.position.x - 1, event.entity.position.y - 1}, {event.entity.position.x + 1, event.entity.position.y + 1}}, type='mining-drill'}
local entities = event.entity.surface.find_entities_filtered{ area = { { event.entity.position.x - 1, event.entity.position.y - 1 }, { event.entity.position.x + 1, event.entity.position.y + 1 } }, type = "mining-drill" }
if #entities == 0 then
return
@@ -171,7 +167,6 @@ Event.on_nth_tick(10, function(event)
if not q.e or not q.e.valid then
table.remove(miner_data.queue, k)
break
elseif event.tick >= q.t then
q.e.order_deconstruction(q.e.force)
table.remove(miner_data.queue, k)

View File

@@ -1,46 +1,44 @@
--- Disable new players from having certain items in their inventory, most commonly nukes
-- @addon Nukeprotect
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
local config = require("modules.exp_legacy.config.nukeprotect") --- @dep config.nukeprotect
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
local config = require("modules.exp_legacy.config.nukeprotect") --- @dep config.nukeprotect
local move_items_stack = _C.move_items_stack --- @dep expcore.common
local function check_items(player, type)
-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end
-- if the players
if config.ignore_admins and player.admin then return end
-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end
-- if the players
if config.ignore_admins and player.admin then return end
local inventory = player.get_inventory(type)
for i = 1, #inventory do
local item = inventory[i]
if item.valid and item.valid_for_read and config[tostring(type)][item.name] then
player.print({ "nukeprotect.found", { "item-name." .. item.name } })
-- insert the items into the table so all items are transferred at once
move_items_stack({ item })
end
end
local inventory = player.get_inventory(type)
for i = 1, #inventory do
local item = inventory[i]
if item.valid and item.valid_for_read and config[tostring(type)][item.name] then
player.print{ "nukeprotect.found", { "item-name." .. item.name } }
-- insert the items into the table so all items are transferred at once
move_items_stack{ item }
end
end
end
for _, inventory in ipairs(config.inventories) do
if #inventory.items > 0 then
Event.add(inventory.event, function(event)
local player = game.get_player(event.player_index)
if player and player.valid then
check_items(player, inventory.inventory)
end
end)
end
if #inventory.items > 0 then
Event.add(inventory.event, function(event)
local player = game.get_player(event.player_index)
if player and player.valid then
check_items(player, inventory.inventory)
end
end)
end
end
if config.disable_nuke_research then
Event.add(defines.events.on_research_started, function(event)
local name = event.research.name
if config.disable_nuke_research_names[name] then
event.research.force.cancel_current_research()
end
end)
Event.add(defines.events.on_research_started, function(event)
local name = event.research.name
if config.disable_nuke_research_names[name] then
event.research.force.cancel_current_research()
end
end)
end

View File

@@ -8,9 +8,9 @@ local delay = config.update_delay * 3600 -- convert from minutes to ticks
Event.on_nth_tick(delay, function()
local surface = game.surfaces[1]
local true_max = surface.get_pollution(config.reference_point)
local max = true_max*config.max_scalar
local min = max*config.min_scalar
local max = true_max * config.max_scalar
local min = max * config.min_scalar
local settings = game.map_settings.pollution
settings.expected_max_per_chunk = max
settings.min_to_show_per_chunk = min
end)
end)

View File

@@ -1,9 +1,9 @@
--- When a player triggers protection multiple times they are automatically jailed
-- @addon protection-jail
local Event = require("modules/exp_legacy/utils/event") ---@dep utils.event
local Storage = require("modules/exp_util/storage") ---@dep utils.global
local Jail = require("modules.exp_legacy.modules.control.jail") ---@dep modules.control.jail
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Storage = require("modules/exp_util/storage") --- @dep utils.global
local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
local Protection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
@@ -30,11 +30,11 @@ Event.add(Protection.events.on_repeat_violation, function(event)
end
local player_name_color = format_chat_player_name(player)
Jail.jail_player(player, '<protection>', 'Removed too many protected entities, please wait for a moderator.')
game.print{'protection-jail.jail', player_name_color}
Jail.jail_player(player, "<protection>", "Removed too many protected entities, please wait for a moderator.")
game.print{ "protection-jail.jail", player_name_color }
end)
--- Clear the counter when they leave the game (stops a build up of data)
Event.add(defines.events.on_player_left_game, function(event)
repeat_count[event.player_index] = nil
end)
end)

View File

@@ -1,8 +1,8 @@
--- When a player is reported, the player is automatically jailed if the combined playtime of the reporters exceeds the reported player
-- @addon report-jail
local Event = require("modules/exp_legacy/utils/event") ---@dep utils.event
local Jail = require("modules.exp_legacy.modules.control.jail") ---@dep modules.control.jail
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
@@ -22,7 +22,7 @@ Event.add(Reports.events.on_player_reported, function(event)
-- player less than 30 min
if (Reports.count_reports(player) > 1) and (total_playtime > math.max(player.online_time * 2, 108000)) then
local player_name_color = format_chat_player_name(player)
Jail.jail_player(player, '<reports>', 'Reported by too many players, please wait for a moderator.')
game.print{'report-jail.jail', player_name_color}
Jail.jail_player(player, "<reports>", "Reported by too many players, please wait for a moderator.")
game.print{ "report-jail.jail", player_name_color }
end
end)

View File

@@ -26,7 +26,7 @@ local function degrade(surface, position)
local tile_name = tile.name
local degrade_tile_name = config.degrade_order[tile_name]
if not degrade_tile_name then return end
surface.set_tiles{{name=degrade_tile_name, position=position}}
surface.set_tiles{ { name = degrade_tile_name, position = position } }
end
-- Same as degrade but will degrade all tiles that are under an entity
@@ -39,25 +39,26 @@ local function degrade_entity(entity)
local lt = box.left_top
local rb = box.right_bottom
for x = lt.x, rb.x do -- x loop
local px = position.x+x
local px = position.x + x
for y = lt.y, rb.y do -- y loop
local p = {x=px, y=position.y+y}
local p = { x = px, y = position.y + y }
local tile = surface.get_tile(p)
local tile_name = tile.name
local degrade_tile_name = config.degrade_order[tile_name]
if not degrade_tile_name then return end
table.insert(tiles, {name=degrade_tile_name, position=p})
table.insert(tiles, { name = degrade_tile_name, position = p })
end
end
surface.set_tiles(tiles)
end
-- Turns the strength of a tile into a probability (0 = impossible, 1 = certain)
local function get_probability(strength)
local v1 = strength/max_strength
local v1 = strength / max_strength
local dif = 1 - v1
local v2 = dif/2
return (1-v1+v2)/config.weakness_value
local v2 = dif / 2
return (1 - v1 + v2) / config.weakness_value
end
-- Gets the mean of the strengths around a tile to give the strength at that position
@@ -69,24 +70,25 @@ local function get_tile_strength(surface, position)
for x = -1, 1 do -- x loop
local px = position.x + x
for y = -1, 1 do -- y loop
local check_tile = surface.get_tile{x=px, y=position.y+y}
local check_tile = surface.get_tile{ x = px, y = position.y + y }
local check_tile_name = check_tile.name
local check_strength = config.strengths[check_tile_name] or 0
strength = strength + check_strength
end
end
return strength/9
return strength / 9
end
-- Same as get_tile_strength but returns to a in game text rather than as a value
local function debug_get_tile_strength(surface, position)
for x = -3, 3 do -- x loop
local px = position.x+x
local px = position.x + x
for y = -3, 3 do -- y loop
local p = {x=px, y=position.y+y}
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)
print_grid_value(get_probability(strength) * config.weakness_value, surface, tile.position)
end
end
end
@@ -113,7 +115,7 @@ Event.add(defines.events.on_built_entity, function(event)
local position = entity.position
local strength = get_tile_strength(surface, position)
if not strength then return end
if get_probability(strength)*config.weakness_value > math.random() then
if get_probability(strength) * config.weakness_value > math.random() then
degrade_entity(entity)
end
end)
@@ -125,7 +127,7 @@ Event.add(defines.events.on_robot_built_entity, function(event)
local position = entity.position
local strength = get_tile_strength(surface, position)
if not strength then return end
if get_probability(strength)*config.weakness_value > math.random() then
if get_probability(strength) * config.weakness_value > math.random() then
degrade_entity(entity)
end
end)
@@ -135,4 +137,4 @@ return function(player_name, state)
local player = game.players[player_name]
clear_flying_text(player.surface)
debug_players[player_name] = state
end
end

View File

@@ -12,7 +12,7 @@ end)
-- Apply an offset to a LuaPosition
local function apply_offset(position, offset)
return {x=position.x + (offset.x or offset[1]), y=position.y + (offset.y or offset[2])}
return { x = position.x + (offset.x or offset[1]), y = position.y + (offset.y or offset[2]) }
end
-- Apply the offset to the turrets default position
@@ -22,16 +22,16 @@ end
-- Get or create the force used for entities in spawn
local function get_spawn_force()
local force = game.forces['spawn']
local force = game.forces["spawn"]
if force and force.valid then
return force
end
force = game.create_force('spawn')
force.set_cease_fire('player', true)
force = game.create_force("spawn")
force.set_cease_fire("player", true)
-- force.set_friend('player', true)
game.forces['player'].set_cease_fire('spawn', true)
game.forces["player"].set_cease_fire("spawn", true)
-- game.forces['player'].set_friend('spawn', true)
return force
@@ -57,18 +57,18 @@ local function spawn_turrets()
for _, turret_pos in pairs(turrets) do
local surface = game.surfaces[turret_pos.surface]
local pos = turret_pos.position
local turret = surface.find_entity('gun-turret', pos)
local turret = surface.find_entity("gun-turret", pos)
-- Makes a new turret if it is not found
if not turret or not turret.valid then
turret = surface.create_entity{name='gun-turret', position=pos, force='spawn'}
turret = surface.create_entity{ name = "gun-turret", position = pos, force = "spawn" }
protect_entity(turret)
end
-- Adds ammo to the turret
local inv = turret.get_inventory(defines.inventory.turret_ammo)
if inv.can_insert{name=config.turrets.ammo_type, count=10} then
inv.insert{name=config.turrets.ammo_type, count=10}
if inv.can_insert{ name = config.turrets.ammo_type, count = 10 } then
inv.insert{ name = config.turrets.ammo_type, count = 10 }
end
end
end
@@ -77,13 +77,13 @@ end
local function spawn_belts(surface, position)
position = apply_offset(position, config.afk_belts.offset)
local belt_type = config.afk_belts.belt_type
local belt_details = {{-0.5, -0.5, 2}, {0.5, -0.5, 4}, {-0.5, 0.5, 0}, {0.5, 0.5, 6}} -- x, y,dir
local belt_details = { { -0.5, -0.5, 2 }, { 0.5, -0.5, 4 }, { -0.5, 0.5, 0 }, { 0.5, 0.5, 6 } } -- x, y,dir
for _, belt_set in pairs(config.afk_belts.locations) do
local set_position = apply_offset(position, belt_set)
for _, belt in pairs(belt_details) do
local pos = apply_offset(set_position, belt)
local belt_entity = surface.create_entity{name=belt_type, position=pos, force='neutral', direction=belt[3]}
local belt_entity = surface.create_entity{ name = belt_type, position = pos, force = "neutral", direction = belt[3] }
if config.afk_belts.protected then
protect_entity(belt_entity)
@@ -99,7 +99,7 @@ local function spawn_pattern(surface, position)
local pattern_tile = config.pattern.pattern_tile
for _, tile in pairs(config.pattern.locations) do
table.insert(tiles_to_make, {name=pattern_tile, position=apply_offset(position, tile)})
table.insert(tiles_to_make, { name = pattern_tile, position = apply_offset(position, tile) })
end
surface.set_tiles(tiles_to_make)
@@ -111,8 +111,9 @@ local function spawn_water(surface, position)
local tiles_to_make = {}
local water_tile = config.water.water_tile
for _, tile in pairs(config.water.locations) do
table.insert(tiles_to_make, {name=water_tile, position=apply_offset(position, tile)})
table.insert(tiles_to_make, { name = water_tile, position = apply_offset(position, tile) })
end
surface.set_tiles(tiles_to_make)
end
@@ -120,8 +121,8 @@ end
local function spawn_entities(surface, position)
position = apply_offset(position, config.entities.offset)
for _, entity in pairs(config.entities.locations) do
local pos = apply_offset(position, {x=entity[2], y=entity[3]})
entity = surface.create_entity{name=entity[1], position=pos, force='neutral'}
local pos = apply_offset(position, { x = entity[2], y = entity[3] })
entity = surface.create_entity{ name = entity[1], position = pos, force = "neutral" }
if config.entities.protected then
protect_entity(entity)
@@ -135,48 +136,49 @@ end
local function spawn_area(surface, position)
local dr = config.spawn_area.deconstruction_radius
local tr = config.spawn_area.tile_radius
local tr2 = tr^2
local tr2 = tr ^ 2
local decon_tile = config.spawn_area.deconstruction_tile
local fr = config.spawn_area.landfill_radius
local fr2 = fr^2
local fr2 = fr ^ 2
local fill_tile = surface.get_tile(position).name
-- Make sure a non water tile is used for each tile
if surface.get_tile(position).collides_with('player') then fill_tile = 'landfill' end
if surface.get_tile(position).collides_with("player") then fill_tile = "landfill" end
if decon_tile == nil then decon_tile = fill_tile end
local tiles_to_make = {}
for x = -fr, fr do -- loop over x
local x2 = (x+0.5)^2
local x2 = (x + 0.5) ^ 2
for y = -fr, fr do -- loop over y
local y2 = (y+0.5)^2
local dst = x2+y2
local pos = {x=position.x+x, y=position.y+y}
local y2 = (y + 0.5) ^ 2
local dst = x2 + y2
local pos = { x = position.x + x, y = position.y + y }
if dst < tr2 then
-- If it is inside the decon radius always set the tile
table.insert(tiles_to_make, {name=decon_tile, position=pos})
elseif dst < fr2 and surface.get_tile(pos).collides_with('player') then
table.insert(tiles_to_make, { name = decon_tile, position = pos })
elseif dst < fr2 and surface.get_tile(pos).collides_with("player") then
-- If it is inside the fill radius only set the tile if it is water
table.insert(tiles_to_make, {name=fill_tile, position=pos})
table.insert(tiles_to_make, { name = fill_tile, position = pos })
end
end
end
-- Remove entities then set the tiles
local entities_to_remove = surface.find_entities_filtered{position=position, radius=dr, name='character', invert=true}
local entities_to_remove = surface.find_entities_filtered{ position = position, radius = dr, name = "character", invert = true }
for _, entity in pairs(entities_to_remove) do
entity.destroy()
end
surface.set_tiles(tiles_to_make)
end
local function spawn_resource_tiles(surface)
for _, v in ipairs(config.resource_tiles.resources) do
if v.enabled then
for x=v.offset[1], v.offset[1] + v.size[1] do
for y=v.offset[2], v.offset[2] + v.size[2] do
surface.create_entity({name=v.name, amount=v.amount, position={x, y}})
for x = v.offset[1], v.offset[1] + v.size[1] do
for y = v.offset[2], v.offset[2] + v.size[2] do
surface.create_entity{ name = v.name, amount = v.amount, position = { x, y } }
end
end
end
@@ -186,8 +188,8 @@ end
local function spawn_resource_patches(surface)
for _, v in ipairs(config.resource_patches.resources) do
if v.enabled then
for i=1, v.num_patches do
surface.create_entity({name=v.name, amount=v.amount, position={v.offset[1] + v.offset_next[1] * (i - 1), v.offset[2] + v.offset_next[2] * (i - 1)}})
for i = 1, v.num_patches do
surface.create_entity{ name = v.name, amount = v.amount, position = { v.offset[1] + v.offset_next[1] * (i - 1), v.offset[2] + v.offset_next[2] * (i - 1) } }
end
end
end
@@ -208,7 +210,7 @@ if config.resource_refill_nearby.enabled then
return
end
for _, ore in pairs(game.players[1].surface.find_entities_filtered{position=game.players[1].force.get_spawn_position(game.players[1].surface), radius=config.resource_refill_nearby.range, name=config.resource_refill_nearby.resources_name}) do
for _, ore in pairs(game.players[1].surface.find_entities_filtered{ position = game.players[1].force.get_spawn_position(game.players[1].surface), radius = config.resource_refill_nearby.range, name = config.resource_refill_nearby.resources_name }) do
ore.amount = ore.amount + math.random(config.resource_refill_nearby.amount[1], config.resource_refill_nearby.amount[2])
end
end)
@@ -218,7 +220,7 @@ end
Event.add(defines.events.on_player_created, function(event)
if event.player_index ~= 1 then return end
local player = game.players[event.player_index]
local p = {x=0, y=0}
local p = { x = 0, y = 0 }
local s = player.surface
get_spawn_force()
spawn_area(s, p)

View File

@@ -1,86 +1,85 @@
---LuaPlayerBuiltEntityEventFilters
---Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}})
--- LuaPlayerBuiltEntityEventFilters
--- Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}})
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local config = require("modules.exp_legacy.config.station_auto_name") --- @dep config.chat_reply
--Credit to Cooldude2606 for using his lua magic to make this function.
-- Credit to Cooldude2606 for using his lua magic to make this function.
local directions = {
['W'] = -0.875,
['NW'] = -0.625,
['N'] = -0.375,
['NE'] = -0.125,
['E'] = 0.125,
['SE'] = 0.375,
['S'] = 0.625,
['SW'] = 0.875
["W"] = -0.875,
["NW"] = -0.625,
["N"] = -0.375,
["NE"] = -0.125,
["E"] = 0.125,
["SE"] = 0.375,
["S"] = 0.625,
["SW"] = 0.875,
}
local function Angle(entity)
local angle = math.atan2(entity.position.y, entity.position.x)/math.pi
local angle = math.atan2(entity.position.y, entity.position.x) / math.pi
for direction, requiredAngle in pairs(directions) do
if angle < requiredAngle then
return direction
end
end
return 'W'
return "W"
end
local custom_string = ' *'
local custom_string = " *"
local custom_string_len = #custom_string
local function station_name_changer(event)
local entity = event.created_entity
local name = entity.name
if name == "entity-ghost" then
if name == "entity-ghost" then
if entity.ghost_name ~= "train-stop" then return end
local backername = entity.backer_name
if backername ~= '' then
entity.backer_name = backername..custom_string
if backername ~= "" then
entity.backer_name = backername .. custom_string
end
elseif name == "train-stop" then --only do the event if its a train stop
elseif name == "train-stop" then -- only do the event if its a train stop
local backername = entity.backer_name
if backername:sub(-custom_string_len) == custom_string then
entity.backer_name = backername:sub(1, -custom_string_len-1)
entity.backer_name = backername:sub(1, -custom_string_len - 1)
return
end
local boundingBox = entity.bounding_box
-- expanded box for recourse search:
local bounding2 = {{boundingBox.left_top.x-100 ,boundingBox.left_top.y-100} , {boundingBox.right_bottom.x+100, boundingBox.right_bottom.y+100 }}
local bounding2 = { { boundingBox.left_top.x - 100, boundingBox.left_top.y - 100 }, { boundingBox.right_bottom.x + 100, boundingBox.right_bottom.y + 100 } }
-- gets all resources in bounding_box2:
local recourses = game.surfaces[1].find_entities_filtered{area = bounding2, type = "resource"}
local recourses = game.surfaces[1].find_entities_filtered{ area = bounding2, type = "resource" }
if #recourses > 0 then -- save cpu time if their are no recourses in bounding_box2
local closest_distance
local px, py = boundingBox.left_top.x, boundingBox.left_top.y
local recourse_closed
--Check which recourse is closest
-- Check which recourse is closest
for i, item in ipairs(recourses) do
local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y
local distance = (dx*dx)+(dy*dy)
if not closest_distance or distance < closest_distance then
local distance = (dx * dx) + (dy * dy)
if not closest_distance or distance < closest_distance then
recourse_closed = item
closest_distance = distance
end
end
local item_name = recourse_closed.name
if item_name then -- prevent errors if something went wrong
local item_name2 = item_name:gsub("^%l", string.upper):gsub('-', ' ') -- removing the - and making first letter capital
local item_name2 = item_name:gsub("^%l", string.upper):gsub("-", " ") -- removing the - and making first letter capital
local item_type = 'item'
if item_name == 'crude-oil' then
item_type = 'fluid'
local item_type = "item"
if item_name == "crude-oil" then
item_type = "fluid"
end
entity.backer_name = config.station_name:gsub('__icon__', '[img=' .. item_type .. '.' .. item_name .. ']')
:gsub('__item_name__', item_name2)
:gsub('__backer_name__', entity.backer_name)
:gsub('__direction__', Angle(entity))
:gsub('__x__', math.floor(entity.position.x))
:gsub('__y__', math.floor(entity.position.y))
entity.backer_name = config.station_name:gsub("__icon__", "[img=" .. item_type .. "." .. item_name .. "]")
:gsub("__item_name__", item_name2)
:gsub("__backer_name__", entity.backer_name)
:gsub("__direction__", Angle(entity))
:gsub("__x__", math.floor(entity.position.x))
:gsub("__y__", math.floor(entity.position.y))
end
end
end

View File

@@ -9,8 +9,8 @@ local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep ex
-- Storage queue used to store trees that need to be removed, also cache for player roles
local cache = {}
local tree_queue = { _head=0 }
Storage.register({tree_queue, cache}, function(tbl)
local tree_queue = { _head = 0 }
Storage.register({ tree_queue, cache }, function(tbl)
tree_queue = tbl[1]
cache = tbl[2]
end)
@@ -18,26 +18,29 @@ end)
local function get_permission(player_index)
if cache[player_index] == nil then
local player = game.players[player_index]
if Roles.player_allowed(player, 'fast-tree-decon') then cache[player_index] = 'fast'
elseif Roles.player_allowed(player, 'standard-decon') then cache[player_index] = 'standard'
else cache[player_index] = player.force end
if Roles.player_allowed(player, "fast-tree-decon") then
cache[player_index] = "fast"
elseif Roles.player_allowed(player, "standard-decon") then
cache[player_index] = "standard"
else
cache[player_index] = player.force
end
end
return cache[player_index]
end
-- Left menu button to toggle between fast decon and normal decon marking
local HasEnabledDecon = PlayerData.Settings:combine('HasEnabledDecon')
local HasEnabledDecon = PlayerData.Settings:combine("HasEnabledDecon")
HasEnabledDecon:set_default(false)
Gui.toolbar_toggle_button("entity/tree-01", {'tree-decon.main-tooltip'}, function (player)
return Roles.player_allowed(player, "fast-tree-decon")
Gui.toolbar_toggle_button("entity/tree-01", { "tree-decon.main-tooltip" }, function(player)
return Roles.player_allowed(player, "fast-tree-decon")
end)
:on_event(Gui.events.on_toolbar_button_toggled, function(player, _, event)
HasEnabledDecon:set(player, event.state)
player.print{'tree-decon.toggle-msg', event.state and {'tree-decon.enabled'} or {'tree-decon.disabled'}}
end)
:on_event(Gui.events.on_toolbar_button_toggled, function(player, _, event)
HasEnabledDecon:set(player, event.state)
player.print{ "tree-decon.toggle-msg", event.state and { "tree-decon.enabled" } or { "tree-decon.disabled" } }
end)
-- Add trees to queue when marked, only allows simple entities and for players with role permission
Event.add(defines.events.on_marked_for_deconstruction, function(event)
@@ -52,24 +55,23 @@ Event.add(defines.events.on_marked_for_deconstruction, function(event)
-- Not allowed to decon this entity
local last_user = entity.last_user
local allow = get_permission(index)
if last_user and allow ~= 'standard' and allow ~= 'fast' then
if last_user and allow ~= "standard" and allow ~= "fast" then
entity.cancel_deconstruction(allow)
return
end
-- Allowed to decon this entity, but not fast
if allow ~= 'fast' then return end
if allow ~= "fast" then return end
local player = game.get_player(index)
if not HasEnabledDecon:get(player) then return end
-- Allowed fast decon on this entity, just trees
local head = tree_queue._head + 1
if not last_user and entity.type ~= 'cliff' then
if not last_user and entity.type ~= "cliff" then
tree_queue[head] = entity
tree_queue._head = head
end
end)
-- Remove trees at random till the queue is empty
@@ -77,7 +79,7 @@ Event.add(defines.events.on_tick, function()
local head = tree_queue._head
if head == 0 then return end
local max_remove = math.floor(head/100)+1
local max_remove = math.floor(head / 100) + 1
local remove_count = math.random(0, max_remove)
while remove_count > 0 and head > 0 do
local remove_index = math.random(1, head)
@@ -89,6 +91,7 @@ Event.add(defines.events.on_tick, function()
entity.destroy()
end
end
tree_queue._head = head
end)
@@ -101,24 +104,24 @@ end)
-- Clear trees when hit with a car
Event.add(defines.events.on_entity_damaged, function(event)
if not (event.damage_type.name == 'impact' and event.force) then
return
end
if not (event.damage_type.name == "impact" and event.force) then
return
end
if not (event.entity.type == 'tree' or event.entity.type == 'simple-entity') then
return
end
if not (event.entity.type == "tree" or event.entity.type == "simple-entity") then
return
end
if (not event.cause) or (event.cause.type ~= 'car')then
return
end
if (not event.cause) or (event.cause.type ~= "car") then
return
end
local driver = event.cause.get_driver()
if not driver then return end
local allow = get_permission(driver.player.index)
if allow == "fast" and HasEnabledDecon:get(driver.player) then
event.entity.destroy()
event.entity.destroy()
else
event.entity.order_deconstruction(event.force, driver.player)
end

View File

@@ -10,17 +10,18 @@ require("modules.exp_legacy.config.expcore.command_general_parse")
--- Sends a message in chat that only admins can see
-- @command admin-chat
-- @tparam string message the message to send in the admin chat
Commands.new_command('admin-chat', {'expcom-admin-chat.description'}, 'Sends a message in chat that only admins can see.')
:add_param('message', false)
:enable_auto_concat()
:set_flag('admin_only')
:add_alias('ac')
:register(function(player, message)
local player_name_colour = format_chat_player_name(player)
for _, return_player in pairs(game.connected_players) do
if return_player.admin then
return_player.print{'expcom-admin-chat.format', player_name_colour, message}
Commands.new_command("admin-chat", { "expcom-admin-chat.description" }, "Sends a message in chat that only admins can see.")
:add_param("message", false)
:enable_auto_concat()
:set_flag("admin_only")
:add_alias("ac")
:register(function(player, message)
local player_name_colour = format_chat_player_name(player)
for _, return_player in pairs(game.connected_players) do
if return_player.admin then
return_player.print{ "expcom-admin-chat.format", player_name_colour, message }
end
end
end
return Commands.success -- prevents command complete message from showing
end)
return Commands.success -- prevents command complete message from showing
end)

View File

@@ -13,7 +13,7 @@ local markers = {} -- Stores all admin markers
--- Storage variables
Storage.register({
admins = admins,
markers = markers
markers = markers,
}, function(tbl)
admins = tbl.admins
markers = tbl.markers
@@ -21,20 +21,20 @@ end)
--- Toggle admin marker mode, can only be applied to yourself
-- @command admin-marker
Commands.new_command('admin-marker', {'expcom-admin-marker.description'}, 'Toggles admin marker mode, new markers can only be edited by admins')
:set_flag('admin_only')
:add_alias('am', 'admin-markers')
:register(function(player)
if admins[player.name] then
-- Exit admin mode
admins[player.name] = nil
return Commands.success{'expcom-admin-marker.exit'}
else
-- Enter admin mode
admins[player.name] = true
return Commands.success{'expcom-admin-marker.enter'}
end
end)
Commands.new_command("admin-marker", { "expcom-admin-marker.description" }, "Toggles admin marker mode, new markers can only be edited by admins")
:set_flag("admin_only")
:add_alias("am", "admin-markers")
:register(function(player)
if admins[player.name] then
-- Exit admin mode
admins[player.name] = nil
return Commands.success{ "expcom-admin-marker.exit" }
else
-- Enter admin mode
admins[player.name] = true
return Commands.success{ "expcom-admin-marker.enter" }
end
end)
--- Listen for new map markers being added, add admin marker if done by player in admin mode
Event.add(defines.events.on_chart_tag_added, function(event)
@@ -42,8 +42,8 @@ Event.add(defines.events.on_chart_tag_added, function(event)
local player = game.get_player(event.player_index)
if not admins[player.name] then return end
local tag = event.tag
markers[tag.force.name..tag.tag_number] = true
Commands.print({'expcom-admin-marker.place'}, nil, player)
markers[tag.force.name .. tag.tag_number] = true
Commands.print({ "expcom-admin-marker.place" }, nil, player)
end)
--- Listen for players leaving the game, leave admin mode to avoid unexpected admin markers
@@ -57,30 +57,30 @@ end)
local function maintain_tag(event)
local tag = event.tag
if not event.player_index then return end
if not markers[tag.force.name..tag.tag_number] then return end
if not markers[tag.force.name .. tag.tag_number] then return end
local player = game.get_player(event.player_index)
if player.admin then
-- Player is admin, tell them it was an admin marker
Commands.print({'expcom-admin-marker.edit'}, nil, player)
Commands.print({ "expcom-admin-marker.edit" }, nil, player)
elseif event.name == defines.events.on_chart_tag_modified then
-- Tag was modified, revert the changes
tag.text = event.old_text
tag.last_user = event.old_player
if event.old_icon then tag.icon = event.old_icon end
player.play_sound{path='utility/wire_pickup'}
Commands.print({'expcom-admin-marker.revert'}, nil, player)
player.play_sound{ path = "utility/wire_pickup" }
Commands.print({ "expcom-admin-marker.revert" }, nil, player)
else
-- Tag was removed, remake the tag
player.play_sound{path='utility/wire_pickup'}
Commands.print({'expcom-admin-marker.revert'}, 'orange_red', player)
player.play_sound{ path = "utility/wire_pickup" }
Commands.print({ "expcom-admin-marker.revert" }, "orange_red", player)
local new_tag = tag.force.add_chart_tag(tag.surface, {
last_user = tag.last_user,
position = tag.position,
icon = tag.icon,
text = tag.text,
})
markers[tag.force.name..tag.tag_number] = nil
markers[new_tag.force.name..new_tag.tag_number] = true
markers[tag.force.name .. tag.tag_number] = nil
markers[new_tag.force.name .. new_tag.tag_number] = true
end
end

View File

@@ -6,21 +6,17 @@
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
require("modules.exp_legacy.config.expcore.command_general_parse")
local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection
local SelectionArtyArea = 'ArtyArea'
local SelectionArtyArea = "ArtyArea"
local function location_break(player, pos)
if player.force.is_chunk_charted(player.surface, {x=math.floor(pos.left_top.x / 32), y=math.floor(pos.left_top.y / 32)}) then
if player.force.is_chunk_charted(player.surface, { x = math.floor(pos.left_top.x / 32), y = math.floor(pos.left_top.y / 32) }) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.left_top.x / 32), y=math.floor(pos.right_bottom.y / 32)}) then
elseif player.force.is_chunk_charted(player.surface, { x = math.floor(pos.left_top.x / 32), y = math.floor(pos.right_bottom.y / 32) }) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.right_bottom.x / 32), y=math.floor(pos.left_top.y / 32)}) then
elseif player.force.is_chunk_charted(player.surface, { x = math.floor(pos.right_bottom.x / 32), y = math.floor(pos.left_top.y / 32) }) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.right_bottom.x / 32), y=math.floor(pos.right_bottom.y / 32)}) then
elseif player.force.is_chunk_charted(player.surface, { x = math.floor(pos.right_bottom.x / 32), y = math.floor(pos.right_bottom.y / 32) }) then
return true
else
return false
end
@@ -29,8 +25,8 @@ end
--- align an aabb to the grid by expanding it
local function aabb_align_expand(aabb)
return {
left_top = {x = math.floor(aabb.left_top.x), y = math.floor(aabb.left_top.y)},
right_bottom = {x = math.ceil(aabb.right_bottom.x), y = math.ceil(aabb.right_bottom.y)}
left_top = { x = math.floor(aabb.left_top.x), y = math.floor(aabb.left_top.y) },
right_bottom = { x = math.ceil(aabb.right_bottom.x), y = math.ceil(aabb.right_bottom.y) },
}
end
@@ -50,7 +46,7 @@ Selection.on_selection(SelectionArtyArea, function(event)
local count = 0
local hit = {}
for _, e in pairs(player.surface.find_entities_filtered({area=area, type={'unit-spawner', 'turret'}, force='enemy'})) do
for _, e in pairs(player.surface.find_entities_filtered{ area = area, type = { "unit-spawner", "turret" }, force = "enemy" }) do
local skip = false
for _, pos in ipairs(hit) do
@@ -61,7 +57,7 @@ Selection.on_selection(SelectionArtyArea, function(event)
end
if not skip then
player.surface.create_entity{name='artillery-flare', position=e.position, force=player.force, life_time=240, movement={0, 0}, height=0, vertical_speed=0, frame_speed=0}
player.surface.create_entity{ name = "artillery-flare", position = e.position, force = player.force, life_time = 240, movement = { 0, 0 }, height = 0, vertical_speed = 0, frame_speed = 0 }
table.insert(hit, e.position)
count = count + 1
@@ -72,13 +68,13 @@ Selection.on_selection(SelectionArtyArea, function(event)
end
end)
Commands.new_command('artillery-target-remote', {'expcom-artillery.description'}, 'Artillery Target Remote')
:register(function(player)
if Selection.is_selecting(player, SelectionArtyArea) then
Selection.stop(player)
else
Selection.start(player, SelectionArtyArea)
end
Commands.new_command("artillery-target-remote", { "expcom-artillery.description" }, "Artillery Target Remote")
:register(function(player)
if Selection.is_selecting(player, SelectionArtyArea) then
Selection.stop(player)
else
Selection.start(player, SelectionArtyArea)
end
return Commands.success
end)
return Commands.success
end)

View File

@@ -6,20 +6,20 @@
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
require("modules.exp_legacy.config.expcore.command_general_parse")
Commands.new_command('bot-queue-get', {'expcom-bot-queue.description-get'}, 'Get bot queue')
:set_flag('admin_only')
:register(function(player)
local s = player.force.max_successful_attempts_per_tick_per_construction_queue
local f = player.force.max_failed_attempts_per_tick_per_construction_queue
return Commands.success{'expcom-bot-queue.result', player.name, s, f}
end)
Commands.new_command("bot-queue-get", { "expcom-bot-queue.description-get" }, "Get bot queue")
:set_flag("admin_only")
:register(function(player)
local s = player.force.max_successful_attempts_per_tick_per_construction_queue
local f = player.force.max_failed_attempts_per_tick_per_construction_queue
return Commands.success{ "expcom-bot-queue.result", player.name, s, f }
end)
Commands.new_command('bot-queue-set', {'expcom-bot-queue.description-set'}, 'Set bot queue')
:add_param('amount', 'integer-range', 1, 20)
:set_flag('admin_only')
:register(function(player, amount)
player.force.max_successful_attempts_per_tick_per_construction_queue = 3 * amount
player.force.max_failed_attempts_per_tick_per_construction_queue = 1 * amount
game.print{'expcom-bot-queue.result', player.name, 3 * amount, 1 * amount}
return Commands.success
end)
Commands.new_command("bot-queue-set", { "expcom-bot-queue.description-set" }, "Set bot queue")
:add_param("amount", "integer-range", 1, 20)
:set_flag("admin_only")
:register(function(player, amount)
player.force.max_successful_attempts_per_tick_per_construction_queue = 3 * amount
player.force.max_failed_attempts_per_tick_per_construction_queue = 1 * amount
game.print{ "expcom-bot-queue.result", player.name, 3 * amount, 1 * amount }
return Commands.success
end)

View File

@@ -9,37 +9,37 @@ require("modules.exp_legacy.config.expcore.command_general_parse")
--- Toggles cheat mode for your player, or another player.
-- @command toggle-cheat-mode
-- @tparam[opt=self] LuaPlayer player player to toggle chest mode of, can be nil for self
Commands.new_command('toggle-cheat-mode', {'expcom-cheat.description-cheat'}, 'Toggles cheat mode for your player, or another player.')
:add_param('player', true, 'player')
:set_defaults{player=function(player)
return player -- default is the user using the command
end}
:set_flag('admin_only')
:register(function(_, player)
player.cheat_mode = not player.cheat_mode
return Commands.success
end)
Commands.new_command("toggle-cheat-mode", { "expcom-cheat.description-cheat" }, "Toggles cheat mode for your player, or another player.")
:add_param("player", true, "player")
:set_defaults{ player = function(player)
return player -- default is the user using the command
end }
:set_flag("admin_only")
:register(function(_, player)
player.cheat_mode = not player.cheat_mode
return Commands.success
end)
Commands.new_command('research-all', {'expcom-cheat.description-res'}, 'Set all research for your force.')
:set_flag('admin_only')
:add_param('force', true, 'force')
:set_defaults{force=function(player)
return player.force
end}
:register(function(player, force)
force.research_all_technologies()
game.print{'expcom-cheat.res', player.name}
return Commands.success
end)
Commands.new_command("research-all", { "expcom-cheat.description-res" }, "Set all research for your force.")
:set_flag("admin_only")
:add_param("force", true, "force")
:set_defaults{ force = function(player)
return player.force
end }
:register(function(player, force)
force.research_all_technologies()
game.print{ "expcom-cheat.res", player.name }
return Commands.success
end)
Commands.new_command('toggle-always-day', {'expcom-cheat.description-day'}, 'Toggles always day in surface.')
:set_flag('admin_only')
:add_param('surface', true, 'surface')
:set_defaults{surface=function(player)
return player.surface
end}
:register(function(player, surface)
surface.always_day = not surface.always_day
game.print{'expcom-cheat.day', player.name, surface.always_day}
return Commands.success
end)
Commands.new_command("toggle-always-day", { "expcom-cheat.description-day" }, "Toggles always day in surface.")
:set_flag("admin_only")
:add_param("surface", true, "surface")
:set_defaults{ surface = function(player)
return player.surface
end }
:register(function(player, surface)
surface.always_day = not surface.always_day
game.print{ "expcom-cheat.day", player.name, surface.always_day }
return Commands.success
end)

View File

@@ -10,14 +10,14 @@ require("modules.exp_legacy.config.expcore.command_role_parse")
--- Clears a players inventory
-- @command clear-inventory
-- @tparam LuaPlayer player the player to clear the inventory of
Commands.new_command('clear-inventory', {'expcom-clr-inv.description'}, 'Clears a players inventory')
:add_param('player', false, 'player-role')
:add_alias('clear-inv', 'move-inventory', 'move-inv')
:register(function(_, player)
local inv = player.get_main_inventory()
if not inv then
return Commands.error{'expcore-commands.reject-player-alive'}
end
move_items_stack(inv)
inv.clear()
end)
Commands.new_command("clear-inventory", { "expcom-clr-inv.description" }, "Clears a players inventory")
:add_param("player", false, "player-role")
:add_alias("clear-inv", "move-inventory", "move-inv")
:register(function(_, player)
local inv = player.get_main_inventory()
if not inv then
return Commands.error{ "expcore-commands.reject-player-alive" }
end
move_items_stack(inv)
inv.clear()
end)

View File

@@ -30,20 +30,20 @@ local function get_server_id(server)
end
if server_count > 1 then
return false, Commands.error{'expcom-connect.too-many-matching', concat(server_names, ', ')}
return false, Commands.error{ "expcom-connect.too-many-matching", concat(server_names, ", ") }
elseif server_count == 1 then
local server_id, server_details = next(servers)
local status = External.get_server_status(server_id)
if server_id == current_server.id then
return false, Commands.error{'expcom-connect.same-server', server_details.name}
elseif status == 'Offline' then
return false, Commands.error{'expcom-connect.offline', server_details.name}
return false, Commands.error{ "expcom-connect.same-server", server_details.name }
elseif status == "Offline" then
return false, Commands.error{ "expcom-connect.offline", server_details.name }
end
return true, server_id
elseif server_count_before > 0 then
return false, Commands.error{'expcom-connect.wrong-version', concat(server_names_before, ', ')}
return false, Commands.error{ "expcom-connect.wrong-version", concat(server_names_before, ", ") }
else
return false, Commands.error{'expcom-connect.none-matching'}
return false, Commands.error{ "expcom-connect.none-matching" }
end
end
@@ -51,57 +51,57 @@ end
-- @command connect
-- @tparam string server The address or name of the server to connect to
-- @tparam[opt=false] boolean is_address If an address was given for the server param
Commands.new_command('connect', {'expcom-connect.description'}, 'Connect to another server')
:add_param('server')
:add_param('is_address', true, 'boolean')
:add_alias('join', 'server')
:register(function(player, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
Commands.new_command("connect", { "expcom-connect.description" }, "Connect to another server")
:add_param("server")
:add_param("is_address", true, "boolean")
:add_alias("join", "server")
:register(function(player, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
Async(request_connection, player, server_id, true)
end)
Async(request_connection, player, server_id, true)
end)
--- Connect a player to a different server
-- @command connect-player
-- @tparam string address The address or name of the server to connect to
-- @tparam LuaPlayer player The player to connect to a different server
-- @tparam[opt=false] boolean is_address If an address was given for the server param
Commands.new_command('connect-player', {'expcom-connect.description-player'}, 'Send a player to a different server')
:add_param('player', 'player-role')
:add_param('server')
:add_param('is_address', true, 'boolean')
:register(function(_, player, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
Commands.new_command("connect-player", { "expcom-connect.description-player" }, "Send a player to a different server")
:add_param("player", "player-role")
:add_param("server")
:add_param("is_address", true, "boolean")
:register(function(_, player, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
External.request_connection(player, server_id)
end)
External.request_connection(player, server_id)
end)
--- Connect all players to a different server
-- @command connect-all
-- @tparam string address The address or name of the server to connect to
-- @tparam[opt=false] boolean is_address If an address was given for the server param
Commands.new_command('connect-all', {'expcom-connect.description-all'}, 'Connect all players to another server')
:add_param('server')
:add_param('is_address', true, 'boolean')
:register(function(_, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
Commands.new_command("connect-all", { "expcom-connect.description-all" }, "Connect all players to another server")
:add_param("server")
:add_param("is_address", true, "boolean")
:register(function(_, server, is_address)
local server_id = server
if not is_address and External.valid() then
local success, new_server_id = get_server_id(server)
if not success then return new_server_id end
server_id = new_server_id
end
for _, player in pairs(game.connected_players) do
External.request_connection(player, server_id)
end
end)
for _, player in pairs(game.connected_players) do
External.request_connection(player, server_id)
end
end)

View File

@@ -8,7 +8,7 @@ local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore
--- Opens the debug pannel for viewing tables.
-- @command debug
Commands.new_command('debug', {'expcom-debug.description'}, 'Opens the debug pannel for viewing tables.')
:register(function(player)
DebugView.open_dubug(player)
end)
Commands.new_command("debug", { "expcom-debug.description" }, "Opens the debug pannel for viewing tables.")
:register(function(player)
DebugView.open_dubug(player)
end)

Some files were not shown because too many files have changed in this diff Show More