mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Migrate all commands to new lib
This commit is contained in:
@@ -8,44 +8,6 @@ return {
|
|||||||
"modules.factorio-control", -- base factorio free play scenario
|
"modules.factorio-control", -- base factorio free play scenario
|
||||||
"expcore.player_data", -- must be loaded first to register event handlers
|
"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",
|
|
||||||
|
|
||||||
--- Addons
|
--- Addons
|
||||||
"modules.addons.chat-popups",
|
"modules.addons.chat-popups",
|
||||||
"modules.addons.damage-popups",
|
"modules.addons.damage-popups",
|
||||||
@@ -104,9 +66,6 @@ return {
|
|||||||
"modules.gui.toolbar", -- must be loaded last to register toolbar handlers
|
"modules.gui.toolbar", -- must be loaded last to register toolbar handlers
|
||||||
|
|
||||||
--- Config Files
|
--- 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.permission_groups", -- loads some predefined permission groups
|
||||||
"config.expcore.roles", -- loads some predefined roles
|
"config.expcore.roles", -- loads some predefined roles
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ return {
|
|||||||
local options = { "?", ".", "!", "!!!" }
|
local options = { "?", ".", "!", "!!!" }
|
||||||
return { "chat-bot.hodor", table.get_random(options) }
|
return { "chat-bot.hodor", table.get_random(options) }
|
||||||
end,
|
end,
|
||||||
["evolution"] = function(_player, _is_command)
|
["evolution"] = function(player, _is_command)
|
||||||
return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].evolution_factor) }
|
return { "chat-bot.current-evolution", string.format("%.2f", game.forces["enemy"].get_evolution_factor(player.surface)) }
|
||||||
end,
|
end,
|
||||||
["makepopcorn"] = function(player, _is_command)
|
["makepopcorn"] = function(player, _is_command)
|
||||||
local timeout = math.floor(180 * (math.random() + 0.5))
|
local timeout = math.floor(180 * (math.random() + 0.5))
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
--- This is a very simple config file which adds a admin only auth function;
|
|
||||||
-- not much to change here its more so it can be enabled and disabled from ./config/file_loader.lua;
|
|
||||||
-- either way you can change the requirements to be "admin" if you wanted to
|
|
||||||
-- @config Commands-Auth-Admin
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
|
|
||||||
-- luacheck:ignore 212/command
|
|
||||||
Commands.add_authenticator(function(player, command, tags, reject)
|
|
||||||
if tags.admin_only then
|
|
||||||
if player.admin then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return reject{ "command-auth.admin-only" }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
--- This will make commands only work if the role has been allowed it in the role config
|
|
||||||
-- @config Commands-Auth-Roles
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
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
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return reject()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
--- This will make commands only work when a valid color from the presets has been selected
|
|
||||||
-- @config Commands-Color-Parse
|
|
||||||
|
|
||||||
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)
|
|
||||||
if not input then return end
|
|
||||||
local color = Colours[input]
|
|
||||||
if not color then
|
|
||||||
return reject{ "expcore-commands.reject-color" }
|
|
||||||
else
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
--[[-- This file contains some common command param parse functions;
|
|
||||||
this file is less of a config and more of a requirement but you may wish to change how some behave;
|
|
||||||
as such you need to be confident with lua but you edit this config file;
|
|
||||||
use Commands.add_parse('name',function(input, player, reject) end) to add a parse;
|
|
||||||
see ./expcore/commands.lua for more details
|
|
||||||
@config Commands-Parse
|
|
||||||
@usage Adds Parses:
|
|
||||||
boolean
|
|
||||||
string-options - options: array
|
|
||||||
string-max-length - max_length: number
|
|
||||||
number
|
|
||||||
integer
|
|
||||||
number-range - range_min: number, range_max: number
|
|
||||||
integer-range - range_min: number, range_max: number
|
|
||||||
player
|
|
||||||
player-online
|
|
||||||
player-alive
|
|
||||||
force
|
|
||||||
surface
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
|
|
||||||
-- luacheck:ignore 212/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
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
Commands.add_parse("string-options", function(input, player, reject, options)
|
|
||||||
if not input then return end -- nil check
|
|
||||||
local option = ExpUtil.auto_complete(options, input)
|
|
||||||
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)
|
|
||||||
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 }
|
|
||||||
else
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return number
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
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)
|
|
||||||
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 }
|
|
||||||
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)
|
|
||||||
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 }
|
|
||||||
else
|
|
||||||
return number
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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 }
|
|
||||||
else
|
|
||||||
return input_player
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
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)
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return input_player
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return force
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return surface
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
--[[-- Adds some parse functions that can be used with the role system
|
|
||||||
@config Commands-Parse-Roles
|
|
||||||
@usage Adds Parses:
|
|
||||||
role
|
|
||||||
player-role
|
|
||||||
player-role-online
|
|
||||||
player-role-alive
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
||||||
local auto_complete = ExpUtil.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)
|
|
||||||
if not input then return end
|
|
||||||
local roles = Roles.config.order
|
|
||||||
local rev_roles = {}
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return role
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
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)
|
|
||||||
end)
|
|
||||||
|
|
||||||
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)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
--- This config for command auth allows commands to be globally enabled and disabled during runtime;
|
|
||||||
-- this config adds Commands.disable and Commands.enable to enable and disable commands for all users
|
|
||||||
-- @config Commands-Auth-Runtime-Disable
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
|
|
||||||
local disabled_commands = {}
|
|
||||||
Storage.register(disabled_commands, function(tbl)
|
|
||||||
disabled_commands = tbl
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Stops a command from be used by any one
|
|
||||||
-- @tparam string command_name the name of the command to disable
|
|
||||||
function Commands.disable(command_name)
|
|
||||||
disabled_commands[command_name] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Allows a command to be used again after disable was used
|
|
||||||
-- @tparam string command_name the name of the command to enable
|
|
||||||
function Commands.enable(command_name)
|
|
||||||
disabled_commands[command_name] = nil
|
|
||||||
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" }
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,895 +0,0 @@
|
|||||||
--[[-- Core Module - Commands
|
|
||||||
- Factorio command making module that makes commands with better parse and more modularity
|
|
||||||
@core Commands
|
|
||||||
@alias Commands
|
|
||||||
|
|
||||||
@usage--- Full code example, see below for explanation
|
|
||||||
Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.')
|
|
||||||
:add_param('repeat-count', 'number-range-int', 1, 5) -- required int in range 1 to 5 inclusive
|
|
||||||
:add_param('smiley', true, function(input, player, reject) -- optional boolean default false
|
|
||||||
if not input then return end
|
|
||||||
input = input:lower()
|
|
||||||
if input == 'true' or input == 'yes' then return true end
|
|
||||||
return false
|
|
||||||
end)
|
|
||||||
:set_defaults{ smiley = false }
|
|
||||||
:set_flag('admin_only') -- command is admin only
|
|
||||||
:add_alias('name', 'rname') -- allow alias: name and rname
|
|
||||||
:register(function(player, repeat_count, smiley, raw)
|
|
||||||
game.print(player.name..' used a command with input: '..raw)
|
|
||||||
|
|
||||||
local msg = ') '..player.name
|
|
||||||
if smiley then
|
|
||||||
msg = ':'..msg
|
|
||||||
end
|
|
||||||
|
|
||||||
for 1 = 1, repeat_count do
|
|
||||||
Command.print(1..msg)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
@usage--- Example Command Explanation:
|
|
||||||
-- Making commands basics, the commands can be set up with any number of params and flags that you want,
|
|
||||||
-- you can add aliases for the commands and set default values for optional params and of course register your command callback.
|
|
||||||
-- In our example we will have a command that will repeat the users name in chat X amount of times and only allow admins to use it.
|
|
||||||
|
|
||||||
-- First we create the new command, note this will not register the command to the game this is done at the end.
|
|
||||||
-- We will call the command "repeat-name" and set the help message as follows:
|
|
||||||
Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.')
|
|
||||||
|
|
||||||
-- Now for our first param, we have named it "repeat-count" and it will be a required value, between 1 and 5 inclusive:
|
|
||||||
-- By using "number-range-int" we are saying to use this parser to convert our input text, common ones exist in config.expcore.command_general_parse
|
|
||||||
:add_param('repeat-count', 'number-range-int', 1, 5)
|
|
||||||
|
|
||||||
-- Our second param needs a custom parser, meaning it isnt defined with add_parser, this is an option for when it is unlikely for
|
|
||||||
-- any other command to use the same input type. In the example it is a boolean type and we are just showing it here as part of the example.
|
|
||||||
-- As for the param its self it will be called "smiley" and will be optional with a default value of false:
|
|
||||||
:add_param('smiley', true, function(input, player, reject)
|
|
||||||
-- Since it is optional the input can be nil, in which case we just return
|
|
||||||
if not input then return end
|
|
||||||
-- If it is not nil then we check for a truthy value
|
|
||||||
if input == 'true' or input == 'yes' then return true end
|
|
||||||
-- Note that because we did not return nil or reject then false will be passed to command callback, see example parse
|
|
||||||
return false
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Once all params are defined you can add some default values for your optional params, the default value will be used only
|
|
||||||
-- when no value is given as input, if an invalid value is given then the command will fail and the default will not be used, the
|
|
||||||
-- default can also be a function which is passed the player as an argument and should return a value to be the default.
|
|
||||||
-- Here we set the default for "smiley" to false:
|
|
||||||
:set_defaults{smiley=false}
|
|
||||||
|
|
||||||
-- Another example of defaults if we have: item, amount[opt], player[opt]
|
|
||||||
:set_defaults{
|
|
||||||
amount = 50, -- More than one value can be set at a time
|
|
||||||
player = function(player) return player end -- Default is the player using the command
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Now the params are set up we can alter how the command works, we can set auth flags, add aliases, or enable "auto concat":
|
|
||||||
:set_flag('admin_only') -- In our case we want "admin_only" to be set to true so only admins can use the command
|
|
||||||
:add_alias('name', 'rname') -- We also add two aliases here: "name" and "rname" which point to this command
|
|
||||||
-- :enable_auto_concat() -- We do not use this in our case but this can also be used to enable the "auto concat" feature
|
|
||||||
|
|
||||||
-- And finally we want to register a callback to this command, the callback is what defines what the command does, can be as complex as you
|
|
||||||
-- want it to be, or as simple as our example; the command receives two params plus all param you have defined:
|
|
||||||
-- 1) the player who used the command
|
|
||||||
-- 2) in our case repeat_count which will be a number
|
|
||||||
-- 3) in our case smiley which will be a boolean
|
|
||||||
-- 4) the raw input; this param is always last as is always present as a catch all
|
|
||||||
:register(function(player, repeat_count, smiley, raw)
|
|
||||||
-- This is to show the value for raw as this is an example command, the log file will also show this
|
|
||||||
game.print(player.name..' used a command with input: '..raw)
|
|
||||||
local msg = ') '..player.name
|
|
||||||
|
|
||||||
if smiley then
|
|
||||||
msg = ':'..msg
|
|
||||||
end
|
|
||||||
|
|
||||||
for 1 = 1, repeat_count do
|
|
||||||
-- this print function will return ANY value to the user in a desync safe manor, this includes if the command was used through rcon
|
|
||||||
Command.print(1..msg)
|
|
||||||
end
|
|
||||||
-- See below for what can be used here
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Values that can be returned from register callback
|
|
||||||
Commands.print(any, colour[opt]) -- This will return any value value to the user including if it is ran through rcon console
|
|
||||||
Commands.error(message[opt]) -- This returns a warning to the user, aka an error that does not prevent execution of the command
|
|
||||||
return Commands.error(message[opt]) -- This returns an error to the user, and will halt the command execution, ie no success message is returned
|
|
||||||
Commands.success(message[opt]) -- Used to return a success message however don't use this method, see below
|
|
||||||
return Commands.success(message[opt]) -- Will return the success message to the user and your given message, halts execution
|
|
||||||
return <any> -- If any value is returned then it will be returned to the player via a Commands.success call
|
|
||||||
|
|
||||||
@usage--- Example Authenticator:
|
|
||||||
-- The command system is best used when you can control who uses commands;
|
|
||||||
-- to do this you need to define an authenticator which is ran every time a command is run;
|
|
||||||
-- in this example I will show a simple one that requires certain commands to require the user to be a game admin.
|
|
||||||
|
|
||||||
-- For our admin only example we will set a flag to true when we want it to be admin only;
|
|
||||||
-- when we define the command will will use :set_flag('admin_only');
|
|
||||||
-- then inside the authenticator we will test if the flag is present using: if flags.admin_only then
|
|
||||||
|
|
||||||
-- When the authenticator is called by the command handler it will be passed 4 arguments:
|
|
||||||
-- 1) player - the player who used the command
|
|
||||||
-- 2) command - the name of the command that is being used
|
|
||||||
-- 3) flags - the flags which have been set for this command, flags are set with :set_flag(name, value)
|
|
||||||
-- 4) reject - the reject function which is the preferred method to prevent execution of the command
|
|
||||||
|
|
||||||
-- No return is required to allow the command to execute but it is best practice to return true;
|
|
||||||
-- we do this in two cases in our authenticator:
|
|
||||||
-- 1) when the "admin_only" flag is not set, which we take assume that any one can use it
|
|
||||||
-- 2) when the "admin_only" flag is set, and the player is admin
|
|
||||||
|
|
||||||
-- When want to prevent execution of the command we must reject it, listed is how that can be done:
|
|
||||||
-- 1) return false -- this is the most basic rejection and should only be used while testing
|
|
||||||
-- 2) return reject -- returning the reject function is as a fail safe in case you forget to call it, same as returning false
|
|
||||||
-- 3) reject() -- this will block execution while allowing further code to be ran in your authenticator
|
|
||||||
-- 4) reject('This command is for admins only!') -- using reject as a function allows a error message to be returned
|
|
||||||
-- 5) return reject() -- using return on either case above is best practice as you should execute all your code before rejecting
|
|
||||||
|
|
||||||
-- Example Code:
|
|
||||||
Commands.add_authenticator(function(player, command, flags, reject)
|
|
||||||
-- Check if the command is admin only
|
|
||||||
if flags.admin_only then
|
|
||||||
-- Return true if player is admin, or reject and return error message
|
|
||||||
return player.admin or reject('This command is for admins only!')
|
|
||||||
else
|
|
||||||
-- Return true if command was not admin only
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
@usage--- Example Parser:
|
|
||||||
-- Before you make a command it is important to understand the most powerful feature of this command handler;
|
|
||||||
-- when you define a command you are able to type the params and have then be parsed and validated before your command is executed;
|
|
||||||
-- This module should be paired with a general command parse but you may want to create your own.
|
|
||||||
|
|
||||||
-- For our example we will create a parse to accept only integer numbers in a given range:
|
|
||||||
-- 1) we will give it the name "number-range-int" this is the "type" that the input is expected to be
|
|
||||||
-- 2) when we define the type we will also define the min and max of the range so we can use the function more than once
|
|
||||||
:add_param('repeat_count', 'number-range-int', 5, 10) -- "repeat_count" is a required "number-range-int" in a range 5 to 10 inclusive
|
|
||||||
|
|
||||||
-- The command parse will be passed 3 arguments plus any other which you define, in our case:
|
|
||||||
-- 1) input - the input that has been given by the user for this param, the role of this function is to transform this value
|
|
||||||
-- nb: the input is a string but can be nil if the param is marked as optional
|
|
||||||
-- 2) player - the player who is using the command, this is always present
|
|
||||||
-- 3) reject - the reject function to throw an error to the user, this is always present
|
|
||||||
-- 4) range_min - the range min, this is user defined and has the value given when the param is defined
|
|
||||||
-- 5) range_max - the range max, this is user defined and has the value given when the param is defined
|
|
||||||
|
|
||||||
-- When returning from the param parse you have a few options with how to do this:
|
|
||||||
-- 1) you return the new value for the param (any non nil value) this value is then passed to the command callback
|
|
||||||
-- 2) not returning will cause a generic invalid error and the command is rejected, not recommenced
|
|
||||||
-- 3) return reject -- this is just a failsafe in case the function is not called, same as no return
|
|
||||||
-- 4) return reject() -- will give a shorter error message as you pass a nil custom error
|
|
||||||
-- 5) return reject('Number entered is not in range: '..range_min..', '..range_max) -- returns a custom error to the user
|
|
||||||
-- nb: if you do not return reject after you call it then you will still be returning nil so there will be a duplicate error message
|
|
||||||
|
|
||||||
-- It should be noted that if you want to expand on an existing parse you can use Commands.parse(type, input, player, reject)
|
|
||||||
-- this function will either return a new value for the input or nil, if it is nil you should return nil to prevent duplicate
|
|
||||||
-- error messages to the user:
|
|
||||||
input = Commands.parse('number-int', input, player, reject)
|
|
||||||
if not input then return end -- nil check
|
|
||||||
|
|
||||||
-- Example Code:
|
|
||||||
Commands.add_parse('number-range-int', function(input, player, reject, range_min, range_max)
|
|
||||||
local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number
|
|
||||||
if not rtn or rtn < range_min or rtn > range_max then
|
|
||||||
-- the input is either not a number or is outside the range
|
|
||||||
return reject('Number entered is not in range: '..range_min..', '..range_max)
|
|
||||||
else
|
|
||||||
-- returns the input as a number value rather than a string, thus the param is now the correct type
|
|
||||||
return rtn
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local write_json = ExpUtil.write_json --- @dep expcore.common
|
|
||||||
local trace = debug.traceback
|
|
||||||
|
|
||||||
local Commands = {
|
|
||||||
--- Constant values used by the command system
|
|
||||||
defines = {
|
|
||||||
error = "CommandError",
|
|
||||||
unauthorized = "CommandErrorUnauthorized",
|
|
||||||
success = "CommandSuccess",
|
|
||||||
},
|
|
||||||
--- An array of all custom commands that are registered
|
|
||||||
commands = {},
|
|
||||||
--- When true any authenticator error will result in authorization failure, more secure
|
|
||||||
authorization_failure_on_error = false,
|
|
||||||
--- An array of all custom authenticators that are registered
|
|
||||||
authenticators = {},
|
|
||||||
--- Used to store default functions which are common parse function such as player or number in range
|
|
||||||
parsers = {},
|
|
||||||
--- The command prototype which stores all command defining functions
|
|
||||||
_prototype = {},
|
|
||||||
}
|
|
||||||
|
|
||||||
local Colours = ExpUtil.color
|
|
||||||
--- This is copied in so that _C.player_return can be removed
|
|
||||||
--- Returns a value to the player, different to success as this does not signal the end of your command
|
|
||||||
function Commands.print(value, colour, player)
|
|
||||||
colour = type(colour) == "table" and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white
|
|
||||||
player = player or game.player
|
|
||||||
local output = ExpUtil.format_any(value)
|
|
||||||
if player then
|
|
||||||
player = type(player) == "userdata" and player or game.get_player(player)
|
|
||||||
if not player then error("Invalid Player given to Commands.print", 2) end
|
|
||||||
player.print(output, {
|
|
||||||
color = colour,
|
|
||||||
sound_path = "utility/scenario_message",
|
|
||||||
})
|
|
||||||
else
|
|
||||||
rcon.print(output)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Authentication.
|
|
||||||
-- Functions that control who can use commands
|
|
||||||
-- @section auth
|
|
||||||
|
|
||||||
--[[-- Adds an authorization function, function used to check if a player if allowed to use a command
|
|
||||||
@tparam function authenticator The function you want to register as an authenticator
|
|
||||||
@treturn number The index it was inserted at, used to remove the authenticator
|
|
||||||
|
|
||||||
@usage-- If the admin_only flag is set, then make sure the player is an admin
|
|
||||||
local admin_authenticator =
|
|
||||||
Commands.add_authenticator(function(player, command, flags, reject)
|
|
||||||
if flags.admin_only and not player.admin then
|
|
||||||
return reject('This command is for admins only!')
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.add_authenticator(authenticator)
|
|
||||||
local next_index = #Commands.authenticators + 1
|
|
||||||
Commands.authenticators[next_index] = authenticator
|
|
||||||
return next_index
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Removes an authorization function, can use the index or the function value
|
|
||||||
@tparam function|number authenticator The authenticator to remove, either the index return from add_authenticator or the function used
|
|
||||||
@treturn boolean If the authenticator was found and removed successfully
|
|
||||||
|
|
||||||
@usage-- Removing the admin authenticator, can not be done during runtime
|
|
||||||
Commands.remove_authenticator(admin_authenticator)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.remove_authenticator(authenticator)
|
|
||||||
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
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- will search the array and remove the key
|
|
||||||
for index, value in pairs(Commands.authenticators) do
|
|
||||||
if value == authenticator then
|
|
||||||
Commands.authenticators[index] = nil
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Mostly used internally, calls all authenticators, returns if the player is authorized
|
|
||||||
@tparam LuaPlayer player The player who is using the command, passed to authenticators
|
|
||||||
@tparam string command_name The name of the command being used, passed to authenticators
|
|
||||||
@treturn[1] boolean true Player is authorized
|
|
||||||
@treturn[1] string commands Define value for success
|
|
||||||
@treturn[2] boolean false Player is unauthorized
|
|
||||||
@treturn[2] string|locale_string The reason given by the failed authenticator
|
|
||||||
|
|
||||||
@usage-- Test if a player can use "repeat-name"
|
|
||||||
local authorized, status = Commands.authorize(game.player, 'repeat-name')
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.authorize(player, command_name)
|
|
||||||
local command_data = Commands.commands[command_name]
|
|
||||||
if not command_data then return false end
|
|
||||||
if not player then return true end
|
|
||||||
|
|
||||||
-- This is the reject function given to authenticators
|
|
||||||
local failure_message
|
|
||||||
local function reject(message)
|
|
||||||
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))
|
|
||||||
if Commands.authorization_failure_on_error then
|
|
||||||
return reject("Internal Error")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Loops over each authenticator, if any return false then then command will not be ran
|
|
||||||
for _, authenticator in pairs(Commands.authenticators) do
|
|
||||||
-- 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
|
|
||||||
return false, failure_message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true, Commands.defines.success
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Parse.
|
|
||||||
-- Functions that help with parsing
|
|
||||||
-- @section parse
|
|
||||||
|
|
||||||
--[[-- Adds a parse function which can be called by name (used in add_param)
|
|
||||||
nb: this is not required as you can use the callback directly this just allows it to be called by name
|
|
||||||
@tparam string name The name of the parse, should describe a type of input such as number or player, must be unique
|
|
||||||
@tparam function parser The function that is ran to parse the input string
|
|
||||||
@treturn boolean Was the parse added, will be false if the name is already used
|
|
||||||
|
|
||||||
@usage-- Adding a parse to validate integers in a given range
|
|
||||||
Commands.add_parse('number-range-int', function(input, player, reject, range_min, range_max)
|
|
||||||
local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number
|
|
||||||
if not rtn or rtn < range_min or rtn > range_max then
|
|
||||||
-- The input is either not a number or is outside the range
|
|
||||||
return reject('Number entered is not in range: '..range_min..', '..range_max)
|
|
||||||
else
|
|
||||||
-- Returns the input as a number rather than a string, thus the param is now the correct type
|
|
||||||
return rtn
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.add_parse(name, parser)
|
|
||||||
if Commands.parsers[name] then return false end
|
|
||||||
Commands.parsers[name] = parser
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Removes a parse function, see add_parse for adding them, cant be done during runtime
|
|
||||||
@tparam string name The name of the parse to remove
|
|
||||||
|
|
||||||
@usage-- Removing a parse
|
|
||||||
Commands.remove_parse('number-range-int')
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.remove_parse(name)
|
|
||||||
Commands.parsers[name] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Intended to be used within other parse functions, runs a parse and returns success and new value
|
|
||||||
@tparam string name The name of the parse to call, must be a registered parser
|
|
||||||
@tparam string input The input to pass to the parse, must be a string but not necessarily the original input
|
|
||||||
@tparam LuaPlayer player The player that is using the command, pass directly from your arguments
|
|
||||||
@tparam function reject The reject function, pass directly from your arguments
|
|
||||||
@treturn any The new value for the input, if nil is return then either there was an error or the input was nil
|
|
||||||
|
|
||||||
@usage-- Parsing an int after first checking it is a number
|
|
||||||
Commands.add_parse('number', function(input, player, reject)
|
|
||||||
local number = tonumber(input)
|
|
||||||
if number then return number end
|
|
||||||
return reject('Input must be a number value')
|
|
||||||
end)
|
|
||||||
|
|
||||||
Commands.add_parse('number-int', function(input, player, reject)
|
|
||||||
local number = Commands.parse('number', input, player, reject)
|
|
||||||
if not number then return end
|
|
||||||
return math.floor(number)
|
|
||||||
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 rtn or rtn == Commands.defines.error then return end
|
|
||||||
return rtn
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Getters.
|
|
||||||
-- Functions that get commands
|
|
||||||
-- @section getters
|
|
||||||
|
|
||||||
--[[-- Gets all commands that a player is allowed to use, game commands are not included
|
|
||||||
@tparam[opt] LuaPlayer player The player that you want to get commands of, nil will return all commands
|
|
||||||
@treturn table All commands that that player is allowed to use, or all commands
|
|
||||||
|
|
||||||
@usage-- Get the commands you are allowed to use
|
|
||||||
local commands = Commands.get(game.player)
|
|
||||||
|
|
||||||
@usage-- Get all commands that are registered
|
|
||||||
local commands = Commands.get()
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.get(player)
|
|
||||||
if not player then return Commands.commands end
|
|
||||||
local allowed = {}
|
|
||||||
for name, command_data in pairs(Commands.commands) do
|
|
||||||
if Commands.authorize(player, name) then
|
|
||||||
allowed[name] = command_data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return allowed
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Searches command names and help messages to find possible commands, game commands are included
|
|
||||||
@tparam string keyword The word which you are trying to find in your search
|
|
||||||
@tparam[opt] LuaPlayer player The player to get allowed commands of, if nil all commands are searched
|
|
||||||
@treturn table All commands that contain the key word, and allowed by the player if a player was given
|
|
||||||
|
|
||||||
@usage-- Get all commands which "repeat"
|
|
||||||
local commands = Commands.search('repeat')
|
|
||||||
|
|
||||||
@usage-- Get all commands which "repeat" and you are allowed to use
|
|
||||||
local commands = Commands.search('repeat', game.player)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.search(keyword, player)
|
|
||||||
local custom_commands = Commands.get(player)
|
|
||||||
local matches = {}
|
|
||||||
keyword = keyword:lower()
|
|
||||||
-- 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, " "))
|
|
||||||
|
|
||||||
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
|
|
||||||
-- because game commands lack some stuff that the custom ones have they are formatted
|
|
||||||
matches[name] = {
|
|
||||||
name = name,
|
|
||||||
help = description,
|
|
||||||
description = "",
|
|
||||||
aliases = {},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return matches
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Creation.
|
|
||||||
-- Functions that create a new command
|
|
||||||
-- @section creation
|
|
||||||
|
|
||||||
--[[-- Creates a new command object to added details to, this does not register the command to the game api
|
|
||||||
@tparam string name The name of the command to be created
|
|
||||||
@tparam string help The help message for the command
|
|
||||||
@treturn table This will be used with other functions to define the new command
|
|
||||||
|
|
||||||
@usage-- Define a new command
|
|
||||||
Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.')
|
|
||||||
|
|
||||||
]]
|
|
||||||
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,
|
|
||||||
auto_concat = false,
|
|
||||||
min_param_count = 0,
|
|
||||||
max_param_count = 0,
|
|
||||||
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}
|
|
||||||
}, {
|
|
||||||
__index = Commands._prototype,
|
|
||||||
})
|
|
||||||
Commands.commands[name] = command
|
|
||||||
return command
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Adds a new param to the command this will be displayed in the help and used to parse the input
|
|
||||||
@tparam string name The name of the new param that is being added to the command
|
|
||||||
@tparam[opt=false] boolean optional Is this param optional, these must be added after all required params
|
|
||||||
@tparam[opt] ?string|function parse This function will take the input and return a new value, if not given no parse is done
|
|
||||||
@tparam[opt] any ... Extra args you want to pass to the parse function; for example if the parse is general use
|
|
||||||
@treturn table Pass through to allow more functions to be called
|
|
||||||
|
|
||||||
@usage-- Adding a required param which has a parser pre-defined
|
|
||||||
command:add_param('repeat-count', 'number-range-int', 1, 5)
|
|
||||||
|
|
||||||
@usage-- Adding an optional param which has a custom parse, see Commands.add_parse for details
|
|
||||||
command:add_param('smiley', true, function(input, player, reject)
|
|
||||||
if not input then return end
|
|
||||||
return input:lower() == 'true' or input:lower() == 'yes' or false
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands._prototype:add_param(name, optional, 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,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.max_param_count = self.max_param_count + 1
|
|
||||||
if not optional then
|
|
||||||
self.min_param_count = self.min_param_count + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Add default values to params, only as an effect if the param is optional, if default value is a function it is called with the acting player
|
|
||||||
@tparam table defaults A table which is keyed by the name of the param and the value is the default value for that param
|
|
||||||
@treturn table Pass through to allow more functions to be called
|
|
||||||
|
|
||||||
@usage-- Adding default values
|
|
||||||
command:set_defaults{
|
|
||||||
smiley = false,
|
|
||||||
-- not in example just used to show arguments given
|
|
||||||
player_name = function(player)
|
|
||||||
return player.name
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands._prototype:set_defaults(defaults)
|
|
||||||
for name, value in pairs(defaults) do
|
|
||||||
if self.params[name] then
|
|
||||||
self.params[name].default = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Adds a flag to the command which is passed via the flags param to the authenticators, can be used to assign command roles or usage type
|
|
||||||
@tparam string name The name of the flag to be added, set to true if no value is given
|
|
||||||
@tparam[opt=true] any value The value for the flag, can be anything that the authenticators are expecting
|
|
||||||
@treturn table Pass through to allow more functions to be called
|
|
||||||
|
|
||||||
@usage-- Setting a custom flag
|
|
||||||
command:set_flag('admin_only', true)
|
|
||||||
|
|
||||||
@usage-- When value is true it does not need to be given
|
|
||||||
command:set_flag('admin_only')
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands._prototype:set_flag(name, value)
|
|
||||||
self.flags[name] = value or true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Adds an alias, or multiple, that will be registered to this command, eg /teleport can be used as /tp
|
|
||||||
@tparam string ... Any amount of aliases that you want this command to be callable with
|
|
||||||
@treturn table Pass through to allow more functions to be called
|
|
||||||
|
|
||||||
@usage-- Added multiple aliases to a command
|
|
||||||
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
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Enables auto concatenation for this command, all params after the last are added to the last param, useful for reasons or other long text input
|
|
||||||
nb: this will disable max param checking as they will be concatenated onto the end of that last param
|
|
||||||
@treturn table Pass through to allow more functions to be called
|
|
||||||
|
|
||||||
@usage-- Enable auto concat for a command
|
|
||||||
command:enable_auto_concat()
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands._prototype:enable_auto_concat()
|
|
||||||
self.auto_concat = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Adds the callback to the command and registers: aliases, params and help message with the base game api
|
|
||||||
nb: this must be the last function ran on the command and must be done for the command to work
|
|
||||||
@tparam function callback The callback for the command, will receive the player running command, and any params added with add_param
|
|
||||||
|
|
||||||
@usage-- Registering your command to the base game api
|
|
||||||
command:register(function(player, repeat_count, smiley, raw)
|
|
||||||
local msg = ') '..player.name
|
|
||||||
if smiley then msg = ':'..msg end
|
|
||||||
|
|
||||||
for 1 = 1, repeat_count do
|
|
||||||
Command.print(1..msg)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands._prototype:register(callback)
|
|
||||||
self.callback = callback
|
|
||||||
|
|
||||||
-- Generates a description to be used
|
|
||||||
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)
|
|
||||||
else
|
|
||||||
description = string.format("%s <%s>", description, param_name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.description = description
|
|
||||||
|
|
||||||
-- Last resort error handler for commands
|
|
||||||
local function command_error(err)
|
|
||||||
Commands.internal_error(false, self.name, trace(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Callback that the game will call
|
|
||||||
local function command_callback(event)
|
|
||||||
event.name = self.name
|
|
||||||
xpcall(Commands.run_command, command_error, event)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Registers the command under its own name
|
|
||||||
local help = { "expcore-commands.command-help", description, self.help }
|
|
||||||
commands.add_command(self.name, help, command_callback)
|
|
||||||
|
|
||||||
-- Adds any aliases that it has
|
|
||||||
for _, alias in pairs(self.aliases) do
|
|
||||||
if not commands.commands[alias] and not commands.game_commands[alias] then
|
|
||||||
commands.add_command(alias, help, command_callback)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Status.
|
|
||||||
-- Functions that indicate status
|
|
||||||
-- @section status
|
|
||||||
|
|
||||||
--[[-- Sends a value to the player, followed by a command complete message, returning a value will trigger this automatically
|
|
||||||
@tparam[opt] any value The value to return to the player, if nil then only the success message is returned
|
|
||||||
@treturn Commands.defines.success Return this to the command handler to prevent two success messages
|
|
||||||
|
|
||||||
@usage-- Print a custom success message
|
|
||||||
return Commands.success('Your message has been printed')
|
|
||||||
|
|
||||||
@usage-- Returning the value has the same result
|
|
||||||
return 'Your message has been printed'
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.success(value)
|
|
||||||
if value ~= nil then Commands.print(value) end
|
|
||||||
Commands.print({ "expcore-commands.command-ran" }, "cyan")
|
|
||||||
return Commands.defines.success
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Sends a value to the player, different to success as this does not signal the end of your command
|
|
||||||
@function print
|
|
||||||
@tparam any value The value that you want to return to the player
|
|
||||||
@tparam table colour The colour of the message that the player sees
|
|
||||||
|
|
||||||
@usage-- Output a message to the player
|
|
||||||
Commands.print('Your command is in progress')
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
--[[-- Sends an error message to the player and when returned will stop execution of the command
|
|
||||||
nb: this is for non fatal errors meaning there is no log of this event, use during register callback
|
|
||||||
@tparam[opt=''] string error_message An optional error message that can be sent to the user
|
|
||||||
@tparam[opt=utility/wire_pickup] string play_sound The sound to play for the error
|
|
||||||
@treturn Commands.defines.error Return this to command handler to terminate execution
|
|
||||||
|
|
||||||
@usage-- Send an error message to the player, and stops further code running
|
|
||||||
return Commands.error('The player you selected is offline')
|
|
||||||
|
|
||||||
]]
|
|
||||||
function Commands.error(error_message, play_sound)
|
|
||||||
error_message = error_message or ""
|
|
||||||
Commands.print({ "expcore-commands.command-fail", error_message }, "orange_red")
|
|
||||||
if play_sound ~= false then
|
|
||||||
play_sound = play_sound or "utility/wire_pickup"
|
|
||||||
if game.player then game.player.play_sound{ path = play_sound } end
|
|
||||||
end
|
|
||||||
return Commands.defines.error
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[-- Sends an error to the player and logs the error, used internally please avoid direct use
|
|
||||||
nb: use error(error_message) within your callback to trigger do not trigger directly as code execution may still continue
|
|
||||||
@tparam boolean success The success value returned from pcall, or just false to trigger error
|
|
||||||
@tparam string command_name The name of the command this is used within the log
|
|
||||||
@tparam string error_message The error returned by pcall or some other error, this is logged and not returned to player
|
|
||||||
@treturn boolean The opposite of success so true means to cancel execution, used internally
|
|
||||||
|
|
||||||
@usage-- Used in the command system to log handler errors
|
|
||||||
local success, err = pcall(command_data.callback, player, table.unpack(params))
|
|
||||||
if Commands.internal_error(success, command_data.name, err) then
|
|
||||||
return command_log(player, command_data, 'Internal Error: Command Callback Fail', raw_params, command_event.parameter, err)
|
|
||||||
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 }
|
|
||||||
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,
|
|
||||||
command_name = command.name,
|
|
||||||
comment = comment,
|
|
||||||
details = details,
|
|
||||||
params = params,
|
|
||||||
raw = raw,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Main event function that is ran for all commands, used internally please avoid direct use
|
|
||||||
-- @tparam table command_event Passed directly from the add_command function
|
|
||||||
-- @usage Commands.run_command(event)
|
|
||||||
function Commands.run_command(command_event)
|
|
||||||
local command_data = Commands.commands[command_event.name]
|
|
||||||
-- Player can be nil when it is the server
|
|
||||||
local player
|
|
||||||
if command_event.player_index and command_event.player_index > 0 then
|
|
||||||
player = game.players[command_event.player_index]
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 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")
|
|
||||||
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 }
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Extract quoted arguments
|
|
||||||
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")
|
|
||||||
quote_params[no_spaces] = word:sub(2, -2)
|
|
||||||
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
|
|
||||||
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 }
|
|
||||||
return
|
|
||||||
else
|
|
||||||
-- concat to the last param
|
|
||||||
if quote_params[word] then
|
|
||||||
raw_params[last_index] = raw_params[last_index] .. ' "' .. quote_params[word] .. '"'
|
|
||||||
else
|
|
||||||
raw_params[last_index] = raw_params[last_index] .. " " .. word
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- new param that needs to be added
|
|
||||||
if quote_params[word] then
|
|
||||||
last_index = last_index + 1
|
|
||||||
raw_params[last_index] = quote_params[word]
|
|
||||||
else
|
|
||||||
last_index = last_index + 1
|
|
||||||
raw_params[last_index] = word
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 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 }
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Parse the arguments
|
|
||||||
local index = 1
|
|
||||||
local params = {}
|
|
||||||
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
|
|
||||||
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))
|
|
||||||
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 }
|
|
||||||
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)
|
|
||||||
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
|
|
||||||
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)
|
|
||||||
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" }
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add the param to the table to be passed to the command callback
|
|
||||||
params[index] = param_parsed
|
|
||||||
index = index + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run the command
|
|
||||||
-- player: LuaPlayer, ... command params, raw: string
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
elseif rtn ~= Commands.defines.success and rtn ~= Commands.success then
|
|
||||||
Commands.success(rtn)
|
|
||||||
end
|
|
||||||
command_log(player, command_data, "Success", raw_params, raw_input)
|
|
||||||
end
|
|
||||||
|
|
||||||
return Commands
|
|
||||||
@@ -195,7 +195,7 @@ Gui.toggle_top_flow(game.player, true)
|
|||||||
]]
|
]]
|
||||||
function Gui.toggle_top_flow(player, state)
|
function Gui.toggle_top_flow(player, state)
|
||||||
-- Get the top flow, we need the parent as we want to toggle the outer frame
|
-- Get the top flow, we need the parent as we want to toggle the outer frame
|
||||||
local top_flow = Gui.get_top_flow(player).parent
|
local top_flow = Gui.get_top_flow(player).parent --- @cast top_flow -nil
|
||||||
if state == nil then state = not top_flow.visible end
|
if state == nil then state = not top_flow.visible end
|
||||||
|
|
||||||
-- Get the show button for the top flow
|
-- Get the show button for the top flow
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ end)
|
|||||||
local Async = require("modules/exp_util/async")
|
local Async = require("modules/exp_util/async")
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
local Datastore = require("modules.exp_legacy.expcore.datastore") --- @dep expcore.datastore
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse") --- @dep config.expcore.command_general_parse
|
|
||||||
|
|
||||||
local table_to_json = helpers.table_to_json
|
local table_to_json = helpers.table_to_json
|
||||||
local write_file = helpers.write_file
|
local write_file = helpers.write_file
|
||||||
@@ -67,23 +66,20 @@ DataSavingPreference:set_metadata{
|
|||||||
}
|
}
|
||||||
|
|
||||||
--- Sets your data saving preference
|
--- Sets your data saving preference
|
||||||
-- @command set-data-preference
|
Commands.new("data-preference", { "expcore-data.description-preference" })
|
||||||
Commands.new_command("set-preference", "Allows you to set your data saving preference")
|
:optional("option", { "expcore-data.arg-option" }, Commands.types.enum(PreferenceEnum))
|
||||||
:add_param("option", false, "string-options", PreferenceEnum)
|
|
||||||
:register(function(player, option)
|
:register(function(player, option)
|
||||||
DataSavingPreference:set(player, option)
|
--- @cast option "All" | "Statistics" | "Settings" | "Required" | nil
|
||||||
return { "expcore-data.set-preference", option }
|
if option then
|
||||||
end)
|
DataSavingPreference:set(player, option)
|
||||||
|
return Commands.status.success{ "expcore-data.set-preference", option }
|
||||||
--- Gets your data saving preference
|
else
|
||||||
-- @command data-preference
|
return Commands.status.success{ "expcore-data.get-preference", DataSavingPreference:get(player) }
|
||||||
Commands.new_command("preference", "Shows you what your current data saving preference is")
|
end
|
||||||
:register(function(player)
|
|
||||||
return { "expcore-data.get-preference", DataSavingPreference:get(player) }
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Gets your data and writes it to a file
|
--- 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")
|
Commands.new("save-data", { "expcore-data.description-data" })
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
player.print{ "expcore-data.get-data" }
|
player.print{ "expcore-data.get-data" }
|
||||||
write_file("expgaming_player_data.json", table_to_json(PlayerData:get(player, {})), false, player.index)
|
write_file("expgaming_player_data.json", table_to_json(PlayerData:get(player, {})), false, player.index)
|
||||||
|
|||||||
@@ -311,6 +311,15 @@ function Roles.get_role_from_any(any)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns all roles in order of index
|
||||||
|
function Roles.get_roles_ordered()
|
||||||
|
local rtn = {}
|
||||||
|
for index, role_name in ipairs(Roles.config.order) do
|
||||||
|
rtn[index] = Roles.config.roles[role_name]
|
||||||
|
end
|
||||||
|
return rtn
|
||||||
|
end
|
||||||
|
|
||||||
--[[-- Gets all the roles of the given player, this will always contain the default role
|
--[[-- Gets all the roles of the given player, this will always contain the default role
|
||||||
@tparam LuaPlayer player the player to get the roles of
|
@tparam LuaPlayer player the player to get the roles of
|
||||||
@treturn table a table where the values are the roles which the player has
|
@treturn table a table where the values are the roles which the player has
|
||||||
|
|||||||
@@ -1,245 +0,0 @@
|
|||||||
[expcom-admin-chat]
|
|
||||||
description=Sends a message in chat that only admins can see.
|
|
||||||
format=[Admin Chat] __1__: __2__
|
|
||||||
|
|
||||||
[expcom-admin-marker]
|
|
||||||
description=Toggles admin marker mode, new markers can only be edited by admins
|
|
||||||
exit=You have left admin marker mode, all new markers will not be protected.
|
|
||||||
enter=You have entered admin marker mode, all new markers will be protected.
|
|
||||||
place=You have placed an admin marker.
|
|
||||||
edit=You have edited an admin marker.
|
|
||||||
revert=You cannot edit admin markers.
|
|
||||||
|
|
||||||
[expcom-artillery]
|
|
||||||
description=Artillery Target Remote
|
|
||||||
|
|
||||||
[expcom-bonus]
|
|
||||||
description=Changes the amount of bonus you receive
|
|
||||||
set=Your bonus has been set to __1__.
|
|
||||||
perm=You dont have enough permission to set more than __1__.
|
|
||||||
|
|
||||||
[expcom-bot-queue]
|
|
||||||
description-get=Get bot queue
|
|
||||||
description-set=Set bot queue
|
|
||||||
result=__1__ set the bot queue to __2__ successful attempts and __3__ failed attempts
|
|
||||||
|
|
||||||
[expcom-cheat]
|
|
||||||
description-cheat=Toggles cheat mode for your player, or another player.
|
|
||||||
description-res=Set all research for your force.
|
|
||||||
description-day=Toggles always day in surface.
|
|
||||||
res=__1__ has enabled all technologies
|
|
||||||
day=__1__ set always day to __2__
|
|
||||||
|
|
||||||
[expcom-chelp]
|
|
||||||
description=Searches for a keyword in all commands you are allowed to use.
|
|
||||||
title=Help results for "__1__":
|
|
||||||
footer=[__1__ results found: page __2__ of __3__]
|
|
||||||
format=/__1__ __2__ - __3__ __4__
|
|
||||||
alias=Alias: __1__
|
|
||||||
out-of-range=__1__ is an invalid page number.
|
|
||||||
|
|
||||||
[expcom-clr-inv]
|
|
||||||
description=Clears a players inventory
|
|
||||||
|
|
||||||
[expcom-connect]
|
|
||||||
description=Connect to another server
|
|
||||||
description-player=Send a player to a different server
|
|
||||||
description-all=Connect all players to another server
|
|
||||||
too-many-matching=Multiple server were found with the given name: __1__
|
|
||||||
wrong-version=Servers were found but are on a different version: __1__
|
|
||||||
same-server=You are already connected to the server: __1__
|
|
||||||
offline=You cannot connect as the server is currently offline: __1__
|
|
||||||
none-matching=No servers were found with that name, if you used an address please append true to the end of your command.
|
|
||||||
|
|
||||||
[expcom-debug]
|
|
||||||
description=Opens the debug pannel for viewing tables.
|
|
||||||
|
|
||||||
[expcom-enemy]
|
|
||||||
description-kill=Kill all biters only
|
|
||||||
description-remove=Remove biters and prevent generation
|
|
||||||
|
|
||||||
[expcom-ff]
|
|
||||||
description=Toggle friendly fire
|
|
||||||
ff=__1__ set friendly fire to __2__
|
|
||||||
|
|
||||||
[expcom-find]
|
|
||||||
description=Find a player on your map.
|
|
||||||
|
|
||||||
[expcom-home]
|
|
||||||
description-home=Teleports you to your home location
|
|
||||||
description-home-set=Sets your home location to your current position
|
|
||||||
description-home-get=Returns your current home location
|
|
||||||
description-return=Teleports you to previous location
|
|
||||||
no-home=You have no home set.
|
|
||||||
no-return=You can't return when home has not yet been used.
|
|
||||||
home-set=Your home point has been set to x: __1__ y: __2__
|
|
||||||
return-set=Your return point has been set to x: __1__ y: __2__
|
|
||||||
home-get=Your home point is at x: __1__ y: __2__
|
|
||||||
|
|
||||||
[expcom-interface]
|
|
||||||
description=Sends an invocation to be ran and returns the result.
|
|
||||||
|
|
||||||
[expcom-inv-search]
|
|
||||||
description-ia=Display players sorted by the quantity of an item held
|
|
||||||
description-ir=Display players who hold an item sorted by join time
|
|
||||||
description-i=Display players sorted by the quantity of an item held and playtime
|
|
||||||
description-io=Display online players sorted by the quantity of an item held and playtime
|
|
||||||
reject-item=No item was found with internal name __1__; try using rich text selection.
|
|
||||||
results-heading=Players found with [item=__1__]:
|
|
||||||
results-item=__1__) __2__ has __3__ items. (__4__)
|
|
||||||
results-none=No players have [item=__1__]
|
|
||||||
|
|
||||||
[expcom-jail]
|
|
||||||
description-jail=Puts a player into jail and removes all other roles.
|
|
||||||
description-unjail=Removes a player from jail.
|
|
||||||
give=__1__ was jailed by __2__. Reason: __3__
|
|
||||||
remove=__1__ was unjailed by __2__.
|
|
||||||
already-jailed=__1__ is already in jail.
|
|
||||||
not-jailed=__1__ is not currently in jail.
|
|
||||||
|
|
||||||
[expcom-join-message]
|
|
||||||
description-msg=Sets your custom join message
|
|
||||||
description-clr=Clear your join message
|
|
||||||
|
|
||||||
[expcom-kill]
|
|
||||||
description=Kills yourself or another player.
|
|
||||||
already-dead=You are already dead.
|
|
||||||
|
|
||||||
[expcom-lawnmower]
|
|
||||||
description=Clean up biter corpse, decoratives and nuclear hole
|
|
||||||
|
|
||||||
[expcom-lastlocation]
|
|
||||||
description=Sends you the last location of a player
|
|
||||||
response=Last location of __1__ was [gps=__2__,__3__]
|
|
||||||
|
|
||||||
[expcom-me]
|
|
||||||
description=Sends an action message in the chat
|
|
||||||
|
|
||||||
[expcom-personal-logistics]
|
|
||||||
description=Set Personal Logistic (-1 to cancel all) (Select spidertron to edit spidertron)
|
|
||||||
|
|
||||||
[expcom-pol]
|
|
||||||
description-clr=Clear pollution
|
|
||||||
description-off=Disable pollution
|
|
||||||
clr=__1__ cleared the pollution.
|
|
||||||
off=__1__ disabled the pollution.
|
|
||||||
|
|
||||||
[expcom-protection]
|
|
||||||
description-pe=Toggles entity protection selection, hold shift to remove protection
|
|
||||||
description-pa=Toggles area protection selection, hold shift to remove protection
|
|
||||||
entered-entity-selection=Entered entity selection, select entites to protect, hold shift to remove protection.
|
|
||||||
entered-area-selection=Entered area selection, select areas to protect, hold shift to remove protection.
|
|
||||||
protected-entities=__1__ entities have been protected.
|
|
||||||
unprotected-entities=__1__ entities have been unprotected.
|
|
||||||
already-protected=This area is already protected.
|
|
||||||
protected-area=This area is now protected.
|
|
||||||
unprotected-area=This area is now unprotected.
|
|
||||||
repeat-offence=__1__ has removed __2__ at [gps=__3__,__4__]
|
|
||||||
|
|
||||||
[expcom-quickbar]
|
|
||||||
description=Saves your quickbar preset items to file
|
|
||||||
|
|
||||||
[expcom-rainbow]
|
|
||||||
description=Sends an rainbow message in the chat
|
|
||||||
|
|
||||||
[expcom-ratio]
|
|
||||||
description=This command will give the input and output ratios of the selected machine. Use the parameter for calculating the machines needed for that amount of items per second.
|
|
||||||
notSelecting=Please select an entity with a recipe.
|
|
||||||
item-in=You need __1__ per second of [item=__2__].
|
|
||||||
fluid-in=You need __1__ per second of [fluid=__2__].
|
|
||||||
item-out=This will result in: __1__ [item=__2__] per second.
|
|
||||||
fluid-out=This will result in: __1__ [fluid=__2__] per second.
|
|
||||||
machines=And you will need __1__ machines (with the same speed as this one) for this.
|
|
||||||
|
|
||||||
[expcom-repair]
|
|
||||||
description=Repairs entities on your force around you
|
|
||||||
result=__1__ entites were revived and __2__ were healed to max health.
|
|
||||||
|
|
||||||
[expcom-report]
|
|
||||||
description-report=Reports a player and notifies moderators
|
|
||||||
description-get-reports=Gets a list of all reports that a player has on them. If no player then lists all players and the number of reports on them.
|
|
||||||
description-clear-reports=Clears all reports from a player or just the report from one player.
|
|
||||||
player-immune=This player can not be reported.
|
|
||||||
self-report=You cannot report yourself.
|
|
||||||
non-admin=__1__ was reported for __2__.
|
|
||||||
admin=__1__ was reported by __2__ for __3__.
|
|
||||||
already-reported=You can only report a player once, you can ask a moderator to clear this report.
|
|
||||||
not-reported=The player had no reports on them.
|
|
||||||
player-count-title=The following players have reports against them:
|
|
||||||
player-report-title=__1__ has the following reports against them:
|
|
||||||
list=__1__: __2__
|
|
||||||
removed=__1__ has one or more reports removed by __2__.
|
|
||||||
|
|
||||||
[expcom-res]
|
|
||||||
description-ares=Automatically queue up research
|
|
||||||
res=__1__ set auto research to __2__
|
|
||||||
msg=[color=255, 255, 255] Research completed at __1__ - [technology=__2__][/color]
|
|
||||||
inf=[color=255, 255, 255] Research completed at __1__ - [technology=__2__] - __3__[/color]
|
|
||||||
inf-q=[color=255, 255, 255] Research added to queue - [technology=__1__] - __2__[/color]
|
|
||||||
res-name=[technology=__1__] __2__
|
|
||||||
name=Name
|
|
||||||
target=Target
|
|
||||||
attempt=Attempt
|
|
||||||
difference=Diff
|
|
||||||
main-tooltip=Research GUI
|
|
||||||
|
|
||||||
[expcom-roles]
|
|
||||||
description-assign-role=Assigns a role to a player
|
|
||||||
description-unassign-role=Unassigns a role from a player
|
|
||||||
description-list-roles=Lists all roles in they correct order
|
|
||||||
higher-role=The role you tried to assign is higher than your highest.
|
|
||||||
list=All roles are: __1__
|
|
||||||
list-player=__1__ has: __2__
|
|
||||||
list-element=__1__, __2__
|
|
||||||
|
|
||||||
[expcom-server-ups]
|
|
||||||
no-ext=No external source was found, cannot display server ups.
|
|
||||||
|
|
||||||
[expcom-spawn]
|
|
||||||
description=Teleport to spawn
|
|
||||||
unavailable=They was a problem getting you to spawn, please try again later.
|
|
||||||
|
|
||||||
[expcom-spectate]
|
|
||||||
description-spectate=Toggles spectator mode
|
|
||||||
description-follow=Start following a player in spectator
|
|
||||||
follow-self=You can not follow yourself
|
|
||||||
|
|
||||||
[expcom-speed]
|
|
||||||
description=Set game speed
|
|
||||||
result=__1__ set the game speed to __2__
|
|
||||||
|
|
||||||
[expcom-surface-clearing]
|
|
||||||
description-ci=Clear Item On Ground
|
|
||||||
description-cb=Clear Blueprint
|
|
||||||
|
|
||||||
[expcom-tag]
|
|
||||||
description=Sets your player tag.
|
|
||||||
description-clear=Clears your tag. Or another player if you are admin.
|
|
||||||
|
|
||||||
[expcom-tp]
|
|
||||||
description-tp=Teleports a player to another player.
|
|
||||||
description-bring=Teleports a player to you.
|
|
||||||
description-goto=Teleports you to a player.
|
|
||||||
no-position-found=No position to teleport to was found, please try again later.
|
|
||||||
to-self=Player can not be teleported to themselves.
|
|
||||||
|
|
||||||
[expcom-train]
|
|
||||||
description=Set All Trains to Automatic
|
|
||||||
manual-result=__1__ put __2__ trains into automatic mode
|
|
||||||
|
|
||||||
[expcom-warnings]
|
|
||||||
description-give=Gives a warning to a player; may lead to automatic script action.
|
|
||||||
description-get=Gets the number of warnings a player has. If no player then lists all players and the number of warnings they have.
|
|
||||||
description-clear=Clears all warnings (and script warnings) from a player
|
|
||||||
received=__1__ received a warning from __2__ for __3__.
|
|
||||||
player=__1__ has __2__ warnings and __3__/__4__ script warnings.
|
|
||||||
player-detail=__1__ gave warning for: __2__
|
|
||||||
list-title=The following players have this many warnings (and this many script warnings):
|
|
||||||
list=__1__: __2__ (__3__/__4__)
|
|
||||||
cleared=__1__ had all their warnings cleared by __2__.
|
|
||||||
|
|
||||||
[expcom-waterfill]
|
|
||||||
description=Change tile to water
|
|
||||||
waterfill-distance=Too close to designated location
|
|
||||||
waterfill-cliff=Not enough cliff explosive to create water
|
|
||||||
entered-area-selection=Entered area selection, select areas to convert.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
[command-auth]
|
|
||||||
admin-only=This command is for (game) admins only!
|
|
||||||
command-disabled=This command has been disabled by management!
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
[join-message]
|
[join-message]
|
||||||
|
description-add=Sets / Gets your custom join message.
|
||||||
|
description-remove=Removes you custom join message.
|
||||||
|
arg-message=Your custom join message.
|
||||||
greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color]
|
greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color]
|
||||||
message-set=Your join message has been updated.
|
message-set=Your join message has been updated.
|
||||||
|
message-get=Your join message is: __1__
|
||||||
message-cleared=Your join message has been cleared.
|
message-cleared=Your join message has been cleared.
|
||||||
|
|
||||||
[quickbar]
|
[quickbar]
|
||||||
|
|||||||
@@ -1,29 +1,3 @@
|
|||||||
time-symbol-days-short=__1__d
|
|
||||||
color-tag=[color=__1__]__2__[/color]
|
|
||||||
|
|
||||||
[time-format]
|
|
||||||
simple-format-tagged=__1__ __2__
|
|
||||||
simple-format-div=__1__:__2__
|
|
||||||
|
|
||||||
[expcore-commands]
|
|
||||||
unauthorized=Unauthorized, Access is denied due to invalid credentials
|
|
||||||
reject-string-options=Invalid Option, Must be one of: __1__
|
|
||||||
reject-string-max-length=Invalid Length, Max: __1__
|
|
||||||
reject-number=Invalid Number.
|
|
||||||
reject-number-range=Invalid Range, Min (inclusive): __1__, Max (inclusive): __2__
|
|
||||||
reject-player=Invalid Player Name, __1__ ,try using tab key to auto-complete the name
|
|
||||||
reject-player-online=Player is offline.
|
|
||||||
reject-player-alive=Player is dead.
|
|
||||||
reject-force=Invalid Force Name.
|
|
||||||
reject-surface=Invalid Surface Name.
|
|
||||||
reject-color=Invalid Color Name.
|
|
||||||
invalid-inputs=Invalid Input, /__1__ __2__
|
|
||||||
invalid-param=Invalid Param "__1__"; __2__
|
|
||||||
command-help=__1__ - __2__
|
|
||||||
command-ran=Command Complete
|
|
||||||
command-fail=Command failed to run: __1__
|
|
||||||
command-error-log-format=[ERROR] command/__1__ :: __2__
|
|
||||||
|
|
||||||
[expcore-roles]
|
[expcore-roles]
|
||||||
error-log-format-flag=[ERROR] roleFlag/__1__ :: __2__
|
error-log-format-flag=[ERROR] roleFlag/__1__ :: __2__
|
||||||
error-log-format-assign=[ERROR] rolePromote/__1__ :: __2__
|
error-log-format-assign=[ERROR] rolePromote/__1__ :: __2__
|
||||||
@@ -39,6 +13,8 @@ button_tooltip=Shows/hides the toolbar.
|
|||||||
left-button-tooltip=Hide all open windows.
|
left-button-tooltip=Hide all open windows.
|
||||||
|
|
||||||
[expcore-data]
|
[expcore-data]
|
||||||
|
description-preference=Allows you to set/get your data saving preference.
|
||||||
|
description-data=Writes all your player data to a file on your computer.
|
||||||
set-preference=You data saving preference has been set to __1__. Existing data will not be effected until you rejoin.
|
set-preference=You data saving preference has been set to __1__. Existing data will not be effected until you rejoin.
|
||||||
get-preference=You data saving preference is __1__. Use /set-preference to change this. Use /save-data to get a local copy of your data.
|
get-preference=You data saving preference is __1__. Use /set-preference to change this. Use /save-data to get a local copy of your data.
|
||||||
get-data=Your player data has been writen to file, location: factorio/script_output/expgaming_player_data.json
|
get-data=Your player data has been writen to file, location: factorio/script_output/expgaming_player_data.json
|
||||||
|
|||||||
@@ -210,6 +210,11 @@ disabled=disabled
|
|||||||
toggle-msg=Fast decon has been __1__
|
toggle-msg=Fast decon has been __1__
|
||||||
|
|
||||||
[bonus]
|
[bonus]
|
||||||
|
description=Get / Set the amount of bonus you receive.
|
||||||
|
arg-amount=Amount to set your bonus to, 0 will disable bonus.
|
||||||
|
set=Your bonus has been set to __1__.
|
||||||
|
get=Your bonus is __1__.
|
||||||
|
perm=You dont have enough permission to set more than __1__.
|
||||||
main-tooltip=Bonus
|
main-tooltip=Bonus
|
||||||
control-pts-a=Points available
|
control-pts-a=Points available
|
||||||
control-pts-n=Points needed
|
control-pts-n=Points needed
|
||||||
@@ -319,3 +324,17 @@ reset=Reset All
|
|||||||
toggle=Toggle Favourites
|
toggle=Toggle Favourites
|
||||||
move-up=Move Up
|
move-up=Move Up
|
||||||
move-down=Move Down
|
move-down=Move Down
|
||||||
|
|
||||||
|
[research]
|
||||||
|
msg=[color=255, 255, 255] Research completed at __1__ - [technology=__2__][/color]
|
||||||
|
inf=[color=255, 255, 255] Research completed at __1__ - [technology=__2__] - __3__[/color]
|
||||||
|
res-name=[technology=__1__] __2__
|
||||||
|
name=Name
|
||||||
|
target=Target
|
||||||
|
attempt=Attempt
|
||||||
|
difference=Diff
|
||||||
|
main-tooltip=Research GUI
|
||||||
|
|
||||||
|
[server-ups]
|
||||||
|
description=Toggle the server UPS display.
|
||||||
|
no-ext=No external source was found, cannot display server ups.
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
--[[-- Addon Lawnmower
|
|
||||||
- Adds a command that clean up biter corpse and nuclear hole
|
|
||||||
@addon Lawnmower
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
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", "Clean up biter corpse, decoratives and nuclear hole")
|
|
||||||
:add_param("range", false, "integer-range", 1, 200)
|
|
||||||
:register(function(player, range)
|
|
||||||
local tile_to_do = {}
|
|
||||||
|
|
||||||
-- Intentionally left as player.position to allow use in remote view
|
|
||||||
player.surface.destroy_decoratives{ position = player.position, radius = range }
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
player.surface.set_tiles(tile_to_do)
|
|
||||||
|
|
||||||
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 }
|
|
||||||
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_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_revive, function(event)
|
|
||||||
destroy_decoratives(event.entity)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
--[[-- Commands Module - Admin Chat
|
|
||||||
- Adds a command that allows admins to talk in a private chat
|
|
||||||
@commands Admin-Chat
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Sends a message in chat that only admins can see
|
|
||||||
-- @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_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
|
|
||||||
|
|
||||||
return Commands.success -- prevents command complete message from showing
|
|
||||||
end)
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
--[[-- Commands Module - Admin Markers
|
|
||||||
- Adds a command that creates map markers which can only be edited by admins
|
|
||||||
@commands Admin-Markers
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
||||||
|
|
||||||
local admins = {} -- Stores all players in admin marker mode
|
|
||||||
local markers = {} -- Stores all admin markers
|
|
||||||
|
|
||||||
--- Storage variables
|
|
||||||
Storage.register({
|
|
||||||
admins = admins,
|
|
||||||
markers = markers,
|
|
||||||
}, function(tbl)
|
|
||||||
admins = tbl.admins
|
|
||||||
markers = tbl.markers
|
|
||||||
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)
|
|
||||||
|
|
||||||
--- 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)
|
|
||||||
if not event.player_index then return end
|
|
||||||
local player = game.players[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)
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Listen for players leaving the game, leave admin mode to avoid unexpected admin markers
|
|
||||||
Event.add(defines.events.on_player_left_game, function(event)
|
|
||||||
if not event.player_index then return end
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
admins[player.name] = nil
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Listen for tags being removed or edited, maintain tags edited by non admins
|
|
||||||
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
|
|
||||||
local player = game.players[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)
|
|
||||||
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)
|
|
||||||
else
|
|
||||||
-- Tag was removed, remake the tag
|
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Event.add(defines.events.on_chart_tag_modified, maintain_tag)
|
|
||||||
Event.add(defines.events.on_chart_tag_removed, maintain_tag)
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
--[[-- Commands Module - Artillery
|
|
||||||
- Adds a command that help shot artillery
|
|
||||||
@commands Artillery
|
|
||||||
]]
|
|
||||||
|
|
||||||
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 function location_break(player, pos)
|
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
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) },
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- when an area is selected to add protection to the area
|
|
||||||
Selection.on_selection(SelectionArtyArea, function(event)
|
|
||||||
local area = aabb_align_expand(event.area)
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
|
|
||||||
if player == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (game.players[event.player_index].cheat_mode or location_break(player, event.area)) then
|
|
||||||
return Commands.error
|
|
||||||
end
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
local hit = {}
|
|
||||||
|
|
||||||
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
|
|
||||||
if math.sqrt(math.abs(e.position.x - pos.x) ^ 2 + math.abs(e.position.y - pos.y) ^ 2) < 6 then
|
|
||||||
skip = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
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 }
|
|
||||||
table.insert(hit, e.position)
|
|
||||||
count = count + 1
|
|
||||||
|
|
||||||
if count > 400 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
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
|
|
||||||
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
--[[-- Commands Module - Bot queue
|
|
||||||
- Adds a command that allows changing bot queue
|
|
||||||
@commands Bot Queue
|
|
||||||
]]
|
|
||||||
|
|
||||||
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-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)
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
--[[-- Commands Module - Cheat Mode
|
|
||||||
- Adds a command that allows players to enter cheat mode
|
|
||||||
@commands Cheat-Mode
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
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("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)
|
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
|
||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
--[[-- Commands Module - Clear Inventory
|
|
||||||
- Adds a command that allows admins to clear people's inventorys
|
|
||||||
@commands Clear-Inventory
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
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 inventory = player.get_main_inventory()
|
|
||||||
if not inventory then
|
|
||||||
return Commands.error{ "expcore-commands.reject-player-alive" }
|
|
||||||
end
|
|
||||||
|
|
||||||
ExpUtil.transfer_inventory_to_surface{
|
|
||||||
inventory = inventory,
|
|
||||||
surface = game.planets.nauvis.surface,
|
|
||||||
name = "iron-chest",
|
|
||||||
allow_creation = true,
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
--[[-- Commands Module - Connect
|
|
||||||
- Adds a commands that allows you to request a player move to another server
|
|
||||||
@commands Connect
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Async = require("modules/exp_util/async")
|
|
||||||
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
|
||||||
local concat = table.concat
|
|
||||||
|
|
||||||
local request_connection_async = Async.register(External.request_connection)
|
|
||||||
|
|
||||||
local function get_server_id(server)
|
|
||||||
local current_server = External.get_current_server()
|
|
||||||
local current_version = current_server.version
|
|
||||||
local servers = External.get_servers_filtered(server)
|
|
||||||
|
|
||||||
local server_names_before, server_names = {}, {}
|
|
||||||
local server_count_before, server_count = 0, 0
|
|
||||||
for next_server_id, server_details in pairs(servers) do
|
|
||||||
server_count_before = server_count_before + 1
|
|
||||||
server_names_before[server_count_before] = server_details.name
|
|
||||||
if server_details.version == current_version then
|
|
||||||
server_count = server_count + 1
|
|
||||||
server_names[server_count] = server_details.name
|
|
||||||
else
|
|
||||||
servers[next_server_id] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if server_count > 1 then
|
|
||||||
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 }
|
|
||||||
end
|
|
||||||
return true, server_id
|
|
||||||
elseif server_count_before > 0 then
|
|
||||||
return false, Commands.error{ "expcom-connect.wrong-version", concat(server_names_before, ", ") }
|
|
||||||
else
|
|
||||||
return false, Commands.error{ "expcom-connect.none-matching" }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Connect to a different server
|
|
||||||
-- @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
|
|
||||||
|
|
||||||
request_connection_async(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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
for _, player in pairs(game.connected_players) do
|
|
||||||
External.request_connection(player, server_id)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
--[[-- Commands Module - Debug
|
|
||||||
- Adds a command that opens the debug frame
|
|
||||||
@commands Debug
|
|
||||||
]]
|
|
||||||
|
|
||||||
local DebugView = require("modules.exp_legacy.modules.gui.debug.main_view") --- @dep modules.gui.debug.main_view
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
|
|
||||||
--- 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)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
--[[-- Commands Module - Enemy
|
|
||||||
- Adds a command of handling enemy
|
|
||||||
@commands Enemy
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
Commands.new_command("kill-biters", { "expcom-enemy.description-kill" }, "Kill all biters only")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:register(function(_, _)
|
|
||||||
game.forces["enemy"].kill_all_units()
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
Commands.new_command("remove-biters", { "expcom-enemy.description-remove" }, "Remove biters and prevent generation")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:add_param("surface", true, "surface")
|
|
||||||
:set_defaults{ surface = function(player)
|
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
|
||||||
return player.surface
|
|
||||||
end }
|
|
||||||
:register(function(_, surface)
|
|
||||||
for _, entity in pairs(surface.find_entities_filtered{ force = "enemy" }) do
|
|
||||||
entity.destroy()
|
|
||||||
end
|
|
||||||
|
|
||||||
surface.map_gen_settings.autoplace_controls["enemy-base"].size = "none"
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
--[[-- Commands Module - Find
|
|
||||||
- Adds a command that zooms in on the given player
|
|
||||||
@commands Find
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Find a player on your map.
|
|
||||||
-- @command find-on-map
|
|
||||||
-- @tparam LuaPlayer the player to find on the map
|
|
||||||
Commands.new_command("find-on-map", { "expcom-find.description" }, "Find a player on your map.")
|
|
||||||
:add_param("player", false, "player-online")
|
|
||||||
:add_alias("find", "zoom-to")
|
|
||||||
:register(function(player, action_player)
|
|
||||||
local position = action_player.physical_position
|
|
||||||
player.zoom_to_world(position, 1.75)
|
|
||||||
return Commands.success -- prevents command complete message from showing
|
|
||||||
end)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
--[[-- Commands Module - Toggle Friendly Fire
|
|
||||||
- Adds a command that toggle all friendly fire
|
|
||||||
@commands Toggle Friendly Fire
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
-- For Modded Server Use
|
|
||||||
Commands.new_command("toggle-friendly-fire", { "expcom-ff.description" }, "Toggle friendly fire")
|
|
||||||
:add_param("force", true, "force")
|
|
||||||
:set_defaults{ force = function(player)
|
|
||||||
return player.force
|
|
||||||
end }
|
|
||||||
:register(function(player, force)
|
|
||||||
force.friendly_fire = not force.friendly_fire
|
|
||||||
game.print{ "expcom-ff.ff", player.name, force.friendly_fire }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
--[[-- Commands Module - Help
|
|
||||||
- Adds a better help command that allows searching of descriotions and names
|
|
||||||
@commands Help
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
local results_per_page = 5
|
|
||||||
|
|
||||||
local search_cache = {}
|
|
||||||
Storage.register(search_cache, function(tbl)
|
|
||||||
search_cache = tbl
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Searches for a keyword in all commands you are allowed to use.
|
|
||||||
-- @command chelp
|
|
||||||
-- @tparam string keyword the keyword that will be looked for
|
|
||||||
-- @tparam number page the page of help to view, must be in range of pages
|
|
||||||
Commands.new_command("search-help", { "expcom-chelp.description" }, "Searches for a keyword in all commands you are allowed to use.")
|
|
||||||
:add_alias("chelp", "shelp", "commands")
|
|
||||||
:add_param("keyword", true)
|
|
||||||
:add_param("page", true, "integer")
|
|
||||||
:set_defaults{ keyword = "", page = 1 }
|
|
||||||
:register(function(player, keyword, page)
|
|
||||||
local player_index = player and player.index or 0
|
|
||||||
-- if keyword is a number then treat it as page number
|
|
||||||
if tonumber(keyword) then
|
|
||||||
--- @diagnostic disable-next-line: param-type-mismatch
|
|
||||||
page = math.floor(tonumber(keyword))
|
|
||||||
keyword = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
-- gets a value for pages, might have result in cache
|
|
||||||
local pages
|
|
||||||
local found = 0
|
|
||||||
|
|
||||||
if search_cache[player_index] and search_cache[player_index].keyword == keyword:lower() then
|
|
||||||
pages = search_cache[player_index].pages
|
|
||||||
found = search_cache[player_index].found
|
|
||||||
else
|
|
||||||
pages = { {} }
|
|
||||||
local current_page = 1
|
|
||||||
local page_count = 0
|
|
||||||
local commands = Commands.search(keyword, player)
|
|
||||||
-- loops other all commands returned by search, includes game commands
|
|
||||||
for _, command_data in pairs(commands) do
|
|
||||||
-- if the number of results if greater than the number already added then it moves onto a new page
|
|
||||||
if page_count >= results_per_page then
|
|
||||||
page_count = 0
|
|
||||||
current_page = current_page + 1
|
|
||||||
table.insert(pages, {})
|
|
||||||
end
|
|
||||||
-- adds the new command to the page
|
|
||||||
page_count = page_count + 1
|
|
||||||
found = found + 1
|
|
||||||
local alias_format = #command_data.aliases > 0 and { "expcom-chelp.alias", table.concat(command_data.aliases, ", ") } or ""
|
|
||||||
table.insert(pages[current_page], {
|
|
||||||
"expcom-chelp.format",
|
|
||||||
command_data.name,
|
|
||||||
command_data.description,
|
|
||||||
command_data.help,
|
|
||||||
alias_format,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- adds the result to the cache
|
|
||||||
search_cache[player_index] = {
|
|
||||||
keyword = keyword:lower(),
|
|
||||||
pages = pages,
|
|
||||||
found = found,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- print the requested page
|
|
||||||
keyword = keyword == "" and "<all>" or keyword
|
|
||||||
Commands.print({ "expcom-chelp.title", keyword }, "cyan")
|
|
||||||
|
|
||||||
if pages[page] then
|
|
||||||
for _, command in pairs(pages[page]) do
|
|
||||||
Commands.print(command)
|
|
||||||
end
|
|
||||||
|
|
||||||
Commands.print({ "expcom-chelp.footer", found, page, #pages }, "cyan")
|
|
||||||
else
|
|
||||||
Commands.print({ "expcom-chelp.footer", found, page, #pages }, "cyan")
|
|
||||||
return Commands.error{ "expcom-chelp.out-of-range", page }
|
|
||||||
end
|
|
||||||
-- blocks command complete message
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- way to access global
|
|
||||||
return search_cache
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
--[[-- Commands Module - Home
|
|
||||||
- Adds a command that allows setting and teleporting to your home position
|
|
||||||
@commands Home
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
local homes = {}
|
|
||||||
Storage.register(homes, function(tbl)
|
|
||||||
homes = tbl
|
|
||||||
end)
|
|
||||||
|
|
||||||
local function teleport(player, position)
|
|
||||||
local surface = player.physical_surface
|
|
||||||
local pos = surface.find_non_colliding_position("character", position, 32, 1)
|
|
||||||
if not position then return false end
|
|
||||||
if player.driving then player.driving = false end -- kicks a player out a vehicle if in one
|
|
||||||
player.teleport(pos, surface)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local function floor_pos(position)
|
|
||||||
return {
|
|
||||||
x = math.floor(position.x),
|
|
||||||
y = math.floor(position.y),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Teleports you to your home location
|
|
||||||
-- @command home
|
|
||||||
Commands.new_command("home", { "expcom-home.description-home" }, "Teleports you to your home location")
|
|
||||||
:register(function(player)
|
|
||||||
local home = homes[player.index]
|
|
||||||
if not home or not home[1] then
|
|
||||||
return Commands.error{ "expcom-home.no-home" }
|
|
||||||
end
|
|
||||||
local rtn = floor_pos(player.physical_position)
|
|
||||||
teleport(player, home[1])
|
|
||||||
home[2] = rtn
|
|
||||||
Commands.print{ "expcom-home.return-set", rtn.x, rtn.y }
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Sets your home location to your current position
|
|
||||||
-- @command home-set
|
|
||||||
Commands.new_command("home-set", { "expcom-home.description-home-set" }, "Sets your home location to your current position")
|
|
||||||
:register(function(player)
|
|
||||||
local home = homes[player.index]
|
|
||||||
if not home then
|
|
||||||
home = {}
|
|
||||||
homes[player.index] = home
|
|
||||||
end
|
|
||||||
local pos = floor_pos(player.physical_position)
|
|
||||||
home[1] = pos
|
|
||||||
Commands.print{ "expcom-home.home-set", pos.x, pos.y }
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Returns your current home location
|
|
||||||
-- @command home-get
|
|
||||||
Commands.new_command("home-get", { "expcom-home.description-home-get" }, "Returns your current home location")
|
|
||||||
:register(function(player)
|
|
||||||
local home = homes[player.index]
|
|
||||||
if not home or not home[1] then
|
|
||||||
return Commands.error{ "expcom-home.no-home" }
|
|
||||||
end
|
|
||||||
local pos = home[1]
|
|
||||||
Commands.print{ "expcom-home.home-get", pos.x, pos.y }
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Teleports you to previous location
|
|
||||||
-- @command return
|
|
||||||
Commands.new_command("return", { "expcom-home.description-return" }, "Teleports you to previous location")
|
|
||||||
:register(function(player)
|
|
||||||
local home = homes[player.index]
|
|
||||||
if not home or not home[2] then
|
|
||||||
return Commands.error{ "expcom-home.no-return" }
|
|
||||||
end
|
|
||||||
local rtn = floor_pos(player.physical_position)
|
|
||||||
teleport(player, home[2])
|
|
||||||
home[2] = rtn
|
|
||||||
Commands.print{ "expcom-home.return-set", rtn.x, rtn.y }
|
|
||||||
end)
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
--[[-- Commands Module - Interface
|
|
||||||
- Adds a command that acts as a direct link to the the active softmod, for debug use
|
|
||||||
@commands Interface
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
|
|
||||||
-- modules that are loaded into the interface env to be accessed
|
|
||||||
local interface_modules = {
|
|
||||||
["Commands"] = Commands,
|
|
||||||
["output"] = Commands.print,
|
|
||||||
["Group"] = "modules.exp_legacy.expcore.permission_groups",
|
|
||||||
["Roles"] = "modules.exp_legacy.expcore.roles",
|
|
||||||
["Gui"] = "modules.exp_legacy.expcore.gui",
|
|
||||||
["Datastore"] = "modules.exp_legacy.expcore.datastore",
|
|
||||||
["External"] = "modules.exp_legacy.expcore.external",
|
|
||||||
}
|
|
||||||
|
|
||||||
-- loads all the modules given in the above table
|
|
||||||
for key, value in pairs(interface_modules) do
|
|
||||||
if type(value) == "string" then
|
|
||||||
interface_modules[key] = ExpUtil.optional_require(value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local interface_env = {} -- used as a persistent sandbox for interface commands
|
|
||||||
local interface_callbacks = {} -- saves callbacks which can load new values per use
|
|
||||||
Storage.register(interface_env, function(tbl)
|
|
||||||
interface_env = tbl
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Adds a static module that can be accessed with the interface
|
|
||||||
-- @tparam string name The name that the value is assigned to
|
|
||||||
-- @tparam any value The value that will be accessible in the interface env
|
|
||||||
-- callback param - player: LuaPlayer - the player who used the command
|
|
||||||
local function add_interface_module(name, value)
|
|
||||||
interface_modules[name] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Adds a dynamic value that is calculated when the interface is used
|
|
||||||
-- @tparam string name The name that the value is assigned to
|
|
||||||
-- @tparam function callback The function that will be called to get the value
|
|
||||||
local function add_interface_callback(name, callback)
|
|
||||||
if type(callback) == "function" then
|
|
||||||
interface_callbacks[name] = callback
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Internal, this is a meta function for __index when self[key] is nil
|
|
||||||
local function get_index(_, key)
|
|
||||||
if interface_env[key] then
|
|
||||||
return interface_env[key]
|
|
||||||
elseif interface_modules[key] then
|
|
||||||
return interface_modules[key]
|
|
||||||
elseif _G[key] then
|
|
||||||
return _G[key]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sends an invocation to be ran and returns the result.
|
|
||||||
-- @command interface
|
|
||||||
-- @tparam string invocation the command that will be run
|
|
||||||
Commands.new_command("interface", { "expcom-interface.description" }, "Sends an invocation to be ran and returns the result.")
|
|
||||||
:add_param("invocation", false)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:register(function(player, invocation)
|
|
||||||
-- If the invocation has no white space then prepend return to it
|
|
||||||
if not invocation:find("%s") and not invocation:find("return") then
|
|
||||||
invocation = "return " .. invocation
|
|
||||||
end
|
|
||||||
|
|
||||||
-- _env will be the new _ENV that the invocation will run inside of
|
|
||||||
local _env = setmetatable({}, {
|
|
||||||
__index = get_index,
|
|
||||||
__newindex = interface_env,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- If the command is ran by a player then load the dynamic values
|
|
||||||
if player then
|
|
||||||
for name, callback in pairs(interface_callbacks) do
|
|
||||||
local _, rtn = pcall(callback, player)
|
|
||||||
rawset(_env, name, rtn)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Compile the invocation with the custom _env value
|
|
||||||
local invocation_func, compile_error = load(invocation, "interface", nil, _env)
|
|
||||||
if compile_error then return Commands.error(compile_error) end
|
|
||||||
--- @cast invocation_func -nil
|
|
||||||
|
|
||||||
-- Run the invocation
|
|
||||||
local success, rtn = pcall(invocation_func)
|
|
||||||
if not success then
|
|
||||||
local err = rtn:gsub("%.%.%..-/temp/currently%-playing", "")
|
|
||||||
return Commands.error(err)
|
|
||||||
end
|
|
||||||
return Commands.success(rtn)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Adds some basic callbacks for the interface
|
|
||||||
add_interface_callback("player", function(player) return player end)
|
|
||||||
add_interface_callback("surface", function(player) return player.surface end)
|
|
||||||
add_interface_callback("force", function(player) return player.force end)
|
|
||||||
add_interface_callback("position", function(player) return player.position end)
|
|
||||||
add_interface_callback("entity", function(player) return player.selected end)
|
|
||||||
add_interface_callback("tile", function(player) return player.surface.get_tile(player.position) end)
|
|
||||||
|
|
||||||
-- Module Return
|
|
||||||
return {
|
|
||||||
add_interface_module = add_interface_module,
|
|
||||||
add_interface_callback = add_interface_callback,
|
|
||||||
interface_env = interface_env,
|
|
||||||
clean_stack_trace = function(str) return str:gsub("%.%.%..-/temp/currently%-playing", "") end,
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
--[[-- Commands Module - Jail
|
|
||||||
- Adds a commands that allow admins to jail and unjail
|
|
||||||
@commands Jail
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
|
||||||
|
|
||||||
--- Puts a player into jail and removes all other roles.
|
|
||||||
-- @command jail
|
|
||||||
-- @tparam LuaPlayer player the player that will be jailed
|
|
||||||
-- @tparam[opt] string reason the reason why the player is being jailed
|
|
||||||
Commands.new_command("jail", { "expcom-jail.description-jail" }, "Puts a player into jail and removes all other roles.")
|
|
||||||
:add_param("player", false, "player-role")
|
|
||||||
:add_param("reason", true)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, action_player, reason)
|
|
||||||
reason = reason or "Non Given."
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
local player_name = player and player.name or "<server>"
|
|
||||||
if Jail.jail_player(action_player, player_name, reason) then
|
|
||||||
game.print{ "expcom-jail.give", action_player_name_color, by_player_name_color, reason }
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcom-jail.already-jailed", action_player_name_color }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Removes a player from jail.
|
|
||||||
-- @command unjail
|
|
||||||
-- @tparam LuaPlayer the player that will be unjailed
|
|
||||||
Commands.new_command("unjail", { "expcom-jail.description-unjail" }, "Removes a player from jail.")
|
|
||||||
:add_param("player", false, "player-role")
|
|
||||||
:add_alias("clear-jail", "remove-jail")
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, action_player)
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
local player_name = player and player.name or "<server>"
|
|
||||||
if Jail.unjail_player(action_player, player_name) then
|
|
||||||
game.print{ "expcom-jail.remove", action_player_name_color, by_player_name_color }
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcom-jail.not-jailed", action_player_name_color }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
--[[-- Commands Module - Kill
|
|
||||||
- Adds a command that allows players to kill them selfs and others
|
|
||||||
@commands Kill
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
|
||||||
|
|
||||||
--- Kills yourself or another player.
|
|
||||||
-- @command kill
|
|
||||||
-- @tparam[opt=self] LuaPlayer player the player to kill, must be alive to be valid
|
|
||||||
Commands.new_command("kill", { "expcom-kill.description" }, "Kills yourself or another player.")
|
|
||||||
:add_param("player", true, "player-role-alive")
|
|
||||||
:set_defaults{ player = function(player)
|
|
||||||
-- default is the player unless they are dead
|
|
||||||
if player.character and player.character.health > 0 then
|
|
||||||
return player
|
|
||||||
end
|
|
||||||
end }
|
|
||||||
:register(function(player, action_player)
|
|
||||||
if not action_player then
|
|
||||||
-- can only be nil if no player given and the user is dead
|
|
||||||
return Commands.error{ "expcom-kill.already-dead" }
|
|
||||||
end
|
|
||||||
if player == action_player then
|
|
||||||
action_player.character.die()
|
|
||||||
elseif Roles.player_allowed(player, "command/kill/always") then
|
|
||||||
action_player.character.die()
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcore-commands.unauthorized" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
--[[-- Commands Module - Last location
|
|
||||||
- Adds a command that will return the last location of a player
|
|
||||||
@commands LastLocation
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Get the last location of a player.
|
|
||||||
-- @command last-location
|
|
||||||
-- @tparam LuaPlayer player the player that you want a location of
|
|
||||||
Commands.new_command("last-location", { "expcom-lastlocation.description" }, "Sends you the last location of a player")
|
|
||||||
:add_alias("location")
|
|
||||||
:add_param("player", false, "player")
|
|
||||||
:register(function(_, action_player)
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
return Commands.success{ "expcom-lastlocation.response", action_player_name_color, string.format("%.1f", action_player.physical_position.x), string.format("%.1f", action_player.physical_position.y) }
|
|
||||||
end)
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
--[[-- Commands Module - Me
|
|
||||||
- Adds a command that adds * around your message in the chat
|
|
||||||
@commands Me
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
|
|
||||||
--- Sends an action message in the chat
|
|
||||||
-- @command me
|
|
||||||
-- @tparam string action the action that follows your name in chat
|
|
||||||
Commands.new_command("me", { "expcom-me.description" }, "Sends an action message in the chat")
|
|
||||||
:add_param("action", false)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, action)
|
|
||||||
local player_name = player and player.name or "<Server>"
|
|
||||||
game.print(string.format("* %s %s *", player_name, action), player.chat_color)
|
|
||||||
end)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
--[[-- Commands Module - Pollution Handle
|
|
||||||
- Adds a command that allows modifying pollution
|
|
||||||
@commands Pollution Handle
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
Commands.new_command("pollution-clear", { "expcom-pol.description-clr" }, "Clear pollution")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:add_alias("pol-clr")
|
|
||||||
:add_param("surface", true, "surface")
|
|
||||||
:set_defaults{ surface = function(player)
|
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
|
||||||
return player.surface
|
|
||||||
end }
|
|
||||||
:register(function(player, surface)
|
|
||||||
surface.clear_pollution()
|
|
||||||
game.print{ "expcom-pol.clr", player.name }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
Commands.new_command("pollution-off", { "expcom-pol.description-off" }, "Disable pollution")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:add_alias("pol-off")
|
|
||||||
:register(function(player)
|
|
||||||
game.map_settings.pollution.enabled = false
|
|
||||||
|
|
||||||
for _, v in pairs(game.surfaces) do
|
|
||||||
v.clear_pollution()
|
|
||||||
end
|
|
||||||
|
|
||||||
game.print{ "expcom-pol.off", player.name }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
local Commands = require("modules.exp_legacy.expcore.commands")
|
|
||||||
|
|
||||||
local function Modules(moduleInventory) -- returns the multiplier of the modules
|
|
||||||
local effect1 = moduleInventory.get_item_count("productivity-module") -- type 1
|
|
||||||
local effect2 = moduleInventory.get_item_count("productivity-module-2") -- type 2
|
|
||||||
local effect3 = moduleInventory.get_item_count("productivity-module-3") -- type 3
|
|
||||||
|
|
||||||
local multi = effect1 * 4 + effect2 * 6 + effect3 * 10
|
|
||||||
return multi / 100 + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local function AmountOfMachines(itemsPerSecond, output)
|
|
||||||
if (itemsPerSecond) then
|
|
||||||
return itemsPerSecond / output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Commands.new_command("ratio", { "expcom-ratio.description" },
|
|
||||||
"This command will give the input and output ratios of the selected machine. Use the parameter for calculating the machines needed for that amount of items per second.")
|
|
||||||
:add_param("itemsPerSecond", true, "number")
|
|
||||||
:register(function(player, itemsPerSecond)
|
|
||||||
local machine = player.selected -- selected machine
|
|
||||||
|
|
||||||
if not machine then -- nil check
|
|
||||||
return Commands.error{ "expcom-ratio.notSelecting" }
|
|
||||||
end
|
|
||||||
|
|
||||||
if machine.type ~= "assembling-machine" and machine.type ~= "furnace" then
|
|
||||||
return Commands.error{ "expcom-ratio.notSelecting" }
|
|
||||||
end
|
|
||||||
|
|
||||||
local recipe = machine.get_recipe() -- recipe
|
|
||||||
|
|
||||||
if not recipe then -- nil check
|
|
||||||
return Commands.error{ "expcom-ratio.notSelecting" }
|
|
||||||
end
|
|
||||||
|
|
||||||
local items = recipe.ingredients -- items in that recipe
|
|
||||||
local products = recipe.products -- output items
|
|
||||||
local amountOfMachines
|
|
||||||
local moduleInventory = machine.get_module_inventory() -- the module Inventory of the machine
|
|
||||||
local multi = Modules(moduleInventory) -- function for the productively modals
|
|
||||||
|
|
||||||
if itemsPerSecond then
|
|
||||||
amountOfMachines = math.ceil(AmountOfMachines(itemsPerSecond, 1 / recipe.energy * machine.crafting_speed * products[1].amount * multi)) -- amount of machines
|
|
||||||
end
|
|
||||||
|
|
||||||
if not amountOfMachines then
|
|
||||||
amountOfMachines = 1 -- set to 1 to make it not nil
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------items----------------------------
|
|
||||||
for i, item in ipairs(items) do
|
|
||||||
local sprite -- string to make the icon work either fluid ore item
|
|
||||||
|
|
||||||
if item.type == "item" then
|
|
||||||
sprite = "expcom-ratio.item-in"
|
|
||||||
else
|
|
||||||
sprite = "expcom-ratio.fluid-in"
|
|
||||||
end
|
|
||||||
|
|
||||||
local ips = item.amount / recipe.energy * machine.crafting_speed * amountOfMachines -- math on the items/fluids per second
|
|
||||||
Commands.print{ sprite, math.round(ips, 3), item.name } -- full string
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------products----------------------------
|
|
||||||
for i, product in ipairs(products) do
|
|
||||||
local sprite -- string to make the icon work either fluid ore item
|
|
||||||
|
|
||||||
if product.type == "item" then
|
|
||||||
sprite = "expcom-ratio.item-out"
|
|
||||||
else
|
|
||||||
sprite = "expcom-ratio.fluid-out"
|
|
||||||
end
|
|
||||||
|
|
||||||
local output = 1 / recipe.energy * machine.crafting_speed * product.amount * multi -- math on the outputs per second
|
|
||||||
Commands.print{ sprite, math.round(output * amountOfMachines, 3), product.name } -- full string
|
|
||||||
end
|
|
||||||
|
|
||||||
if amountOfMachines ~= 1 then
|
|
||||||
Commands.print{ "expcom-ratio.machines", amountOfMachines }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
--[[-- Commands Module - Repair
|
|
||||||
- Adds a command that allows an admin to repair and revive a large area
|
|
||||||
@commands Repair
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local config = require("modules.exp_legacy.config.repair") --- @dep config.repair
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
local max_time_to_live = 4294967295 -- unit32 max
|
|
||||||
--- Repairs entities on your force around you
|
|
||||||
-- @command repair
|
|
||||||
-- @tparam number range the range to repair stuff in, there is a max limit to this
|
|
||||||
Commands.new_command("repair", { "expcom-repair.description" }, "Repairs entities on your force around you")
|
|
||||||
:add_param("range", false, "integer-range", 1, config.max_range)
|
|
||||||
:register(function(player, range)
|
|
||||||
local revive_count = 0
|
|
||||||
local heal_count = 0
|
|
||||||
local range2 = range ^ 2
|
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
|
||||||
local surface = player.surface
|
|
||||||
-- Intentionally left as player.position to allow use in remote view
|
|
||||||
local center = player.position
|
|
||||||
local area = { { x = center.x - range, y = center.y - range }, { x = center.x + range, y = center.y + range } }
|
|
||||||
if config.allow_ghost_revive then
|
|
||||||
local ghosts = surface.find_entities_filtered{ area = area, type = "entity-ghost", force = player.force }
|
|
||||||
for _, ghost in pairs(ghosts) do
|
|
||||||
if ghost.valid then
|
|
||||||
local x = ghost.position.x - center.x
|
|
||||||
local y = ghost.position.y - center.y
|
|
||||||
if x ^ 2 + y ^ 2 <= range2 then
|
|
||||||
if config.allow_blueprint_repair or ghost.time_to_live ~= max_time_to_live then
|
|
||||||
revive_count = revive_count + 1
|
|
||||||
if not config.disallow[ghost.ghost_name] then ghost.revive() end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if config.allow_heal_entities then
|
|
||||||
local entities = surface.find_entities_filtered{ area = area, force = player.force }
|
|
||||||
for _, entity in pairs(entities) do
|
|
||||||
if entity.valid then
|
|
||||||
local x = entity.position.x - center.x
|
|
||||||
local y = entity.position.y - center.y
|
|
||||||
if entity.health and entity.get_health_ratio() ~= 1 and x ^ 2 + y ^ 2 <= range2 then
|
|
||||||
heal_count = heal_count + 1
|
|
||||||
entity.health = max_time_to_live
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return Commands.success{ "expcom-repair.result", revive_count, heal_count }
|
|
||||||
end)
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
--[[-- Commands Module - Reports
|
|
||||||
- Adds a commands that allow players to report other players
|
|
||||||
@commands Reports
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Print a message to all players who match the value of admin
|
|
||||||
local function print_to_players(admin, message)
|
|
||||||
for _, player in ipairs(game.connected_players) do
|
|
||||||
if player.admin == admin then
|
|
||||||
player.print(message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Reports a player and notifies moderators
|
|
||||||
-- @command report
|
|
||||||
-- @tparam LuaPlayer player the player to report, some players are immune
|
|
||||||
-- @tparam string reason the reason the player is being reported
|
|
||||||
Commands.new_command("report", { "expcom-report.description-report" }, "Reports a player and notifies moderators")
|
|
||||||
:add_param("player", false, function(input, player, reject)
|
|
||||||
input = Commands.parse("player", input, player, reject)
|
|
||||||
if not input then return end
|
|
||||||
if Roles.player_has_flag(input, "report-immune") then
|
|
||||||
return reject{ "expcom-report.player-immune" }
|
|
||||||
elseif player == input then
|
|
||||||
return reject{ "expcom-report.self-report" }
|
|
||||||
else
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
:add_param("reason", false)
|
|
||||||
:add_alias("report-player")
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, action_player, reason)
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
if Reports.report_player(action_player, player.name, reason) then
|
|
||||||
print_to_players(false, { "expcom-report.non-admin", action_player_name_color, reason })
|
|
||||||
print_to_players(true, { "expcom-report.admin", action_player_name_color, by_player_name_color, reason })
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcom-report.already-reported" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Gets a list of all reports that a player has on them. If no player then lists all players and the number of reports on them.
|
|
||||||
-- @command get-reports
|
|
||||||
-- @tparam LuaPlayer player the player to get the report for
|
|
||||||
Commands.new_command("get-reports", { "expcom-report.description-get-reports" },
|
|
||||||
"Gets a list of all reports that a player has on them. If no player then lists all players and the number of reports on them.")
|
|
||||||
:add_param("player", true, "player")
|
|
||||||
:add_alias("reports", "list-reports")
|
|
||||||
:register(function(_, player)
|
|
||||||
if player then
|
|
||||||
local reports = Reports.get_reports(player)
|
|
||||||
local player_name_color = format_player_name(player)
|
|
||||||
Commands.print{ "expcom-report.player-report-title", player_name_color }
|
|
||||||
for player_name, reason in pairs(reports) do
|
|
||||||
local by_player_name_color = format_player_name(player_name)
|
|
||||||
Commands.print{ "expcom-report.list", by_player_name_color, reason }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local user_reports = Reports.user_reports
|
|
||||||
Commands.print{ "expcom-report.player-count-title" }
|
|
||||||
for player_name in pairs(user_reports) do
|
|
||||||
local player_name_color = format_player_name(player_name)
|
|
||||||
local report_count = Reports.count_reports(player_name)
|
|
||||||
Commands.print{ "expcom-report.list", player_name_color, report_count }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Clears all reports from a player or just the report from one player.
|
|
||||||
-- @command clear-reports
|
|
||||||
-- @tparam LuaPlayer player the player to clear the report(s) from
|
|
||||||
-- @tparam[opt=all] LuaPlayer from-player remove only the report made by this player
|
|
||||||
Commands.new_command("clear-reports", { "expcom-report.description-clear-reports" }, "Clears all reports from a player or just the report from one player.")
|
|
||||||
:add_param("player", false, "player")
|
|
||||||
:add_param("from-player", true, "player")
|
|
||||||
:register(function(player, action_player, from_player)
|
|
||||||
if from_player then
|
|
||||||
if not Reports.remove_report(action_player, from_player.name, player.name) then
|
|
||||||
return Commands.error{ "expcom-report.not-reported" }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not Reports.remove_all(action_player, player.name) then
|
|
||||||
return Commands.error{ "expcom-report.not-reported" }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
game.print{ "expcom-report.removed", action_player_name_color, by_player_name_color }
|
|
||||||
end)
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
local Storage = require("modules/exp_util/storage")
|
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local config = require("modules.exp_legacy.config.research") --- @dep config.research
|
|
||||||
|
|
||||||
local research = {}
|
|
||||||
Storage.register(research, function(tbl)
|
|
||||||
research = tbl
|
|
||||||
end)
|
|
||||||
|
|
||||||
local function res_queue(force, by_script)
|
|
||||||
local res_q = force.research_queue
|
|
||||||
local res = force.technologies["mining-productivity-4"]
|
|
||||||
|
|
||||||
if #res_q < config.queue_amount then
|
|
||||||
for i = 1, config.queue_amount - #res_q do
|
|
||||||
force.add_research(res)
|
|
||||||
|
|
||||||
if not (by_script) then
|
|
||||||
game.print{ "expcom-res.inf-q", res.name, res.level + i }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Commands.new_command("auto-research", { "expcom-res.description-ares" }, "Automatically queue up research")
|
|
||||||
:add_alias("ares")
|
|
||||||
:register(function(player)
|
|
||||||
research.res_queue_enable = not research.res_queue_enable
|
|
||||||
|
|
||||||
if research.res_queue_enable then
|
|
||||||
res_queue(player.force, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
game.print{ "expcom-res.res", player.name, research.res_queue_enable }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
Event.add(defines.events.on_research_finished, function(event)
|
|
||||||
if research.res_queue_enable then
|
|
||||||
if event.research.force.rockets_launched > 0 and event.research.force.technologies["mining-productivity-4"].level > 4 then
|
|
||||||
res_queue(event.research.force, event.by_script)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
--[[-- Commands Module - Roles
|
|
||||||
- Adds a commands that allow interaction with the role system
|
|
||||||
@commands Roles
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
||||||
local Colours = require("modules/exp_util/include/color")
|
|
||||||
local format_player_name, format_color = ExpUtil.format_player_name_locale, ExpUtil.format_rich_text_color
|
|
||||||
|
|
||||||
--- Assigns a role to a player
|
|
||||||
-- @command assign-role
|
|
||||||
-- @tparam LuaPlayer player the player to assign the role to
|
|
||||||
-- @tparam string role the name of the role to assign to the player, supports auto complete after enter
|
|
||||||
Commands.new_command("assign-role", { "expcom-roles.description-assign-role" }, "Assigns a role to a player")
|
|
||||||
:add_param("player", false, "player-role")
|
|
||||||
:add_param("role", false, "role")
|
|
||||||
:set_flag("admin-only")
|
|
||||||
:add_alias("rpromote", "assign", "role", "add-role")
|
|
||||||
:register(function(player, action_player, role)
|
|
||||||
local player_highest = Roles.get_player_highest_role(player)
|
|
||||||
|
|
||||||
if player_highest.index < role.index then
|
|
||||||
Roles.assign_player(action_player, role, player.name)
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcom-roles.higher-role" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Unassigns a role from a player
|
|
||||||
-- @command unassign-role
|
|
||||||
-- @tparam LuaPlayer player the player to unassign the role from
|
|
||||||
-- @tparam string role the name of the role to unassign from the player, supports auto complete after enter
|
|
||||||
Commands.new_command("unassign-role", { "expcom-roles.description-unassign-role" }, "Unassigns a role from a player")
|
|
||||||
:add_param("player", false, "player-role")
|
|
||||||
:add_param("role", false, "role")
|
|
||||||
:set_flag("admin-only")
|
|
||||||
:add_alias("rdemote", "unassign", "rerole", "remove-role")
|
|
||||||
:register(function(player, action_player, role)
|
|
||||||
local player_highest = Roles.get_player_highest_role(player)
|
|
||||||
|
|
||||||
if player_highest.index < role.index then
|
|
||||||
Roles.unassign_player(action_player, role, player.name)
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcom-roles.higher-role" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Lists all roles in they correct order
|
|
||||||
-- @command list-roles
|
|
||||||
-- @tparam[opt=all] LuaPlayer player list only the roles which this player has
|
|
||||||
Commands.new_command("list-roles", { "expcom-roles.description-list-roles" }, "Lists all roles in they correct order")
|
|
||||||
:add_param("player", true, "player")
|
|
||||||
:add_alias("lsroles", "roles")
|
|
||||||
:register(function(_, player)
|
|
||||||
local roles = Roles.config.order
|
|
||||||
local message = { "expcom-roles.list" }
|
|
||||||
|
|
||||||
if player then
|
|
||||||
roles = Roles.get_player_roles(player)
|
|
||||||
end
|
|
||||||
|
|
||||||
for index, role in pairs(roles) do
|
|
||||||
role = Roles.get_role_from_any(role)
|
|
||||||
local colour = role.custom_color or Colours.white
|
|
||||||
local role_name = format_color(role.name, colour)
|
|
||||||
if index == 1 then
|
|
||||||
message = { "expcom-roles.list", role_name }
|
|
||||||
if player then
|
|
||||||
local player_name_colour = format_player_name(player)
|
|
||||||
message = { "expcom-roles.list-player", player_name_colour, role_name }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
message = { "expcom-roles.list-element", message, role_name }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return Commands.success(message)
|
|
||||||
end)
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
--[[-- Commands Module - Inventory Search
|
|
||||||
- Adds commands that will search all players inventories for an item
|
|
||||||
@commands InventorySearch
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local format_number = require("util").format_number --- @dep util
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Input parse for items by name
|
|
||||||
local function item_parse(input, _, reject)
|
|
||||||
if input == nil then return end
|
|
||||||
local lower_input = input:lower():gsub(" ", "-")
|
|
||||||
|
|
||||||
-- Simple Case - internal name is given
|
|
||||||
local item = prototypes.item[lower_input]
|
|
||||||
if item then return item end
|
|
||||||
|
|
||||||
-- Second Case - rich text is given
|
|
||||||
local item_name = input:match("%[item=([0-9a-z-]+)%]")
|
|
||||||
item = prototypes.item[item_name]
|
|
||||||
if item then return item end
|
|
||||||
|
|
||||||
-- No item found, we do not attempt to search all prototypes as this will be expensive
|
|
||||||
return reject{ "expcom-inv-search.reject-item", lower_input }
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Search all players for this item
|
|
||||||
local function search_players(players, item)
|
|
||||||
local head = 1
|
|
||||||
local found = {}
|
|
||||||
|
|
||||||
-- Check the item count of all players
|
|
||||||
for _, player in pairs(players) do
|
|
||||||
local item_count = player.get_item_count(item.name)
|
|
||||||
if item_count > 0 then
|
|
||||||
-- Add the player to the array as they have the item
|
|
||||||
found[head] = { player = player, count = item_count, online_time = player.online_time }
|
|
||||||
head = head + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return found
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Custom sort function which only retains 5 greatest values
|
|
||||||
local function sort_players(players, func)
|
|
||||||
local sorted = {}
|
|
||||||
local values = {}
|
|
||||||
local threshold = nil
|
|
||||||
|
|
||||||
-- Loop over all provided players
|
|
||||||
for index, player in ipairs(players) do
|
|
||||||
local value = func(player)
|
|
||||||
-- Check if the item will make the top 5 elements
|
|
||||||
if index <= 5 or value > threshold then
|
|
||||||
local inserted = false
|
|
||||||
values[player] = value
|
|
||||||
-- Find where in the top 5 to insert the element
|
|
||||||
for next_index, next_player in ipairs(sorted) do
|
|
||||||
if value > values[next_player] then
|
|
||||||
table.insert(sorted, next_index, player)
|
|
||||||
inserted = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Insert the element, this can only be called when index <= 5
|
|
||||||
if not inserted then
|
|
||||||
sorted[#sorted + 1] = player
|
|
||||||
end
|
|
||||||
-- Update the threshold
|
|
||||||
if sorted[6] then
|
|
||||||
threshold = values[sorted[5]]
|
|
||||||
values[sorted[6]] = nil
|
|
||||||
sorted[6] = nil
|
|
||||||
else
|
|
||||||
threshold = values[sorted[#sorted]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return sorted
|
|
||||||
end
|
|
||||||
|
|
||||||
local display_players_time_format = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true }
|
|
||||||
|
|
||||||
--- Display to the player the top players which were found
|
|
||||||
local function display_players(player, players, item)
|
|
||||||
player.print{ "expcom-inv-search.results-heading", item.name }
|
|
||||||
for index, data in ipairs(players) do
|
|
||||||
local player_name_color = format_player_name(data.player)
|
|
||||||
local amount = format_number(data.count)
|
|
||||||
local time = display_players_time_format(data.online_time)
|
|
||||||
player.print{ "expcom-inv-search.results-item", index, player_name_color, amount, time }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the amount of an item a player has
|
|
||||||
local function amount_sort(data)
|
|
||||||
return data.count
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get a list of players sorted by the quantity of an item in their inventory
|
|
||||||
-- @command search-amount
|
|
||||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
|
||||||
Commands.new_command("search-amount", { "expcom-inv-search.description-ia" }, "Display players sorted by the quantity of an item held")
|
|
||||||
:add_alias("ia")
|
|
||||||
:add_param("item", false, item_parse)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, item)
|
|
||||||
local players = search_players(game.players, item)
|
|
||||||
if #players == 0 then return { "expcom-inv-search.results-none", item.name } end
|
|
||||||
local top_players = sort_players(players, amount_sort)
|
|
||||||
display_players(player, top_players, item)
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Return the index of the player, higher means they joined more recently
|
|
||||||
local function recent_sort(data)
|
|
||||||
return data.player.index
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get a list of players who have the given item, sorted by how recently they joined
|
|
||||||
-- @command search-recent
|
|
||||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
|
||||||
Commands.new_command("search-recent", { "expcom-inv-search.description-ir" }, "Display players who hold an item sorted by join time")
|
|
||||||
:add_alias("ir")
|
|
||||||
:add_param("item", false, item_parse)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, item)
|
|
||||||
local players = search_players(game.players, item)
|
|
||||||
if #players == 0 then return { "expcom-inv-search.results-none", item.name } end
|
|
||||||
local top_players = sort_players(players, recent_sort)
|
|
||||||
display_players(player, top_players, item)
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Return the the amount of an item a player has divided by their playtime
|
|
||||||
local function combined_sort(data)
|
|
||||||
return data.count / data.online_time
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get a list of players sorted by quantity held and play time
|
|
||||||
-- @command search
|
|
||||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
|
||||||
Commands.new_command("search", { "expcom-inv-search.description-i" }, "Display players sorted by the quantity of an item held and playtime")
|
|
||||||
:add_alias("i")
|
|
||||||
:add_param("item", false, item_parse)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, item)
|
|
||||||
local players = search_players(game.players, item)
|
|
||||||
if #players == 0 then return { "expcom-inv-search.results-none", item.name } end
|
|
||||||
local top_players = sort_players(players, combined_sort)
|
|
||||||
display_players(player, top_players, item)
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Get a list of online players sorted by quantity held and play time
|
|
||||||
-- @command search-online
|
|
||||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
|
||||||
Commands.new_command("search-online", { "expcom-inv-search.description-io" }, "Display online players sorted by the quantity of an item held and playtime")
|
|
||||||
:add_alias("io")
|
|
||||||
:add_param("item", false, item_parse)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, item)
|
|
||||||
local players = search_players(game.connected_players, item)
|
|
||||||
if #players == 0 then return { "expcom-inv-search.results-none", item.name } end
|
|
||||||
local top_players = sort_players(players, combined_sort)
|
|
||||||
display_players(player, top_players, item)
|
|
||||||
end)
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
--[[-- Commands Module - Spawn
|
|
||||||
- Adds a command that allows players to teleport to their spawn point
|
|
||||||
@commands Spawn
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
||||||
|
|
||||||
local function teleport(player)
|
|
||||||
local surface = player.surface
|
|
||||||
local spawn = player.force.get_spawn_position(surface)
|
|
||||||
local position = surface.find_non_colliding_position("character", spawn, 32, 1)
|
|
||||||
-- return false if no new position
|
|
||||||
if not position then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if player.vehicle then
|
|
||||||
-- Teleport the entity
|
|
||||||
local entity = player.vehicle
|
|
||||||
local goto_position = surface.find_non_colliding_position(entity.name, position, 32, 1)
|
|
||||||
-- Surface teleport can only be done for players and cars at the moment. (with surface as an peramitor it gives this error)
|
|
||||||
if entity.type == "car" then
|
|
||||||
entity.teleport(goto_position, surface)
|
|
||||||
elseif surface.index == entity.surface.index then
|
|
||||||
-- Try teleport the entity
|
|
||||||
if not entity.teleport(goto_position) then
|
|
||||||
player.driving = false
|
|
||||||
player.teleport(position, surface)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Teleport the player
|
|
||||||
player.teleport(position, surface)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Teleport to spawn
|
|
||||||
-- @command go-to-spawn
|
|
||||||
-- @tparam[opt=self] LuaPlayer player the player to teleport to their spawn point
|
|
||||||
Commands.new_command("go-to-spawn", { "expcom-spawn.description" }, "Teleport to spawn")
|
|
||||||
:add_param("player", true, "player-role-alive")
|
|
||||||
:set_defaults{
|
|
||||||
player = function(player)
|
|
||||||
if player.connected and player.character and player.character.health > 0 then
|
|
||||||
return player
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
:add_alias("spawn", "tp-spawn")
|
|
||||||
:register(function(player, action_player)
|
|
||||||
if not action_player then
|
|
||||||
return Commands.error{ "expcom-spawn.unavailable" }
|
|
||||||
elseif action_player == player then
|
|
||||||
if not teleport(player) then
|
|
||||||
return Commands.error{ "expcom-spawn.unavailable" }
|
|
||||||
end
|
|
||||||
elseif Roles.player_allowed(player, "command/go-to-spawn/always") then
|
|
||||||
if not teleport(action_player) then
|
|
||||||
return Commands.error{ "expcom-spawn.unavailable" }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return Commands.error{ "expcore-commands.unauthorized" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
--[[-- Commands Module - Spectate
|
|
||||||
- Adds commands relating to spectate and follow
|
|
||||||
@commands Spectate
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Spectate = require("modules.exp_legacy.modules.control.spectate") --- @dep modules.control.spectate
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Toggles spectator mode for the caller
|
|
||||||
-- @command spectate
|
|
||||||
Commands.new_command("spectate", { "expcom-spectate.description-spectate" }, "Toggles spectator mode")
|
|
||||||
:register(function(player)
|
|
||||||
if Spectate.is_spectating(player) then
|
|
||||||
Spectate.stop_spectate(player)
|
|
||||||
else
|
|
||||||
Spectate.start_spectate(player)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Enters follow mode for the caller, following the given player.
|
|
||||||
-- @command follow
|
|
||||||
-- @tparam LuaPlayer player The player that will be followed
|
|
||||||
Commands.new_command("follow", { "expcom-spectate.description-follow" }, "Start following a player in spectator")
|
|
||||||
:add_alias("f")
|
|
||||||
:add_param("player", false, "player-online")
|
|
||||||
:register(function(player, action_player)
|
|
||||||
if player == action_player then
|
|
||||||
return Commands.error{ "expcom-spectate.follow-self" }
|
|
||||||
else
|
|
||||||
Spectate.start_follow(player, action_player)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
--[[-- Commands Module - Set game speed
|
|
||||||
- Adds a command that allows changing game speed
|
|
||||||
@commands Set game speed
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
Commands.new_command("game-speed", { "expcom-speed.description" }, "Set game speed")
|
|
||||||
:add_param("amount", "number-range", 0.2, 8)
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:register(function(player, amount)
|
|
||||||
game.speed = math.round(amount, 3)
|
|
||||||
game.print{ "expcom-speed.result", player.name, string.format("%.3f", amount) }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
--[[-- Commands Module - Clear Item On Ground
|
|
||||||
- Adds a command that clear item on ground so blueprint can deploy safely
|
|
||||||
@commands Clear Item On Ground
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
Commands.new_command("clear-item-on-ground", { "expcom-surface-clearing.description-ci" }, "Clear Item On Ground")
|
|
||||||
:add_param("range", false, "integer-range", 1, 1000)
|
|
||||||
:register(function(player, range)
|
|
||||||
local items = {} --- @type LuaItemStack[]
|
|
||||||
-- Intentionally left as player.position to allow use in remote view
|
|
||||||
local entities = player.surface.find_entities_filtered{ position = player.position, radius = range, name = "item-on-ground" }
|
|
||||||
for _, e in pairs(entities) do
|
|
||||||
if e.stack then
|
|
||||||
items[#items + 1] = e.stack
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
ExpUtil.move_items_to_surface{
|
|
||||||
items = items,
|
|
||||||
surface = player.surface,
|
|
||||||
allow_creation = true,
|
|
||||||
name = "iron-chest",
|
|
||||||
}
|
|
||||||
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
Commands.new_command("clear-blueprint", { "expcom-surface-clearing.description-cb" }, "Clear Blueprint")
|
|
||||||
:add_param("range", false, "integer-range", 1, 1000)
|
|
||||||
:register(function(player, range)
|
|
||||||
-- Intentionally left as player.position to allow use in remote view
|
|
||||||
for _, e in pairs(player.surface.find_entities_filtered{ position = player.position, radius = range, type = "entity-ghost" }) do
|
|
||||||
e.destroy()
|
|
||||||
end
|
|
||||||
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
--[[-- Commands Module - Teleport
|
|
||||||
- Adds a command that allows players to teleport to other players
|
|
||||||
@commands Teleport
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
local function teleport(from_player, to_player)
|
|
||||||
local surface = to_player.physical_surface
|
|
||||||
local position = surface.find_non_colliding_position("character", to_player.physical_position, 32, 1)
|
|
||||||
|
|
||||||
-- return false if no new position
|
|
||||||
if not position then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if from_player.vehicle then
|
|
||||||
-- Teleport the entity
|
|
||||||
local entity = from_player.vehicle
|
|
||||||
local goto_position = surface.find_non_colliding_position(entity.name, position, 32, 1)
|
|
||||||
|
|
||||||
-- Surface teleport can only be done for players and cars at the moment. (with surface as an peramitor it gives this error)
|
|
||||||
if entity.type == "car" then
|
|
||||||
entity.teleport(goto_position, surface)
|
|
||||||
elseif surface.index == entity.surface.index then
|
|
||||||
-- Try teleport the entity
|
|
||||||
if not entity.teleport(goto_position) then
|
|
||||||
from_player.driving = false
|
|
||||||
from_player.teleport(position, surface)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Teleport the player
|
|
||||||
from_player.teleport(position, surface)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Teleports a player to another player.
|
|
||||||
-- @command teleport
|
|
||||||
-- @tparam LuaPlayer from_player the player that will be teleported, must be alive
|
|
||||||
-- @tparam LuaPlayer to_player the player to teleport to, must be online (if dead goes to where they died)
|
|
||||||
Commands.new_command("teleport", { "expcom-tp.description-tp" }, "Teleports a player to another player.")
|
|
||||||
:add_param("from_player", false, "player-alive")
|
|
||||||
:add_param("to_player", false, "player-online")
|
|
||||||
:add_alias("tp")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:register(function(_, from_player, to_player)
|
|
||||||
if from_player.index == to_player.index then
|
|
||||||
-- return if attempting to teleport to self
|
|
||||||
return Commands.error{ "expcom-tp.to-self" }
|
|
||||||
end
|
|
||||||
if not teleport(from_player, to_player) then
|
|
||||||
-- return if the teleport failed
|
|
||||||
return Commands.error{ "expcom-tp.no-position-found" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Teleports a player to you.
|
|
||||||
-- @command bring
|
|
||||||
-- @tparam LuaPlayer player the player that will be teleported, must be alive
|
|
||||||
Commands.new_command("bring", { "expcom-tp.description-bring" }, "Teleports a player to you.")
|
|
||||||
:add_param("player", false, "player-alive")
|
|
||||||
:set_flag("admin_only")
|
|
||||||
:register(function(player, from_player)
|
|
||||||
if from_player.index == player.index then
|
|
||||||
-- return if attempting to teleport to self
|
|
||||||
return Commands.error{ "expcom-tp.to-self" }
|
|
||||||
end
|
|
||||||
if not teleport(from_player, player) then
|
|
||||||
-- return if the teleport failed
|
|
||||||
return Commands.error{ "expcom-tp.no-position-found" }
|
|
||||||
end
|
|
||||||
from_player.print("Come here my friend")
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Teleports you to a player.
|
|
||||||
-- @command goto
|
|
||||||
-- @tparam LuaPlayer player the player to teleport to, must be online (if dead goes to where they died)
|
|
||||||
Commands.new_command("goto", { "expcom-tp.description-goto" }, "Teleports you to a player.")
|
|
||||||
:add_param("player", false, "player-online")
|
|
||||||
:add_alias("tp-me", "tpme")
|
|
||||||
:register(function(player, to_player)
|
|
||||||
if to_player.index == player.index then
|
|
||||||
-- return if attempting to teleport to self
|
|
||||||
return Commands.error{ "expcom-tp.to-self" }
|
|
||||||
end
|
|
||||||
if not teleport(player, to_player) then
|
|
||||||
-- return if the teleport failed
|
|
||||||
return Commands.error{ "expcom-tp.no-position-found" }
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
--[[-- Commands Module - Set Automatic Train
|
|
||||||
- Adds a command that set all train back to automatic
|
|
||||||
@commands Set Automatic Train
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
local format_number = require("util").format_number
|
|
||||||
|
|
||||||
Commands.new_command("set-trains-to-automatic", { "expcom-train.description" }, "Set All Trains to Automatic")
|
|
||||||
:register(function(player)
|
|
||||||
local count = 0
|
|
||||||
|
|
||||||
for _, v in pairs(player.force.get_trains()) do
|
|
||||||
if v.manual_mode then
|
|
||||||
count = count + 1
|
|
||||||
v.manual_mode = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
game.print{ "expcom-train.manual-result", player.name, format_number(count) }
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
--- Adds a virtual layer to store power to save space.
|
|
||||||
-- @commands Vlayer
|
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
local vlayer = require("modules.exp_legacy.modules.control.vlayer")
|
|
||||||
|
|
||||||
Commands.new_command("vlayer-info", { "vlayer.description-vi" }, "Vlayer Info")
|
|
||||||
:register(function(_)
|
|
||||||
local c = vlayer.get_circuits()
|
|
||||||
|
|
||||||
for k, v in pairs(c) do
|
|
||||||
Commands.print(v .. " : " .. k)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
--[[-- Commands Module - Warnings
|
|
||||||
- Adds a commands that allow admins to warn other players
|
|
||||||
@commands Warnings
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local Warnings = require("modules.exp_legacy.modules.control.warnings") --- @dep modules.control.warnings
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale
|
|
||||||
local config = require("modules.exp_legacy.config.warnings") --- @dep config.warnings
|
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
|
||||||
|
|
||||||
--- Gives a warning to a player; may lead to automatic script action.
|
|
||||||
-- @command give-warning
|
|
||||||
-- @tparam LuaPlayer player the player the will recive a warning
|
|
||||||
-- @tparam string reason the reason the player is being given a warning
|
|
||||||
Commands.new_command("give-warning", { "expcom-warnings.description-give" }, "Gives a warning to a player; may lead to automatic script action.")
|
|
||||||
:add_param("player", false, "player-role")
|
|
||||||
:add_param("reason", false)
|
|
||||||
:add_alias("warn")
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, action_player, reason)
|
|
||||||
Warnings.add_warning(action_player, player.name, reason)
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
game.print{ "expcom-warnings.received", action_player_name_color, by_player_name_color, reason }
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Gets the number of warnings a player has. If no player then lists all players and the number of warnings they have.
|
|
||||||
-- @command get-warnings
|
|
||||||
-- @tparam[opt=list] LuaPlayer player the player to get the warning for, if nil all players are listed
|
|
||||||
Commands.new_command("get-warnings", { "expcom-warnings.description-get" }, "Gets the number of warnings a player has. If no player then lists all players and the number of warnings they have.")
|
|
||||||
:add_param("player", true, "player")
|
|
||||||
:add_alias("warnings", "list-warnings")
|
|
||||||
:register(function(_, player)
|
|
||||||
if player then
|
|
||||||
local warnings = Warnings.get_warnings(player)
|
|
||||||
local script_warnings = Warnings.get_script_warnings(player)
|
|
||||||
local player_name_color = format_player_name(player)
|
|
||||||
Commands.print{ "expcom-warnings.player", player_name_color, #warnings, #script_warnings, config.temp_warning_limit }
|
|
||||||
for _, warning in ipairs(warnings) do
|
|
||||||
Commands.print{ "expcom-warnings.player-detail", format_player_name(warning.by_player_name), warning.reason }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local rtn = {}
|
|
||||||
local user_script_warnings = Warnings.user_script_warnings
|
|
||||||
for player_name, warnings in pairs(Warnings.user_warnings:get_all()) do
|
|
||||||
rtn[player_name] = { #warnings, 0 }
|
|
||||||
end
|
|
||||||
|
|
||||||
for player_name, warnings in pairs(user_script_warnings) do
|
|
||||||
if not rtn[player_name] then
|
|
||||||
rtn[player_name] = { 0, 0 }
|
|
||||||
end
|
|
||||||
rtn[player_name][2] = #warnings
|
|
||||||
end
|
|
||||||
|
|
||||||
Commands.print{ "expcom-warnings.list-title" }
|
|
||||||
for player_name, warnings in pairs(rtn) do
|
|
||||||
local player_name_color = format_player_name(player_name)
|
|
||||||
Commands.print{ "expcom-warnings.list", player_name_color, warnings[1], warnings[2], config.temp_warning_limit }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- Clears all warnings (and script warnings) from a player
|
|
||||||
-- @command clear-warnings
|
|
||||||
-- @tparam LuaPlayer player the player to clear the warnings from
|
|
||||||
Commands.new_command("clear-warnings", { "expcom-warnings.description-clear" }, "Clears all warnings (and script warnings) from a player")
|
|
||||||
:add_param("player", false, "player")
|
|
||||||
:register(function(player, action_player)
|
|
||||||
Warnings.clear_warnings(action_player, player.name)
|
|
||||||
Warnings.clear_script_warnings(action_player)
|
|
||||||
local action_player_name_color = format_player_name(action_player)
|
|
||||||
local by_player_name_color = format_player_name(player)
|
|
||||||
game.print{ "expcom-warnings.cleared", action_player_name_color, by_player_name_color }
|
|
||||||
end)
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
--- Adds a waterfill
|
|
||||||
-- @commands Waterfill
|
|
||||||
|
|
||||||
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 SelectionConvertArea = "ConvertArea"
|
|
||||||
|
|
||||||
--- 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) },
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
Commands.new_command("waterfill", { "expcom-waterfill.description" }, "Change tile to water")
|
|
||||||
:register(function(player)
|
|
||||||
local inv = player.get_main_inventory()
|
|
||||||
|
|
||||||
if (inv.get_item_count("cliff-explosives")) == 0 then
|
|
||||||
return player.print{ "expcom-waterfill.waterfill-cliff" }
|
|
||||||
end
|
|
||||||
|
|
||||||
if Selection.is_selecting(player, SelectionConvertArea) then
|
|
||||||
Selection.stop(player)
|
|
||||||
else
|
|
||||||
Selection.start(player, SelectionConvertArea)
|
|
||||||
return Commands.success{ "expcom-waterfill.entered-area-selection" }
|
|
||||||
end
|
|
||||||
|
|
||||||
return Commands.success
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- When an area is selected to add protection to the area
|
|
||||||
Selection.on_selection(SelectionConvertArea, function(event)
|
|
||||||
local area = aabb_align_expand(event.area)
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
|
|
||||||
if not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local entities = event.surface.find_entities_filtered{ area = area, name = "steel-chest" }
|
|
||||||
|
|
||||||
if #entities == 0 then
|
|
||||||
player.print("No steel chest found")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local tiles_to_make = {}
|
|
||||||
local inv = player.get_main_inventory()
|
|
||||||
|
|
||||||
if not inv then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local clf_exp = inv.get_item_count("cliff-explosives")
|
|
||||||
|
|
||||||
for _, entity in pairs(entities) do
|
|
||||||
if clf_exp >= 1 then
|
|
||||||
if entity.get_inventory(defines.inventory.chest).is_empty() then
|
|
||||||
-- Intentionally left as player.position to allow use in report view
|
|
||||||
if (math.floor(player.position.x) ~= math.floor(entity.position.x)) or (math.floor(player.position.y) ~= math.floor(entity.position.y)) then
|
|
||||||
table.insert(tiles_to_make, { name = "water-mud", position = entity.position })
|
|
||||||
entity.destroy()
|
|
||||||
else
|
|
||||||
player.print{ "expcom-waterfill.waterfill-distance" }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
clf_exp = clf_exp - 1
|
|
||||||
inv.remove{ name = "cliff-explosives", count = 1 }
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
event.surface.set_tiles(tiles_to_make)
|
|
||||||
end)
|
|
||||||
@@ -123,8 +123,8 @@ function Selection.is_selecting(player, selection_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Filter on_player_selected_area to this custom selection, appends the selection arguments
|
--- Filter on_player_selected_area to this custom selection, appends the selection arguments
|
||||||
-- @tparam string selection_name The name of the selection to listen for
|
-- @param string selection_name The name of the selection to listen for
|
||||||
-- @tparam function handler The event handler
|
-- @param function handler The event handler
|
||||||
function Selection.on_selection(selection_name, handler)
|
function Selection.on_selection(selection_name, handler)
|
||||||
Event.add(defines.events.on_player_selected_area, function(event)
|
Event.add(defines.events.on_player_selected_area, function(event)
|
||||||
local selection = selections[event.player_index]
|
local selection = selections[event.player_index]
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ WrapData:set_serializer(function(raw_key) return raw_key.warp_id end)
|
|||||||
|
|
||||||
local Warps = {}
|
local Warps = {}
|
||||||
|
|
||||||
|
--- @class ExpScenario_Warps.force_warps: { spawn: string, [number]: string }
|
||||||
|
|
||||||
-- Storage lookup table for force name to task ids
|
-- Storage lookup table for force name to task ids
|
||||||
local force_warps = { _uid = 1 }
|
local force_warps = { _uid = 1 }
|
||||||
--- @cast force_warps table<string, { spawn: string, [number]: string }>
|
--- @cast force_warps table<string, ExpScenario_Warps.force_warps>
|
||||||
Storage.register(force_warps, function(tbl)
|
Storage.register(force_warps, function(tbl)
|
||||||
force_warps = tbl
|
force_warps = tbl
|
||||||
end)
|
end)
|
||||||
@@ -61,7 +63,7 @@ WrapData:on_update(function(warp_id, warp, old_warp)
|
|||||||
local warp_ids = force_warps[force_name]
|
local warp_ids = force_warps[force_name]
|
||||||
local spawn_id = warp_ids.spawn
|
local spawn_id = warp_ids.spawn
|
||||||
|
|
||||||
local warp_names = {}
|
local warp_names = {} --- @type table<string, string>
|
||||||
for _, next_warp_id in pairs(warp_ids) do
|
for _, next_warp_id in pairs(warp_ids) do
|
||||||
local next_warp = WrapData:get(next_warp_id)
|
local next_warp = WrapData:get(next_warp_id)
|
||||||
if next_warp_id ~= spawn_id then
|
if next_warp_id ~= spawn_id then
|
||||||
@@ -71,6 +73,7 @@ WrapData:on_update(function(warp_id, warp, old_warp)
|
|||||||
|
|
||||||
-- Sort the warp names in alphabetical order
|
-- Sort the warp names in alphabetical order
|
||||||
local new_warp_ids = table.get_values(table.key_sort(warp_names))
|
local new_warp_ids = table.get_values(table.key_sort(warp_names))
|
||||||
|
--- @cast new_warp_ids ExpScenario_Warps.force_warps
|
||||||
table.insert(new_warp_ids, 1, spawn_id)
|
table.insert(new_warp_ids, 1, spawn_id)
|
||||||
new_warp_ids.spawn = spawn_id
|
new_warp_ids.spawn = spawn_id
|
||||||
force_warps[force_name] = new_warp_ids
|
force_warps[force_name] = new_warp_ids
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local config = require("modules.exp_legacy.config.bonus") --- @dep config.bonuses
|
local config = require("modules.exp_legacy.config.bonus") --- @dep config.bonuses
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
-- Stores the bonus for the player
|
-- Stores the bonus for the player
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
@@ -47,19 +46,16 @@ PlayerBonus:on_update(function(player_name, player_bonus)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
--- Changes the amount of bonus you receive
|
--- Changes the amount of bonus you receive
|
||||||
-- @command bonus
|
Commands.new("bonus", { "bonus.description" })
|
||||||
-- @tparam number amount range 0-10 the increase for your bonus
|
:optional("amount", { "bonus.arg-amount" }, Commands.types.integer_range(0, 10))
|
||||||
Commands.new_command("bonus", "Changes the amount of bonus you receive")
|
|
||||||
:add_param("amount", "integer-range", 0, 10)
|
|
||||||
:register(function(player, amount)
|
:register(function(player, amount)
|
||||||
if not Roles.player_allowed(player, "command/bonus") then
|
--- @cast amount number?
|
||||||
Commands.print{ "expcom-bonus.perm", 1 }
|
if amount then
|
||||||
return
|
PlayerBonus:set(player, amount)
|
||||||
|
return Commands.status.success{ "bonus.set", amount }
|
||||||
|
else
|
||||||
|
return Commands.status.success{ "bonus.get", PlayerBonus:get(player) }
|
||||||
end
|
end
|
||||||
|
|
||||||
PlayerBonus:set(player, amount)
|
|
||||||
|
|
||||||
Commands.print{ "expcom-bonus.set", amount }
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When a player respawns re-apply bonus
|
--- When a player respawns re-apply bonus
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
-- @data Greetings
|
-- @data Greetings
|
||||||
|
|
||||||
local config = require("modules.exp_legacy.config.join_messages") --- @dep config.join_messages
|
local config = require("modules.exp_legacy.config.join_messages") --- @dep config.join_messages
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
|
|
||||||
--- Stores the join message that the player have
|
--- Stores the join message that the player have
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
@@ -24,20 +23,23 @@ CustomMessages:on_load(function(player_name, player_message)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
--- Set your custom join message
|
--- Set your custom join message
|
||||||
-- @command join-message
|
Commands.new("set-join-message", { "join-message.description-add" })
|
||||||
-- @tparam string message The custom join message that will be used
|
:optional("message", false, Commands.types.string_max_length(255))
|
||||||
Commands.new_command("join-message", "Sets your custom join message")
|
:enable_auto_concatenation()
|
||||||
:add_param("message", false, "string-max-length", 255)
|
:add_aliases{ "join-message" }
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, message)
|
:register(function(player, message)
|
||||||
if not player then return end
|
--- @cast message string?
|
||||||
CustomMessages:set(player, message)
|
if message then
|
||||||
return { "join-message.message-set" }
|
CustomMessages:set(player, message)
|
||||||
|
return Commands.status.success{ "join-message.message-set" }
|
||||||
|
else
|
||||||
|
return Commands.status.success{ "join-message.message-get", CustomMessages:get(player) }
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Commands.new_command("join-message-clear", "Clear your join message")
|
--- Removes your custom join message
|
||||||
|
Commands.new("remove-join-message", { "join-message.description-remove" })
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
if not player then return end
|
|
||||||
CustomMessages:remove(player)
|
CustomMessages:remove(player)
|
||||||
return { "join-message.message-cleared" }
|
return Commands.status.success{ "join-message.message-cleared" }
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
local config = require("modules.exp_legacy.config.personal_logistic") --- @dep config.personal-logistic
|
local config = require("modules.exp_legacy.config.personal_logistic") --- @dep config.personal-logistic
|
||||||
|
|
||||||
local function pl(type, target, amount)
|
local function pl(type, target, amount)
|
||||||
@@ -66,21 +66,20 @@ local function pl(type, target, amount)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Commands.new_command("personal-logistic", "Set Personal Logistic (-1 to cancel all) (Select spidertron to edit spidertron)")
|
Commands.new("personal-logistic", "Set Personal Logistic (-1 to cancel all) (Select spidertron to edit spidertron)")
|
||||||
:add_param("amount", "integer-range", -1, 10)
|
:argument("amount", "", Commands.types.integer_range(-1, 10))
|
||||||
:add_alias("pl")
|
:add_aliases{ "pl" }
|
||||||
:register(function(player, amount)
|
:register(function(player, amount)
|
||||||
|
--- @cast amount number
|
||||||
if player.force.technologies["logistic-robotics"].researched then
|
if player.force.technologies["logistic-robotics"].researched then
|
||||||
if player.selected ~= nil then
|
if player.selected ~= nil then
|
||||||
if player.selected.name == "spidertron" then
|
if player.selected.name == "spidertron" then
|
||||||
pl("s", player.selected, amount / 10)
|
pl("s", player.selected, amount / 10)
|
||||||
return Commands.success
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
pl("p", player, amount / 10)
|
pl("p", player, amount / 10)
|
||||||
return Commands.success
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
player.print("Personal Logistic not researched")
|
return Commands.status.error("Personal Logistic not researched")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
@data Quickbar
|
@data Quickbar
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
local config = require("modules.exp_legacy.config.preset_player_quickbar") --- @dep config.preset_player_quickbar
|
local config = require("modules.exp_legacy.config.preset_player_quickbar") --- @dep config.preset_player_quickbar
|
||||||
|
|
||||||
--- Stores the quickbar filters for a player
|
--- Stores the quickbar filters for a player
|
||||||
@@ -32,7 +32,7 @@ PlayerFilters:on_load(function(player_name, filters)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local ignoredItems = {
|
local ignored_items = {
|
||||||
["blueprint"] = true,
|
["blueprint"] = true,
|
||||||
["blueprint-book"] = true,
|
["blueprint-book"] = true,
|
||||||
["deconstruction-planner"] = true,
|
["deconstruction-planner"] = true,
|
||||||
@@ -41,9 +41,8 @@ local ignoredItems = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
--- Saves your quickbar preset to the script-output folder
|
--- Saves your quickbar preset to the script-output folder
|
||||||
-- @command save-quickbar
|
Commands.new("save-quickbar", "Saves your Quickbar preset items to file")
|
||||||
Commands.new_command("save-quickbar", "Saves your Quickbar preset items to file")
|
:add_aliases{ "save-toolbar" }
|
||||||
:add_alias("save-toolbar")
|
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
local filters = {}
|
local filters = {}
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ Commands.new_command("save-quickbar", "Saves your Quickbar preset items to file"
|
|||||||
local slot = player.get_quick_bar_slot(i)
|
local slot = player.get_quick_bar_slot(i)
|
||||||
-- Need to filter out blueprint and blueprint books because the slot is a LuaItemPrototype and does not contain a way to export blueprint data
|
-- Need to filter out blueprint and blueprint books because the slot is a LuaItemPrototype and does not contain a way to export blueprint data
|
||||||
if slot ~= nil then
|
if slot ~= nil then
|
||||||
local ignored = ignoredItems[slot.name]
|
local ignored = ignored_items[slot.name]
|
||||||
if ignored ~= true then
|
if ignored ~= true then
|
||||||
filters[i] = slot.name
|
filters[i] = slot.name
|
||||||
end
|
end
|
||||||
@@ -64,5 +63,5 @@ Commands.new_command("save-quickbar", "Saves your Quickbar preset items to file"
|
|||||||
PlayerFilters:remove(player)
|
PlayerFilters:remove(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
return { "quickbar.saved" }
|
return Commands.status.success{ "quickbar.saved" }
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -3,11 +3,8 @@
|
|||||||
@data Tag
|
@data Tag
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local Commands = require("modules/exp_commands")
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
require("modules.exp_legacy.config.expcore.command_general_parse")
|
|
||||||
require("modules.exp_legacy.config.expcore.command_role_parse")
|
|
||||||
require("modules.exp_legacy.config.expcore.command_color_parse")
|
|
||||||
|
|
||||||
--- Stores the tag for a player
|
--- Stores the tag for a player
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
@@ -47,42 +44,39 @@ PlayerTagColors:on_update(function(player_name, player_tag_color)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
--- Sets your player tag.
|
--- Sets your player tag.
|
||||||
-- @command tag
|
Commands.new("tag", "Sets your player tag.")
|
||||||
-- @tparam string tag the tag that will be after the name, there is a max length
|
:argument("tag", "", Commands.types.string_max_length(20))
|
||||||
Commands.new_command("tag", "Sets your player tag.")
|
:enable_auto_concatenation()
|
||||||
:add_param("tag", false, "string-max-length", 20)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, tag)
|
:register(function(player, tag)
|
||||||
|
--- @cast tag string
|
||||||
PlayerTags:set(player, tag)
|
PlayerTags:set(player, tag)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Sets your player tag color.
|
--- Sets your player tag color.
|
||||||
-- @command tag
|
Commands.new("tag-color", "Sets your player tag color.")
|
||||||
-- @tparam string color name.
|
:argument("color", "", Commands.types.color)
|
||||||
Commands.new_command("tag-color", "Sets your player tag color.")
|
:enable_auto_concatenation()
|
||||||
:add_param("color", false, "color")
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, color)
|
:register(function(player, color)
|
||||||
|
--- @cast color Color
|
||||||
PlayerTagColors:set(player, color)
|
PlayerTagColors:set(player, color)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Clears your tag. Or another player if you are admin.
|
--- Clears your tag. Or another player if you are admin.
|
||||||
-- @command tag-clear
|
Commands.new("tag-clear", "Clears your tag. Or another player if you are admin.")
|
||||||
-- @tparam[opt=self] LuaPlayer player the player to remove the tag from, nil will apply to self
|
:optional("player", "", Commands.types.lower_role_player)
|
||||||
Commands.new_command("tag-clear", "Clears your tag. Or another player if you are admin.")
|
:defaults{
|
||||||
:add_param("player", true, "player-role")
|
player = function(player) return player end
|
||||||
:set_defaults{ player = function(player)
|
}
|
||||||
return player -- default is the user using the command
|
:register(function(player, other_player)
|
||||||
end }
|
--- @cast other_player LuaPlayer
|
||||||
:register(function(player, action_player)
|
if other_player == player then
|
||||||
if action_player.index == player.index then
|
-- No player given so removes your tag
|
||||||
-- no player given so removes your tag
|
PlayerTags:remove(other_player)
|
||||||
PlayerTags:remove(action_player)
|
|
||||||
elseif Roles.player_allowed(player, "command/clear-tag/always") then
|
elseif Roles.player_allowed(player, "command/clear-tag/always") then
|
||||||
-- player given and user is admin so clears that player's tag
|
-- Player given and user is admin so clears that player's tag
|
||||||
PlayerTags:remove(action_player)
|
PlayerTags:remove(other_player)
|
||||||
else
|
else
|
||||||
-- user is not admin and tried to clear another users tag
|
-- User is not admin and tried to clear another users tag
|
||||||
return Commands.error{ "expcore-commands.unauthorized" }
|
return Commands.status.unauthorised()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ end
|
|||||||
|
|
||||||
Event.add(defines.events.on_player_created, function(event)
|
Event.add(defines.events.on_player_created, function(event)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
|
--- @diagnostic disable-next-line param-type-mismatch
|
||||||
util.insert_safe(player, global.created_items)
|
util.insert_safe(player, global.created_items)
|
||||||
|
|
||||||
local r = global.chart_distance or 200
|
local r = global.chart_distance or 200
|
||||||
@@ -65,6 +66,7 @@ end)
|
|||||||
|
|
||||||
Event.add(defines.events.on_player_respawned, function(event)
|
Event.add(defines.events.on_player_respawned, function(event)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
|
--- @diagnostic disable-next-line param-type-mismatch
|
||||||
util.insert_safe(player, global.respawn_items)
|
util.insert_safe(player, global.respawn_items)
|
||||||
if use_silo_script then
|
if use_silo_script then
|
||||||
silo_script.on_event(event)
|
silo_script.on_event(event)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
local Commands = require("modules.exp_legacy.expcore.commands")
|
local Commands = require("modules/exp_commands")
|
||||||
local config = require("modules.exp_legacy.config.graftorio")
|
local config = require("modules.exp_legacy.config.graftorio")
|
||||||
local statics = require("modules.exp_legacy.modules.graftorio.statics")
|
local statics = require("modules.exp_legacy.modules.graftorio.statics")
|
||||||
local general = require("modules.exp_legacy.modules.graftorio.general")
|
local general = require("modules.exp_legacy.modules.graftorio.general")
|
||||||
@@ -10,8 +10,8 @@ if config.modules.forcestats then
|
|||||||
forcestats = require("modules.exp_legacy.modules.graftorio.forcestats")
|
forcestats = require("modules.exp_legacy.modules.graftorio.forcestats")
|
||||||
end
|
end
|
||||||
|
|
||||||
Commands.new_command("collectdata", "Collect data for RCON usage")
|
Commands.new("collectdata", "Collect data for RCON usage")
|
||||||
:add_param("location", true)
|
:optional("location", "", Commands.types.string) -- Not sure what this is for, i didn't write this
|
||||||
:register(function()
|
:register(function()
|
||||||
-- this must be first as it overwrites the stats
|
-- this must be first as it overwrites the stats
|
||||||
-- also makes the .other table for all forces
|
-- also makes the .other table for all forces
|
||||||
@@ -24,6 +24,5 @@ Commands.new_command("collectdata", "Collect data for RCON usage")
|
|||||||
forcestats.collect_production()
|
forcestats.collect_production()
|
||||||
forcestats.collect_loginet()
|
forcestats.collect_loginet()
|
||||||
end
|
end
|
||||||
rcon.print(table_to_json(general.data.output))
|
return Commands.status.success(table_to_json(general.data.output))
|
||||||
return Commands.success()
|
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ local main_frame_name = Gui.uid_name()
|
|||||||
local close_name = Gui.uid_name()
|
local close_name = Gui.uid_name()
|
||||||
local tab_name = Gui.uid_name()
|
local tab_name = Gui.uid_name()
|
||||||
|
|
||||||
function Public.open_dubug(player)
|
function Public.open_debug(player)
|
||||||
for i = 1, #pages do
|
for i = 1, #pages do
|
||||||
local page = pages[i]
|
local page = pages[i]
|
||||||
local callback = page.on_open_debug
|
local callback = page.on_open_debug
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ function Public.show(container)
|
|||||||
local left_panel_style = left_panel.style
|
local left_panel_style = left_panel.style
|
||||||
left_panel_style.width = 300
|
left_panel_style.width = 300
|
||||||
|
|
||||||
for token_id in pairs(Storage.registered) do
|
--- @diagnostic disable-next-line invisible
|
||||||
|
for token_id in pairs(Storage._registered) do
|
||||||
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = token_id }
|
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = token_id }
|
||||||
Gui.set_data(header, token_id)
|
Gui.set_data(header, token_id)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -60,9 +60,10 @@ local elem_filter = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function clear_module(player, area, machine)
|
local function clear_module(player, area, machine)
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
local force = player.force
|
||||||
for _, entity in pairs(player.surface.find_entities_filtered{ area = area, name = machine, force = player.force }) do
|
local surface = player.surface -- Allow remote view
|
||||||
for _, r in pairs(player.surface.find_entities_filtered{ position = entity.position, name = "item-request-proxy", force = player.force }) do
|
for _, entity in pairs(surface.find_entities_filtered{ area = area, name = machine, force = force }) do
|
||||||
|
for _, r in pairs(surface.find_entities_filtered{ position = entity.position, name = "item-request-proxy", force = force }) do
|
||||||
if r then
|
if r then
|
||||||
r.destroy{ raise_destroy = true }
|
r.destroy{ raise_destroy = true }
|
||||||
end
|
end
|
||||||
@@ -75,7 +76,7 @@ local function clear_module(player, area, machine)
|
|||||||
|
|
||||||
if m_current_module_content then
|
if m_current_module_content then
|
||||||
for k, m in pairs(m_current_module_content) do
|
for k, m in pairs(m_current_module_content) do
|
||||||
player.surface.spill_item_stack(entity.bounding_box.left_top, { name = k, count = m }, true, player.force, false)
|
surface.spill_item_stack(entity.bounding_box.left_top, { name = k, count = m }, true, force, false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -129,8 +129,7 @@ end)
|
|||||||
Event.on_nth_tick(60, function()
|
Event.on_nth_tick(60, function()
|
||||||
for _, player in pairs(game.connected_players) do
|
for _, player in pairs(game.connected_players) do
|
||||||
local frame = Gui.get_left_element(player, production_container)
|
local frame = Gui.get_left_element(player, production_container)
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
local stat = player.force.get_item_production_statistics(player.surface) -- Allow remote view
|
||||||
local stat = player.force.get_item_production_statistics(player.surface)
|
|
||||||
local precision_value = precision[frame.container["production_st"].disp.table["production_0_e"].selected_index]
|
local precision_value = precision[frame.container["production_st"].disp.table["production_0_e"].selected_index]
|
||||||
local table = frame.container["production_st"].disp.table
|
local table = frame.container["production_st"].disp.table
|
||||||
|
|
||||||
|
|||||||
@@ -107,12 +107,12 @@ local function research_notification(event)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not (event.by_script) then
|
if not (event.by_script) then
|
||||||
game.print{ "expcom-res.inf", research_time_format(game.tick), event.research.name, event.research.level - 1 }
|
game.print{ "research.inf", research_time_format(game.tick), event.research.name, event.research.level - 1 }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not (event.by_script) then
|
if not (event.by_script) then
|
||||||
game.print{ "expcom-res.msg", research_time_format(game.tick), event.research.name }
|
game.print{ "research.msg", research_time_format(game.tick), event.research.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.bonus_inventory.enabled then
|
if config.bonus_inventory.enabled then
|
||||||
@@ -139,7 +139,7 @@ local function research_gui_update()
|
|||||||
local res_i = res_n + i - 3
|
local res_i = res_n + i - 3
|
||||||
|
|
||||||
if res["disp"][res_i] then
|
if res["disp"][res_i] then
|
||||||
res_disp[i]["name"] = { "expcom-res.res-name", res["disp"][res_i]["raw_name"], prototypes.technology[res["disp"][res_i]["raw_name"]].localised_name }
|
res_disp[i]["name"] = { "research.res-name", res["disp"][res_i]["raw_name"], prototypes.technology[res["disp"][res_i]["raw_name"]].localised_name }
|
||||||
|
|
||||||
if research.time[res_i] == 0 then
|
if research.time[res_i] == 0 then
|
||||||
res_disp[i]["target"] = res["disp"][res_i].target_disp
|
res_disp[i]["target"] = res["disp"][res_i].target_disp
|
||||||
@@ -237,10 +237,10 @@ local research_data_set =
|
|||||||
local res_disp = research_gui_update()
|
local res_disp = research_gui_update()
|
||||||
|
|
||||||
research_data_group(disp, 0)
|
research_data_group(disp, 0)
|
||||||
disp["research_0_name"].caption = { "expcom-res.name" }
|
disp["research_0_name"].caption = { "research.name" }
|
||||||
disp["research_0_target"].caption = { "expcom-res.target" }
|
disp["research_0_target"].caption = { "research.target" }
|
||||||
disp["research_0_attempt"].caption = { "expcom-res.attempt" }
|
disp["research_0_attempt"].caption = { "research.attempt" }
|
||||||
disp["research_0_difference"].caption = { "expcom-res.difference" }
|
disp["research_0_difference"].caption = { "research.difference" }
|
||||||
|
|
||||||
for i = 1, 8, 1 do
|
for i = 1, 8, 1 do
|
||||||
research_data_group(disp, i)
|
research_data_group(disp, i)
|
||||||
@@ -269,7 +269,7 @@ local research_container =
|
|||||||
:static_name(Gui.unique_static_name)
|
:static_name(Gui.unique_static_name)
|
||||||
:add_to_left_flow()
|
:add_to_left_flow()
|
||||||
|
|
||||||
Gui.left_toolbar_button("item/space-science-pack", { "expcom-res.main-tooltip" }, research_container, function(player)
|
Gui.left_toolbar_button("item/space-science-pack", { "research.main-tooltip" }, research_container, function(player)
|
||||||
return Roles.player_allowed(player, "gui/research")
|
return Roles.player_allowed(player, "gui/research")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
--- Stores the visible state of server ups
|
--- Stores the visible state of server ups
|
||||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
||||||
@@ -34,19 +34,19 @@ local server_ups =
|
|||||||
UsesServerUps:on_load(function(player_name, visible)
|
UsesServerUps:on_load(function(player_name, visible)
|
||||||
local player = game.players[player_name]
|
local player = game.players[player_name]
|
||||||
local label = player.gui.screen[server_ups.name]
|
local label = player.gui.screen[server_ups.name]
|
||||||
|
--- @diagnostic disable-next-line undefined-field
|
||||||
if not External.valid() or not global.ext.var.server_ups then visible = false end
|
if not External.valid() or not global.ext.var.server_ups then visible = false end
|
||||||
label.visible = visible
|
label.visible = visible
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Toggles if the server ups is visbile
|
--- Toggles if the server ups is visbile
|
||||||
-- @command server-ups
|
Commands.new("server-ups", { "server-ups.description" })
|
||||||
Commands.new_command("server-ups", "Toggle the server UPS display")
|
:add_aliases{ "sups", "ups" }
|
||||||
:add_alias("sups", "ups")
|
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
local label = player.gui.screen[server_ups.name]
|
local label = player.gui.screen[server_ups.name]
|
||||||
if not External.valid() then
|
if not External.valid() then
|
||||||
label.visible = false
|
label.visible = false
|
||||||
return Commands.error{ "expcom-server-ups.no-ext" }
|
return Commands.status.error{ "server-ups.no-ext" }
|
||||||
end
|
end
|
||||||
label.visible = not label.visible
|
label.visible = not label.visible
|
||||||
UsesServerUps:set(player, label.visible)
|
UsesServerUps:set(player, label.visible)
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ export const plugin: lib.PluginDeclaration = {
|
|||||||
instanceEntrypoint: "./dist/node/instance",
|
instanceEntrypoint: "./dist/node/instance",
|
||||||
|
|
||||||
messages: [
|
messages: [
|
||||||
Messages.PluginExampleEvent,
|
|
||||||
Messages.PluginExampleRequest,
|
|
||||||
Messages.ExampleSubscribableUpdate,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
webEntrypoint: "./web",
|
webEntrypoint: "./web",
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
|
--[[-- Command Authorities - Roles
|
||||||
|
Adds a permission authority for exp roles
|
||||||
|
]]
|
||||||
|
|
||||||
local Commands = require("modules/exp_commands")
|
local Commands = require("modules/exp_commands")
|
||||||
local add, allow, deny = Commands.add_permission_authority, Commands.status.success, Commands.status.unauthorised
|
local add, allow, deny = Commands.add_permission_authority, Commands.status.success, Commands.status.unauthorised
|
||||||
|
|
||||||
local Roles = require("modules/exp_legacy/expcore/roles")
|
local Roles = require("modules/exp_legacy/expcore/roles")
|
||||||
|
local player_allowed = Roles.player_allowed
|
||||||
|
|
||||||
local authorities = {}
|
local authorities = {}
|
||||||
|
|
||||||
--- If a command has the flag "character_only" then the command can only be used outside of remote view
|
--- If a command has the flag "character_only" then the command can only be used outside of remote view
|
||||||
authorities.exp_permission =
|
authorities.exp_permission =
|
||||||
add(function(player, command)
|
add(function(player, command)
|
||||||
if not Roles.player_allowed(player, command.flags.exp_permission or ("command/" .. command)) then
|
if not player_allowed(player, command.flags.exp_permission or ("command/" .. command)) then
|
||||||
return deny{ "exp-commands-authorities_role.deny" }
|
return deny{ "exp-commands-authorities_role.deny" }
|
||||||
else
|
else
|
||||||
return allow()
|
return allow()
|
||||||
12
exp_scenario/module/commands/_rcon.lua
Normal file
12
exp_scenario/module/commands/_rcon.lua
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
--[[-- Command Rcon - ExpCore
|
||||||
|
Adds rcon interfaces for the legacy exp core
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local add_static, add_dynamic = Commands.add_rcon_static, Commands.add_rcon_dynamic
|
||||||
|
|
||||||
|
add_static("Group", require("modules.exp_legacy.expcore.permission_groups"))
|
||||||
|
add_static("Roles", require("modules.exp_legacy.expcore.roles"))
|
||||||
|
add_static("Gui", require("modules.exp_legacy.expcore.gui"))
|
||||||
|
add_static("Datastore", require("modules.exp_legacy.expcore.datastore"))
|
||||||
|
add_static("External", require("modules.exp_legacy.expcore.external"))
|
||||||
@@ -16,20 +16,13 @@ local valid, invalid = Commands.status.success, Commands.status.invalid_input
|
|||||||
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles")
|
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||||
local highest_role = Roles.get_player_highest_role
|
local highest_role = Roles.get_player_highest_role
|
||||||
local key_of_roles = Commands.types.key_of(Roles.config.roles)
|
|
||||||
|
|
||||||
local types = {}
|
local types = {} --- @class Commands._types
|
||||||
|
|
||||||
--- A role defined by exp roles
|
--- A role defined by exp roles
|
||||||
--- @type Commands.InputParser
|
types.role = add("role", Commands.types.key_of(Roles.config.roles))
|
||||||
types.role =
|
|
||||||
add("role", function(input, player)
|
|
||||||
local _, status, rtn = parse(input, player, key_of_roles)
|
|
||||||
return status, rtn
|
|
||||||
end)
|
|
||||||
|
|
||||||
--- A role which is lower than the players highest role
|
--- A role which is lower than the players highest role
|
||||||
--- @type Commands.InputParser
|
|
||||||
types.lower_role =
|
types.lower_role =
|
||||||
add("lower_role", function(input, player)
|
add("lower_role", function(input, player)
|
||||||
local success, status, result = parse(input, player, types.role)
|
local success, status, result = parse(input, player, types.role)
|
||||||
@@ -45,7 +38,6 @@ types.lower_role =
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
--- A player who is of a lower role than the executing player
|
--- A player who is of a lower role than the executing player
|
||||||
--- @type Commands.InputParser
|
|
||||||
types.lower_role_player =
|
types.lower_role_player =
|
||||||
add("lower_role_player", function(input, player)
|
add("lower_role_player", function(input, player)
|
||||||
local success, status, result = parse(input, player, Commands.types.player)
|
local success, status, result = parse(input, player, Commands.types.player)
|
||||||
@@ -62,9 +54,8 @@ types.lower_role_player =
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
--- A player who is of a lower role than the executing player
|
--- A player who is of a lower role than the executing player
|
||||||
--- @type Commands.InputParser
|
|
||||||
types.lower_role_player_online =
|
types.lower_role_player_online =
|
||||||
add("lower_role_player", function(input, player)
|
add("lower_role_player_online", function(input, player)
|
||||||
local success, status, result = parse(input, player, Commands.types.player_online)
|
local success, status, result = parse(input, player, Commands.types.player_online)
|
||||||
if not success then return status, result end
|
if not success then return status, result end
|
||||||
--- @cast result LuaPlayer
|
--- @cast result LuaPlayer
|
||||||
@@ -80,7 +71,7 @@ types.lower_role_player_online =
|
|||||||
|
|
||||||
--- A player who is of a lower role than the executing player
|
--- A player who is of a lower role than the executing player
|
||||||
types.lower_role_player_alive =
|
types.lower_role_player_alive =
|
||||||
add("lower_role_player", function(input, player)
|
add("lower_role_player_alive", function(input, player)
|
||||||
local success, status, result = parse(input, player, Commands.types.player_alive)
|
local success, status, result = parse(input, player, Commands.types.player_alive)
|
||||||
if not success then return status, result end
|
if not success then return status, result end
|
||||||
--- @cast result LuaPlayer
|
--- @cast result LuaPlayer
|
||||||
22
exp_scenario/module/commands/admin_chat.lua
Normal file
22
exp_scenario/module/commands/admin_chat.lua
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
--[[-- Commands - Admin Chat
|
||||||
|
Adds a command that allows admins to talk in a private chat
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
--- Sends a message in chat that only admins can see
|
||||||
|
Commands.new("admin-chat", { "exp-commands_admin-chat.description" })
|
||||||
|
:argument("message", { "exp-commands_admin-chat.arg-message" }, Commands.types.string)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "ac" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, message)
|
||||||
|
--- @cast message string
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
for _, next_player in ipairs(game.connected_players) do
|
||||||
|
if next_player.admin then
|
||||||
|
next_player.print{ "exp-commands_admin-chat.format", player_name, message }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
96
exp_scenario/module/commands/artillery.lua
Normal file
96
exp_scenario/module/commands/artillery.lua
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
--[[-- Commands - Artillery
|
||||||
|
Adds a command that helps shoot artillery
|
||||||
|
]]
|
||||||
|
|
||||||
|
local AABB = require("modules/exp_util/aabb")
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection
|
||||||
|
local SelectionName = "ExpCommand_Artillery"
|
||||||
|
|
||||||
|
local floor = math.floor
|
||||||
|
local abs = math.abs
|
||||||
|
|
||||||
|
--- @param player LuaPlayer
|
||||||
|
--- @param area BoundingBox
|
||||||
|
--- @return boolean
|
||||||
|
local function location_break(player, area)
|
||||||
|
local surface = player.surface -- Allow remote view
|
||||||
|
local is_charted = player.force.is_chunk_charted
|
||||||
|
if is_charted(surface, { x = floor(area.left_top.x / 32), y = floor(area.left_top.y / 32) }) then
|
||||||
|
return true
|
||||||
|
elseif is_charted(surface, { x = floor(area.left_top.x / 32), y = floor(area.right_bottom.y / 32) }) then
|
||||||
|
return true
|
||||||
|
elseif is_charted(surface, { x = floor(area.right_bottom.x / 32), y = floor(area.left_top.y / 32) }) then
|
||||||
|
return true
|
||||||
|
elseif is_charted(surface, { x = floor(area.right_bottom.x / 32), y = floor(area.right_bottom.y / 32) }) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Toggle player selection mode for artillery
|
||||||
|
Commands.new("artillery", { "exp-commands_artillery.description" })
|
||||||
|
:register(function(player)
|
||||||
|
if Selection.is_selecting(player, SelectionName) then
|
||||||
|
Selection.stop(player)
|
||||||
|
return Commands.status.success{ "exp-commands_artillery.exit" }
|
||||||
|
else
|
||||||
|
Selection.start(player, SelectionName)
|
||||||
|
return Commands.status.success{ "exp-commands_artillery.enter" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- when an area is selected to add protection to the area
|
||||||
|
Selection.on_selection(SelectionName, function(event)
|
||||||
|
--- @cast event EventData.on_player_selected_area
|
||||||
|
local area = AABB.expand(event.area)
|
||||||
|
local player = game.players[event.player_index]
|
||||||
|
local surface = event.surface
|
||||||
|
|
||||||
|
if not (player.cheat_mode or location_break(player, event.area)) then
|
||||||
|
player.print{ "exp-commands_artillery.invalid_area" }
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local entities = surface.find_entities_filtered{
|
||||||
|
area = area,
|
||||||
|
type = { "unit-spawner", "turret" },
|
||||||
|
force = "enemy"
|
||||||
|
}
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
local hits = {} --- @type MapPosition[]
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
local skip = false
|
||||||
|
|
||||||
|
for _, pos in ipairs(hits) do
|
||||||
|
local x = abs(entity.position.x - pos.x)
|
||||||
|
local y = abs(entity.position.y - pos.y)
|
||||||
|
if x * x + y * y < 36 then
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not skip then
|
||||||
|
surface.create_entity{
|
||||||
|
name = "artillery-flare",
|
||||||
|
position = entity.position,
|
||||||
|
force = player.force,
|
||||||
|
life_time = 240,
|
||||||
|
movement = { 0, 0 },
|
||||||
|
height = 0,
|
||||||
|
vertical_speed = 0,
|
||||||
|
frame_speed = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
count = count + 1
|
||||||
|
hits[count] = entity.position
|
||||||
|
|
||||||
|
if count > 400 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
28
exp_scenario/module/commands/bot_queue.lua
Normal file
28
exp_scenario/module/commands/bot_queue.lua
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
--[[-- Commands - Bot queue
|
||||||
|
Adds a command that allows viewing and changing the construction queue limits
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
--- Get / Set the current values for the bot queue
|
||||||
|
Commands.new("bot-queue", { "exp-commands_bot-queue.description" })
|
||||||
|
:optional("amount", { "exp-commands_bot-queue.arg-amount" }, Commands.types.integer_range(1, 20))
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, amount)
|
||||||
|
if amount then
|
||||||
|
player.force.max_successful_attempts_per_tick_per_construction_queue = 3 * amount
|
||||||
|
player.force.max_failed_attempts_per_tick_per_construction_queue = 5 * amount
|
||||||
|
game.print{
|
||||||
|
"exp-commands_bot-queue.set",
|
||||||
|
player.force.max_successful_attempts_per_tick_per_construction_queue,
|
||||||
|
player.force.max_failed_attempts_per_tick_per_construction_queue,
|
||||||
|
}
|
||||||
|
return Commands.status.success()
|
||||||
|
end
|
||||||
|
|
||||||
|
return Commands.status.success{
|
||||||
|
"exp-commands_bot-queue.get",
|
||||||
|
player.force.max_successful_attempts_per_tick_per_construction_queue,
|
||||||
|
player.force.max_failed_attempts_per_tick_per_construction_queue,
|
||||||
|
}
|
||||||
|
end)
|
||||||
132
exp_scenario/module/commands/cheat.lua
Normal file
132
exp_scenario/module/commands/cheat.lua
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
--[[-- Commands - Cheats
|
||||||
|
Adds commands for cheating such as unlocking all technology or settings always day
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
--- Toggles cheat mode for your player, or another player.
|
||||||
|
Commands.new("set-cheat-mode", { "exp-commands_cheat.description-cheat-mode" })
|
||||||
|
:optional("state", { "exp-commands_cheat.arg-state" }, Commands.types.boolean)
|
||||||
|
:optional("player", { "exp-commands_cheat.arg-player" }, Commands.types.player)
|
||||||
|
:add_aliases{ "cheat-mode", "toggle-cheat-mode" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
player = function(player) return player end,
|
||||||
|
}
|
||||||
|
:register(function(player, state, other_player)
|
||||||
|
--- @cast state boolean?
|
||||||
|
--- @cast player LuaPlayer
|
||||||
|
if state == nil then
|
||||||
|
other_player.cheat_mode = not other_player.cheat_mode
|
||||||
|
else
|
||||||
|
other_player.cheat_mode = state
|
||||||
|
end
|
||||||
|
return Commands.status.success{ "exp-commands_cheat.cheat-mode", other_player.cheat_mode }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Toggle always day for your surface, or another
|
||||||
|
Commands.new("set-always-day", { "exp-commands_cheat.description-always-day" })
|
||||||
|
:optional("state", { "exp-commands_cheat.arg-state" }, Commands.types.boolean)
|
||||||
|
:optional("surface", { "exp-commands_cheat.arg-surface" }, Commands.types.surface)
|
||||||
|
:add_aliases{ "always-day", "toggle-always-day" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
surface = function(player) return player.surface end
|
||||||
|
}
|
||||||
|
:register(function(player, state, surface)
|
||||||
|
--- @cast state boolean?
|
||||||
|
--- @cast surface LuaSurface
|
||||||
|
if state == nil then
|
||||||
|
surface.always_day = not surface.always_day
|
||||||
|
else
|
||||||
|
surface.always_day = state
|
||||||
|
end
|
||||||
|
game.print{ "exp-commands_cheat.always-day", format_player_name(player), surface.localised_name, surface.always_day }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Toggles friendly fire for your force or another
|
||||||
|
Commands.new("set-friendly-fire", { "exp-commands_cheat.description-friendly-fire" })
|
||||||
|
:optional("state", { "exp-commands_cheat.arg-state" }, Commands.types.boolean)
|
||||||
|
:optional("force", { "exp-commands_cheat.arg-force-friendly-fire" }, Commands.types.force)
|
||||||
|
:add_aliases{ "friendly-fire", "toggle-friendly-fire" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
force = function(player) return player.force end
|
||||||
|
}
|
||||||
|
:register(function(player, state, force)
|
||||||
|
--- @cast state boolean?
|
||||||
|
--- @cast force LuaForce
|
||||||
|
if state == nil then
|
||||||
|
force.friendly_fire = not force.friendly_fire
|
||||||
|
else
|
||||||
|
force.friendly_fire = state
|
||||||
|
end
|
||||||
|
game.print{ "exp-commands_cheat.friendly-fire", format_player_name(player), force.name, force.friendly_fire }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Research all technology on your force, or another force.
|
||||||
|
Commands.new("research-all", { "exp-commands_cheat.description-research-all" })
|
||||||
|
:optional("force", { "exp-commands_cheat.arg-force-research" }, Commands.types.force)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
force = function(player) return player.force end
|
||||||
|
}
|
||||||
|
:register(function(player, force)
|
||||||
|
--- @cast force LuaForce
|
||||||
|
force.research_all_technologies()
|
||||||
|
game.print{ "exp-commands_cheat.research-all", format_player_name(player), force.name }
|
||||||
|
return Commands.status.success()
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clear all pollution from your surface or another
|
||||||
|
Commands.new("clear-pollution", { "exp-commands_cheat.description-clear-pollution" })
|
||||||
|
:optional("surface", { "exp-commands_cheat.arg-surface" }, Commands.types.surface)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
surface = function(player) return player.surface end -- Allow remote view
|
||||||
|
}
|
||||||
|
:register(function(player, surface)
|
||||||
|
--- @cast surface LuaSurface
|
||||||
|
surface.clear_pollution()
|
||||||
|
game.print{ "exp-commands_cheat.clear-pollution", format_player_name(player), surface.localised_name }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Toggles pollution being enabled in the game
|
||||||
|
Commands.new("set-pollution-enabled", { "exp-commands_cheat.description-pollution-enabled" })
|
||||||
|
:optional("state", { "exp-commands_cheat.arg-state" }, Commands.types.boolean)
|
||||||
|
:add_aliases{ "disable-pollution", "toggle-pollution-enabled" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, state)
|
||||||
|
--- @cast state boolean?
|
||||||
|
if state == nil then
|
||||||
|
game.map_settings.pollution.enabled = not game.map_settings.pollution.enabled
|
||||||
|
else
|
||||||
|
game.map_settings.pollution.enabled = state
|
||||||
|
end
|
||||||
|
|
||||||
|
if game.map_settings.pollution.enabled == false then
|
||||||
|
for _, surface in pairs(game.surfaces) do
|
||||||
|
surface.clear_pollution()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
game.print{ "exp-commands_cheat.pollution-enabled", format_player_name(player), game.map_settings.pollution.enabled }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Set or get the game speed
|
||||||
|
Commands.new("set-game-speed", { "exp-commands_cheat.description-game-speed" })
|
||||||
|
:optional("amount", { "exp-commands_cheat.arg-amount" }, Commands.types.number_range(0.2, 10))
|
||||||
|
:add_aliases{ "game-speed" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, amount)
|
||||||
|
--- @cast amount number?
|
||||||
|
if amount then
|
||||||
|
game.speed = math.round(amount, 3)
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
game.print{ "exp-commands_cheat.game-speed-set", player_name, game.speed }
|
||||||
|
return Commands.status.success()
|
||||||
|
else
|
||||||
|
return Commands.status.success{ "exp-commands_cheat.game-speed-get", game.speed }
|
||||||
|
end
|
||||||
|
end)
|
||||||
26
exp_scenario/module/commands/clear_inventory.lua
Normal file
26
exp_scenario/module/commands/clear_inventory.lua
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
--[[-- Commands - Clear Inventory
|
||||||
|
Adds a command that allows admins to clear people's inventory
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
local transfer_inventory = ExpUtil.transfer_inventory_to_surface
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
--- Clears a players inventory
|
||||||
|
Commands.new("clear-inventory", { "exp-commands_clear-inventory.description" })
|
||||||
|
:argument("player", { "exp-commands_clear-inventory.arg-player" }, Commands.types.lower_role_player)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
local inventory = other_player.get_main_inventory()
|
||||||
|
if not inventory then
|
||||||
|
return Commands.status.error{ "expcore-commands.reject-player-alive" }
|
||||||
|
end
|
||||||
|
|
||||||
|
transfer_inventory{
|
||||||
|
inventory = inventory,
|
||||||
|
surface = game.planets.nauvis.surface,
|
||||||
|
name = "iron-chest",
|
||||||
|
allow_creation = true,
|
||||||
|
}
|
||||||
|
end)
|
||||||
111
exp_scenario/module/commands/connect.lua
Normal file
111
exp_scenario/module/commands/connect.lua
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
--[[-- Commands - Connect
|
||||||
|
Adds a commands that allows you to request a player move to another server
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Async = require("modules/exp_util/async")
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
||||||
|
local request_connection_async = Async.register(External.request_connection)
|
||||||
|
|
||||||
|
local concat = table.concat
|
||||||
|
|
||||||
|
--- Convert a server name into a server id, is not an Commands.InputParser because it does not accept addresses
|
||||||
|
--- @param server string
|
||||||
|
--- @return boolean, LocalisedString # True for success
|
||||||
|
local function get_server_id(server)
|
||||||
|
local servers = External.get_servers_filtered(server)
|
||||||
|
local current_server = External.get_current_server()
|
||||||
|
local current_version = current_server.version
|
||||||
|
|
||||||
|
local server_names_before, server_names = {}, {}
|
||||||
|
local server_count_before, server_count = 0, 0
|
||||||
|
for next_server_id, server_details in pairs(servers) do
|
||||||
|
server_count_before = server_count_before + 1
|
||||||
|
server_names_before[server_count_before] = server_details.name
|
||||||
|
if server_details.version == current_version then
|
||||||
|
server_count = server_count + 1
|
||||||
|
server_names[server_count] = server_details.name
|
||||||
|
else
|
||||||
|
servers[next_server_id] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if server_count > 1 then
|
||||||
|
return false, { "exp-commands_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, { "exp-commands_connect.same-server", server_details.name }
|
||||||
|
elseif status == "Offline" then
|
||||||
|
return false, { "exp-commands_connect.offline", server_details.name }
|
||||||
|
end
|
||||||
|
return true, server_id
|
||||||
|
elseif server_count_before > 0 then
|
||||||
|
return false, { "exp-commands_connect.wrong-version", concat(server_names_before, ", ") }
|
||||||
|
else
|
||||||
|
return false, { "exp-commands_connect.none-matching" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Connect to a different server
|
||||||
|
Commands.new("connect", { "exp-commands_connect.description" })
|
||||||
|
:argument("server", { "exp-commands_connect.arg-server" }, Commands.types.string)
|
||||||
|
:optional("is-address", { "exp-commands_connect.is-address" }, Commands.types.boolean)
|
||||||
|
:add_aliases{ "join" }
|
||||||
|
:register(function(player, server, is_address)
|
||||||
|
--- @cast server string
|
||||||
|
--- @cast is_address boolean?
|
||||||
|
if not is_address and External.valid() then
|
||||||
|
local success, result = get_server_id(server)
|
||||||
|
if not success then
|
||||||
|
return Commands.status.invalid_input(result)
|
||||||
|
end
|
||||||
|
server = result
|
||||||
|
end
|
||||||
|
|
||||||
|
request_connection_async(player, server, true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Connect another player to a different server
|
||||||
|
Commands.new("connect-player", { "exp-commands_connect.description-player" })
|
||||||
|
:argument("player", { "exp-commands_connect.arg-player" }, Commands.types.player_online)
|
||||||
|
:argument("server", { "exp-commands_connect.arg-server" }, Commands.types.string)
|
||||||
|
:optional("is-address", { "exp-commands_connect.is-address" }, Commands.types.boolean)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, server, is_address)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast server string
|
||||||
|
--- @cast is_address boolean?
|
||||||
|
if not is_address and External.valid() then
|
||||||
|
local success, result = get_server_id(server)
|
||||||
|
if not success then
|
||||||
|
return Commands.status.invalid_input(result)
|
||||||
|
end
|
||||||
|
server = result
|
||||||
|
end
|
||||||
|
|
||||||
|
request_connection_async(other_player, server)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Connect all players to a different server
|
||||||
|
Commands.new("connect-all", { "exp-commands_connect.description-all" })
|
||||||
|
:argument("server", { "exp-commands_connect.arg-server" }, Commands.types.string)
|
||||||
|
:optional("is-address", { "exp-commands_connect.is-address" }, Commands.types.boolean)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, server, is_address)
|
||||||
|
--- @cast server string
|
||||||
|
--- @cast is_address boolean?
|
||||||
|
if not is_address and External.valid() then
|
||||||
|
local success, result = get_server_id(server)
|
||||||
|
if not success then
|
||||||
|
return Commands.status.invalid_input(result)
|
||||||
|
end
|
||||||
|
server = result
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, next_player in pairs(game.connected_players) do
|
||||||
|
request_connection_async(next_player, server)
|
||||||
|
end
|
||||||
|
end)
|
||||||
10
exp_scenario/module/commands/debug.lua
Normal file
10
exp_scenario/module/commands/debug.lua
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
--[[-- Commands - Debug
|
||||||
|
Adds a command that opens the debug frame
|
||||||
|
]]
|
||||||
|
|
||||||
|
local DebugView = require("modules.exp_legacy.modules.gui.debug.main_view") --- @dep modules.gui.debug.main_view
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
--- Opens the debug gui.
|
||||||
|
Commands.new("debug", { "exp-commands_debug.description" })
|
||||||
|
:register(DebugView.open_debug)
|
||||||
30
exp_scenario/module/commands/enemy.lua
Normal file
30
exp_scenario/module/commands/enemy.lua
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
--[[-- Commands - Enemy
|
||||||
|
Adds a commands of handling the enemy force, such as killing all or disabling them
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
--- Kill all enemies
|
||||||
|
Commands.new("kill-enemies", { "exp-commands_enemy.description-kill" })
|
||||||
|
:add_aliases{ "kill-biters" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player)
|
||||||
|
game.forces["enemy"].kill_all_units()
|
||||||
|
game.print{ "exp-commands_enemy.kill", player.name }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Remove all enemies on a surface
|
||||||
|
Commands.new("remove-enemies", { "exp-commands_enemy.description-remove" })
|
||||||
|
:optional("surface", { "exp-commands_enemy.arg-surface" }, Commands.types.surface)
|
||||||
|
:add_aliases{ "remove-biters" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:defaults{
|
||||||
|
surface = function(player) return player.surface end
|
||||||
|
}
|
||||||
|
:register(function(player, surface)
|
||||||
|
for _, entity in pairs(surface.find_entities_filtered{ force = "enemy" }) do
|
||||||
|
entity.destroy()
|
||||||
|
end
|
||||||
|
-- surface.map_gen_settings.autoplace_controls["enemy-base"].size = "none" -- TODO make this work for SA
|
||||||
|
game.print{ "exp-commands_enemy.remove", player.name }
|
||||||
|
end)
|
||||||
116
exp_scenario/module/commands/home.lua
Normal file
116
exp_scenario/module/commands/home.lua
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
--[[-- Commands - Home
|
||||||
|
Adds a command that allows setting and teleporting to your home position
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
local teleport = ExpUtil.teleport_player
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local Storage = require("modules/exp_util/storage")
|
||||||
|
|
||||||
|
--- @type table<number, table<number, [MapPosition?, MapPosition?]>>
|
||||||
|
local homes = {} -- homes[player_index][surface_index] = { home_pos, return_pos }
|
||||||
|
Storage.register(homes, function(tbl)
|
||||||
|
homes = tbl
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Align a position to the grid
|
||||||
|
--- @param position MapPosition The position to align
|
||||||
|
--- @return MapPosition, MapPosition
|
||||||
|
local function align_to_grid(position)
|
||||||
|
return {
|
||||||
|
x = math.floor(position.x) + math.sign(position.x) * 0.5,
|
||||||
|
y = math.floor(position.y) + math.sign(position.x) * 0.5,
|
||||||
|
}, {
|
||||||
|
x = math.floor(position.x),
|
||||||
|
y = math.floor(position.y),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Teleports you to your home location on the current surface
|
||||||
|
Commands.new("home", { "exp-commands_home.description-home" })
|
||||||
|
:add_flags{ "character_only" }
|
||||||
|
:register(function(player)
|
||||||
|
local surface = player.surface
|
||||||
|
|
||||||
|
local player_homes = homes[player.index]
|
||||||
|
if not player_homes then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-home", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_home = player_homes[surface.index]
|
||||||
|
if not player_home or not player_home[1] then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-home", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local return_position, floor_position = align_to_grid(player.position)
|
||||||
|
teleport(player, surface, player_home[1])
|
||||||
|
player_home[2] = return_position
|
||||||
|
return Commands.status.success{ "exp-commands_home.return-set", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Teleports you to your previous location on the current surface
|
||||||
|
Commands.new("return", { "exp-commands_home.description-return" })
|
||||||
|
:add_flags{ "character_only" }
|
||||||
|
:register(function(player)
|
||||||
|
local surface = player.surface
|
||||||
|
|
||||||
|
local player_homes = homes[player.index]
|
||||||
|
if not player_homes then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-return", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_home = player_homes[surface.index]
|
||||||
|
if not player_home or not player_home[2] then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-return", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local return_position, floor_position = align_to_grid(player.position)
|
||||||
|
teleport(player, surface, player_home[2])
|
||||||
|
player_home[2] = return_position
|
||||||
|
return Commands.status.success{ "exp-commands_home.return-set", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Sets your home location on your current surface to your current position
|
||||||
|
Commands.new("set-home", { "exp-commands_home.description-set" })
|
||||||
|
:add_flags{ "character_only" }
|
||||||
|
:register(function(player)
|
||||||
|
local home_position, floor_position = align_to_grid(player.position)
|
||||||
|
local surface = player.surface
|
||||||
|
|
||||||
|
local player_homes = homes[player.index]
|
||||||
|
if not player_homes then
|
||||||
|
homes[player.index] = {
|
||||||
|
[surface.index] = { home_position, nil }
|
||||||
|
}
|
||||||
|
return Commands.status.success{ "exp-commands_home.home-set", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_home = player_homes[surface.index]
|
||||||
|
if not player_home then
|
||||||
|
player_homes[surface.index] = { home_position, nil }
|
||||||
|
return Commands.status.success{ "exp-commands_home.home-set", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end
|
||||||
|
|
||||||
|
player_home[1] = home_position
|
||||||
|
return Commands.status.success{ "exp-commands_home.home-set", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Gets your home location on your current surface, is allowed in remote view
|
||||||
|
Commands.new("get-home", { "exp-commands_home.description-get" })
|
||||||
|
:register(function(player)
|
||||||
|
local surface = player.surface
|
||||||
|
|
||||||
|
local player_homes = homes[player.index]
|
||||||
|
if not player_homes then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-home", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_home = player_homes[surface.index]
|
||||||
|
if not player_home or not player_home[1] then
|
||||||
|
return Commands.status.error{ "exp-commands_home.no-home", surface.localised_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local _, floor_position = align_to_grid(player_home[1])
|
||||||
|
return Commands.status.success{ "exp-commands_home.home-get", surface.localised_name, floor_position.x, floor_position.y }
|
||||||
|
end)
|
||||||
43
exp_scenario/module/commands/jail.lua
Normal file
43
exp_scenario/module/commands/jail.lua
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
--[[-- Commands - Jail
|
||||||
|
Adds a commands that allow admins to jail and unjail
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local Jail = require("modules.exp_legacy.modules.control.jail") --- @dep modules.control.jail
|
||||||
|
|
||||||
|
--- Puts a player into jail and removes all other roles.
|
||||||
|
Commands.new("jail", { "exp-commands_jail.description" })
|
||||||
|
:argument("player", { "exp-commands_jail.arg-player" }, Commands.types.lower_role_player)
|
||||||
|
:optional("reason", { "exp-commands_jail.arg-reason" }, Commands.types.string)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:register(function(player, other_player, reason)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast reason string?
|
||||||
|
if not reason then
|
||||||
|
reason = "None Given."
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
if Jail.jail_player(other_player, player.name, reason) then
|
||||||
|
game.print{ "exp-commands_jail.jailed", other_player_name, player_name, reason }
|
||||||
|
else
|
||||||
|
return Commands.status.error{ "exp-commands_jail.already-jailed", other_player_name }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Removes a player from jail and restores their old roles.
|
||||||
|
Commands.new("unjail", { "exp-commands_unjail.description" })
|
||||||
|
:argument("player", { "exp-commands_unjail.arg-player" }, Commands.types.lower_role_player)
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
if Jail.unjail_player(other_player, player.name) then
|
||||||
|
game.print{ "exp-commands_unjail.unjailed", other_player_name, player_name }
|
||||||
|
else
|
||||||
|
return Commands.status.error{ "exp-commands_unjail.not-jailed", other_player_name }
|
||||||
|
end
|
||||||
|
end)
|
||||||
32
exp_scenario/module/commands/kill.lua
Normal file
32
exp_scenario/module/commands/kill.lua
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
--[[-- Commands - Kill
|
||||||
|
Adds a command that allows players to kill themselves and others
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
|
local highest_role = Roles.get_player_highest_role
|
||||||
|
|
||||||
|
--- Kills yourself or another player.
|
||||||
|
Commands.new("kill", { "exp-commands_kill.description" })
|
||||||
|
:optional("player", { "exp-commands_kill.arg-player" }, Commands.types.lower_role_player_alive)
|
||||||
|
:defaults{
|
||||||
|
player = function(player)
|
||||||
|
return player.character and player.character.health > 0 and player or nil
|
||||||
|
end
|
||||||
|
}
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer?
|
||||||
|
if other_player == nil then
|
||||||
|
-- Can only be nil if the target is the player and they are already dead
|
||||||
|
return Commands.status.error{ "exp-commands_kill.already-dead" }
|
||||||
|
elseif other_player == player then
|
||||||
|
-- You can always kill yourself
|
||||||
|
other_player.character.die()
|
||||||
|
elseif highest_role(other_player).index < highest_role(player).index then
|
||||||
|
-- Can kill lower role players
|
||||||
|
other_player.character.die()
|
||||||
|
else
|
||||||
|
return Commands.status.unauthorised{ "exp-commands_kill.lower-role" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
52
exp_scenario/module/commands/lawnmower.lua
Normal file
52
exp_scenario/module/commands/lawnmower.lua
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
--[[-- Commands - Lawnmower
|
||||||
|
Adds a command that clean up biter corpse and nuclear hole
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local config = require("modules.exp_legacy.config.lawnmower") --- @dep config.lawnmower
|
||||||
|
|
||||||
|
Commands.new("lawnmower", { "exp-commands_lawnmower.description" })
|
||||||
|
:argument("range", { "exp-commands_lawnmower.arg-range" }, Commands.types.integer_range(1, 200))
|
||||||
|
:register(function(player, range)
|
||||||
|
--- @cast range number
|
||||||
|
local surface = player.surface
|
||||||
|
|
||||||
|
-- Intentionally left as player.position to allow use in remote view
|
||||||
|
local entities = 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
|
||||||
|
|
||||||
|
local replace_tiles = {}
|
||||||
|
local tiles = surface.find_tiles_filtered{ position = player.position, radius = range, name = { "nuclear-ground" } }
|
||||||
|
for i, tile in pairs(tiles) do
|
||||||
|
replace_tiles[i] = { name = "grass-1", position = tile.position }
|
||||||
|
end
|
||||||
|
|
||||||
|
surface.set_tiles(replace_tiles)
|
||||||
|
surface.destroy_decoratives{ position = player.position, radius = range }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- @param event EventData.on_built_entity | EventData.on_robot_built_entity | EventData.script_raised_built | EventData.script_raised_revive
|
||||||
|
local function destroy_decoratives(event)
|
||||||
|
local entity = event.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 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = defines.events
|
||||||
|
local events = {}
|
||||||
|
|
||||||
|
if config.destroy_decoratives then
|
||||||
|
events[e.on_built_entity] = destroy_decoratives
|
||||||
|
events[e.on_robot_built_entity] = destroy_decoratives
|
||||||
|
events[e.script_raised_built] = destroy_decoratives
|
||||||
|
events[e.script_raised_revive] = destroy_decoratives
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
events = events
|
||||||
|
}
|
||||||
40
exp_scenario/module/commands/locate.lua
Normal file
40
exp_scenario/module/commands/locate.lua
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
--[[-- Commands - Locate
|
||||||
|
Adds a command that will return the last location of a player
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local format = string.format
|
||||||
|
|
||||||
|
--- Open remote view at a players last location
|
||||||
|
Commands.new("locate", { "exp-commands_locate.description" })
|
||||||
|
:add_aliases{ "last-location", "find" }
|
||||||
|
:argument("player", { "exp-commands_locate.arg-player" }, Commands.types.player)
|
||||||
|
:optional("remote", { "exp-commands_locate.arg-remote" }, Commands.types.boolean)
|
||||||
|
:register(function(player, other_player, remote)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast remote boolean?
|
||||||
|
local surface = other_player.physical_surface
|
||||||
|
local position = other_player.physical_position
|
||||||
|
if remote and other_player.controller_type == defines.controllers.remote then
|
||||||
|
surface = other_player.surface
|
||||||
|
position = other_player.position
|
||||||
|
end
|
||||||
|
|
||||||
|
if player.index > 0 then
|
||||||
|
-- This check allows rcon to use the command
|
||||||
|
player.set_controller{
|
||||||
|
type = defines.controllers.remote,
|
||||||
|
surface = surface,
|
||||||
|
position = position,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return Commands.status.success{
|
||||||
|
"exp-commands_locate.response",
|
||||||
|
format_player_name(other_player),
|
||||||
|
format("%.1f", position.x),
|
||||||
|
format("%.1f", position.y),
|
||||||
|
}
|
||||||
|
end)
|
||||||
14
exp_scenario/module/commands/me.lua
Normal file
14
exp_scenario/module/commands/me.lua
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
--[[-- Commands - Me
|
||||||
|
Adds a command that adds * around your message in the chat
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_text = Commands.format_rich_text_color_locale
|
||||||
|
|
||||||
|
--- Sends an action message in the chat
|
||||||
|
Commands.new("me", { "exp-commands_me.description" })
|
||||||
|
:argument("action", { "exp-commands_me.arg-action" }, Commands.types.string)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:register(function(player, action)
|
||||||
|
game.print(format_text({ "exp-commands_me.response", player.name, action, }, player.chat_color))
|
||||||
|
end)
|
||||||
@@ -1,63 +1,56 @@
|
|||||||
--[[-- Commands Module - Protection
|
--[[-- Commands - Protection
|
||||||
- Adds commands that can add and remove protection
|
Adds commands that can add and remove protection
|
||||||
@commands Protection
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
|
||||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
||||||
local Storage = require("modules/exp_util/storage")
|
local Storage = require("modules/exp_util/storage")
|
||||||
|
|
||||||
|
local AABB = require("modules/exp_util/aabb")
|
||||||
|
local contains_area = AABB.contains_area
|
||||||
|
local expand_area = AABB.expand
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
||||||
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
||||||
local EntityProtection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection
|
|
||||||
local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection
|
local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection
|
||||||
|
local EntityProtection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection
|
||||||
|
|
||||||
local SelectionProtectEntity = "ProtectEntity"
|
local format_string = string.format
|
||||||
local SelectionProtectArea = "ProtectArea"
|
local floor = math.floor
|
||||||
|
|
||||||
local renders = {} -- Stores all renders for a player
|
local SelectionName_Entity = "ExpCommand_ProtectEntity"
|
||||||
|
local SelectionName_Area = "ExpCommand_ProtectArea"
|
||||||
|
|
||||||
|
local renders = {} --- @type table<number, table<string, LuaRenderObject>> Stores all renders for a player
|
||||||
Storage.register({
|
Storage.register({
|
||||||
renders = renders,
|
renders = renders,
|
||||||
}, function(tbl)
|
}, function(tbl)
|
||||||
renders = tbl.renders
|
renders = tbl.renders
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Test if a point is inside an aabb
|
|
||||||
local function aabb_point_enclosed(point, aabb)
|
|
||||||
return point.x >= aabb.left_top.x and point.y >= aabb.left_top.y
|
|
||||||
and point.x <= aabb.right_bottom.x and point.y <= aabb.right_bottom.y
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Test if an aabb is inside another aabb
|
|
||||||
local function aabb_area_enclosed(aabb_one, aabb_two)
|
|
||||||
return aabb_point_enclosed(aabb_one.left_top, aabb_two)
|
|
||||||
and aabb_point_enclosed(aabb_one.right_bottom, aabb_two)
|
|
||||||
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) },
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get the key used in protected_entities
|
--- Get the key used in protected_entities
|
||||||
|
--- @param entity LuaEntity
|
||||||
|
--- @return string
|
||||||
local function get_entity_key(entity)
|
local function get_entity_key(entity)
|
||||||
return string.format("%i,%i", math.floor(entity.position.x), math.floor(entity.position.y))
|
return format_string("%i,%i", floor(entity.position.x), floor(entity.position.y))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the key used in protected_areas
|
--- Get the key used in protected_areas
|
||||||
|
--- TODO expose this from EntityProtection
|
||||||
|
--- @param area BoundingBox
|
||||||
|
--- @return string
|
||||||
local function get_area_key(area)
|
local function get_area_key(area)
|
||||||
return string.format("%i,%i", math.floor(area.left_top.x), math.floor(area.left_top.y))
|
return format_string("%i,%i", floor(area.left_top.x), floor(area.left_top.y))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Show a protected entity to a player
|
--- Show a protected entity to a player
|
||||||
|
--- @param player LuaPlayer
|
||||||
|
--- @param entity LuaEntity
|
||||||
local function show_protected_entity(player, entity)
|
local function show_protected_entity(player, entity)
|
||||||
local key = get_entity_key(entity)
|
local key = get_entity_key(entity)
|
||||||
if renders[player.index][key] then return end
|
if renders[player.index][key] then return end
|
||||||
local rb = entity.selection_box.right_bottom
|
local rb = entity.selection_box.right_bottom
|
||||||
local render_id = rendering.draw_sprite{
|
renders[player.index][key] = rendering.draw_sprite{
|
||||||
sprite = "utility/notification",
|
sprite = "utility/notification",
|
||||||
target = entity,
|
target = entity,
|
||||||
target_offset = {
|
target_offset = {
|
||||||
@@ -69,14 +62,16 @@ local function show_protected_entity(player, entity)
|
|||||||
surface = entity.surface,
|
surface = entity.surface,
|
||||||
players = { player },
|
players = { player },
|
||||||
}
|
}
|
||||||
renders[player.index][key] = render_id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Show a protected area to a player
|
--- Show a protected area to a player
|
||||||
|
--- @param player LuaPlayer
|
||||||
|
--- @param surface LuaSurface
|
||||||
|
--- @param area BoundingBox
|
||||||
local function show_protected_area(player, surface, area)
|
local function show_protected_area(player, surface, area)
|
||||||
local key = get_area_key(area)
|
local key = get_area_key(area)
|
||||||
if renders[player.index][key] then return end
|
if renders[player.index][key] then return end
|
||||||
local render_id = rendering.draw_rectangle{
|
renders[player.index][key] = rendering.draw_rectangle{
|
||||||
color = { 1, 1, 0, 0.5 },
|
color = { 1, 1, 0, 0.5 },
|
||||||
filled = false,
|
filled = false,
|
||||||
width = 3,
|
width = 3,
|
||||||
@@ -85,101 +80,108 @@ local function show_protected_area(player, surface, area)
|
|||||||
surface = surface,
|
surface = surface,
|
||||||
players = { player },
|
players = { player },
|
||||||
}
|
}
|
||||||
renders[player.index][key] = render_id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Remove a render object for a player
|
--- Remove a render object for a player
|
||||||
|
--- @param player LuaPlayer
|
||||||
|
--- @param key string
|
||||||
local function remove_render(player, key)
|
local function remove_render(player, key)
|
||||||
local render = renders[player.index][key] --[[@as LuaRenderObject]]
|
local render = renders[player.index][key]
|
||||||
if render and render.valid then render.destroy() end
|
if render and render.valid then render.destroy() end
|
||||||
renders[player.index][key] = nil
|
renders[player.index][key] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Toggles entity protection selection
|
--- Toggles entity protection selection
|
||||||
-- @command protect-entity
|
Commands.new("protect-entity", { "exp-commands_protection.description-entity" })
|
||||||
Commands.new_command("protect-entity", { "expcom-protection.description-pe" }, "Toggles entity protection selection, hold shift to remove protection")
|
:add_aliases{ "pe" }
|
||||||
:add_alias("pe")
|
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
if Selection.is_selecting(player, SelectionProtectEntity) then
|
if Selection.is_selecting(player, SelectionName_Entity) then
|
||||||
Selection.stop(player)
|
Selection.stop(player)
|
||||||
|
return Commands.status.success{ "exp-commands_protection.exit-entity" }
|
||||||
else
|
else
|
||||||
Selection.start(player, SelectionProtectEntity)
|
Selection.start(player, SelectionName_Entity)
|
||||||
return Commands.success{ "expcom-protection.entered-entity-selection" }
|
return Commands.status.success{ "exp-commands_protection.enter-entity" }
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Toggles area protection selection
|
--- Toggles area protection selection
|
||||||
-- @command protect-area
|
Commands.new("protect-area", { "exp-commands_protection.description-area" })
|
||||||
Commands.new_command("protect-area", { "expcom-protection.description-pa" }, "Toggles area protection selection, hold shift to remove protection")
|
:add_aliases{ "pa" }
|
||||||
:add_alias("pa")
|
|
||||||
:register(function(player)
|
:register(function(player)
|
||||||
if Selection.is_selecting(player, SelectionProtectArea) then
|
if Selection.is_selecting(player, SelectionName_Entity) then
|
||||||
Selection.stop(player)
|
Selection.stop(player)
|
||||||
|
return Commands.status.success{ "exp-commands_protection.exit-area" }
|
||||||
else
|
else
|
||||||
Selection.start(player, SelectionProtectArea)
|
Selection.start(player, SelectionName_Entity)
|
||||||
return Commands.success{ "expcom-protection.entered-area-selection" }
|
return Commands.status.success{ "exp-commands_protection.enter-area" }
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When an area is selected to add protection to entities
|
--- When an area is selected to add protection to entities
|
||||||
Selection.on_selection(SelectionProtectEntity, function(event)
|
Selection.on_selection(SelectionName_Entity, function(event)
|
||||||
|
--- @cast event EventData.on_player_selected_area
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
for _, entity in ipairs(event.entities) do
|
for _, entity in ipairs(event.entities) do
|
||||||
EntityProtection.add_entity(entity)
|
EntityProtection.add_entity(entity)
|
||||||
show_protected_entity(player, entity)
|
show_protected_entity(player, entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
player.print{ "expcom-protection.protected-entities", #event.entities }
|
player.print({ "exp-commands_protection.protected-entities", #event.entities }, Commands.print_settings.default)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When an area is selected to remove protection from entities
|
--- When an area is selected to remove protection from entities
|
||||||
Selection.on_alt_selection(SelectionProtectEntity, function(event)
|
Selection.on_alt_selection(SelectionName_Entity, function(event)
|
||||||
|
--- @cast event EventData.on_player_alt_selected_area
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
for _, entity in ipairs(event.entities) do
|
for _, entity in ipairs(event.entities) do
|
||||||
EntityProtection.remove_entity(entity)
|
EntityProtection.remove_entity(entity)
|
||||||
remove_render(player, get_entity_key(entity))
|
remove_render(player, get_entity_key(entity))
|
||||||
end
|
end
|
||||||
|
|
||||||
player.print{ "expcom-protection.unprotected-entities", #event.entities }
|
player.print({ "exp-commands_protection.unprotected-entities", #event.entities }, Commands.print_settings.default)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When an area is selected to add protection to the area
|
--- When an area is selected to add protection to the area
|
||||||
Selection.on_selection(SelectionProtectArea, function(event)
|
Selection.on_selection(SelectionName_Area, function(event)
|
||||||
local area = aabb_align_expand(event.area)
|
--- @cast event EventData.on_player_selected_area
|
||||||
|
local surface = event.surface
|
||||||
|
local area = expand_area(event.area)
|
||||||
local areas = EntityProtection.get_areas(event.surface)
|
local areas = EntityProtection.get_areas(event.surface)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
for _, next_area in pairs(areas) do
|
for _, next_area in pairs(areas) do
|
||||||
if aabb_area_enclosed(area, next_area) then
|
if contains_area(next_area, area) then
|
||||||
return player.print{ "expcom-protection.already-protected" }
|
return player.print({ "exp-commands_protection.already-protected" }, Commands.print_settings.error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
EntityProtection.add_area(event.surface, area)
|
EntityProtection.add_area(surface, area)
|
||||||
show_protected_area(player, event.surface, area)
|
show_protected_area(player, surface, area)
|
||||||
player.print{ "expcom-protection.protected-area" }
|
player.print({ "exp-commands_protection.protected-area" }, Commands.print_settings.default)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When an area is selected to remove protection from the area
|
--- When an area is selected to remove protection from the area
|
||||||
Selection.on_alt_selection(SelectionProtectArea, function(event)
|
Selection.on_alt_selection(SelectionName_Area, function(event)
|
||||||
local area = aabb_align_expand(event.area)
|
--- @cast event EventData.on_player_alt_selected_area
|
||||||
local areas = EntityProtection.get_areas(event.surface)
|
local surface = event.surface
|
||||||
|
local area = expand_area(event.area)
|
||||||
|
local areas = EntityProtection.get_areas(surface)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
for _, next_area in pairs(areas) do
|
for _, next_area in pairs(areas) do
|
||||||
if aabb_area_enclosed(next_area, area) then
|
if contains_area(area, next_area) then
|
||||||
EntityProtection.remove_area(event.surface, next_area)
|
EntityProtection.remove_area(surface, next_area)
|
||||||
player.print{ "expcom-protection.unprotected-area" }
|
player.print({ "exp-commands_protection.unprotected-area" }, Commands.print_settings.default)
|
||||||
remove_render(player, get_area_key(next_area))
|
remove_render(player, get_area_key(next_area))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When selection starts show all protected entities and protected areas
|
--- When selection starts show all protected entities and protected areas
|
||||||
Event.add(Selection.events.on_player_selection_start, function(event)
|
local function on_player_selection_start(event)
|
||||||
if event.selection ~= SelectionProtectEntity and event.selection ~= SelectionProtectArea then return end
|
if event.selection ~= SelectionName_Entity and event.selection ~= SelectionName_Area then return end
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
-- Intentionally left as player.surface to allow use in remote view
|
local surface = player.surface -- Allow remote view
|
||||||
local surface = player.surface
|
|
||||||
renders[player.index] = {}
|
renders[player.index] = {}
|
||||||
|
|
||||||
-- Show protected entities
|
-- Show protected entities
|
||||||
local entities = EntityProtection.get_entities(surface)
|
local entities = EntityProtection.get_entities(surface)
|
||||||
for _, entity in pairs(entities) do
|
for _, entity in pairs(entities) do
|
||||||
@@ -192,31 +194,46 @@ Event.add(Selection.events.on_player_selection_start, function(event)
|
|||||||
show_protected_entity(player, entity)
|
show_protected_entity(player, entity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Show always protected entities by type
|
-- Show always protected entities by type
|
||||||
if #EntityProtection.protected_entity_types > 0 then
|
if #EntityProtection.protected_entity_types > 0 then
|
||||||
for _, entity in pairs(surface.find_entities_filtered{ type = EntityProtection.protected_entity_types, force = player.force }) do
|
for _, entity in pairs(surface.find_entities_filtered{ type = EntityProtection.protected_entity_types, force = player.force }) do
|
||||||
show_protected_entity(player, entity)
|
show_protected_entity(player, entity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Show protected areas
|
-- Show protected areas
|
||||||
local areas = EntityProtection.get_areas(surface)
|
local areas = EntityProtection.get_areas(surface)
|
||||||
for _, area in pairs(areas) do
|
for _, area in pairs(areas) do
|
||||||
show_protected_area(player, surface, area)
|
show_protected_area(player, surface, area)
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
|
||||||
--- When selection ends hide protected entities and protected areas
|
--- When selection ends hide protected entities and protected areas
|
||||||
Event.add(Selection.events.on_player_selection_end, function(event)
|
local function on_player_selection_end(event)
|
||||||
if event.selection ~= SelectionProtectEntity and event.selection ~= SelectionProtectArea then return end
|
if event.selection ~= SelectionName_Entity and event.selection ~= SelectionName_Area then return end
|
||||||
for _, render in pairs(renders[event.player_index]) do
|
for _, render in pairs(renders[event.player_index]) do
|
||||||
if render.valid then render.destroy() end
|
if render.valid then render.destroy() end
|
||||||
end
|
end
|
||||||
|
|
||||||
renders[event.player_index] = nil
|
renders[event.player_index] = nil
|
||||||
end)
|
end
|
||||||
|
|
||||||
--- When there is a repeat offence print it in chat
|
--- When there is a repeat offence print it in chat
|
||||||
Event.add(EntityProtection.events.on_repeat_violation, function(event)
|
local function on_repeat_violation(event)
|
||||||
local player_name = format_player_name(event.player_index)
|
Roles.print_to_roles_higher("Regular", {
|
||||||
Roles.print_to_roles_higher("Regular", { "expcom-protection.repeat-offence", player_name, event.entity.localised_name, event.entity.position.x, event.entity.position.y })
|
"exp-commands_protection.repeat-offence",
|
||||||
end)
|
format_player_name(event.player_index),
|
||||||
|
event.entity.localised_name,
|
||||||
|
event.entity.position.x,
|
||||||
|
event.entity.position.y
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
events = {
|
||||||
|
[Selection.events.on_player_selection_start] = on_player_selection_start,
|
||||||
|
[Selection.events.on_player_selection_end] = on_player_selection_end,
|
||||||
|
[EntityProtection.events.on_repeat_violation] = on_repeat_violation,
|
||||||
|
}
|
||||||
|
}
|
||||||
112
exp_scenario/module/commands/protected_tags.lua
Normal file
112
exp_scenario/module/commands/protected_tags.lua
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
--[[-- Commands - Protected Tags
|
||||||
|
Adds a command that creates chart tags which can only be edited by admins
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local Storage = require("modules/exp_util/storage")
|
||||||
|
|
||||||
|
--- Storage variables
|
||||||
|
local active_players = {} --- @type table<number, boolean> Stores all players in in protected mode
|
||||||
|
local map_tags = {} --- @type table<number, boolean> Stores all protected map tags
|
||||||
|
|
||||||
|
Storage.register({
|
||||||
|
active_players = active_players,
|
||||||
|
map_tags = map_tags,
|
||||||
|
}, function(tbl)
|
||||||
|
active_players = tbl.active_players
|
||||||
|
map_tags = tbl.map_tags
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Toggle admin marker mode, can only be applied to yourself
|
||||||
|
local cmd_protected_tag =
|
||||||
|
Commands.new("protected-tag", { "exp-commands_protected-tags.description" })
|
||||||
|
:add_aliases{ "ptag" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player)
|
||||||
|
if active_players[player.index] then
|
||||||
|
active_players[player.index] = nil
|
||||||
|
return Commands.status.success{ "exp-commands_protected-tags.exit" }
|
||||||
|
else
|
||||||
|
active_players[player.index] = true
|
||||||
|
return Commands.status.success{ "exp-commands_protected-tags.enter" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- When a player leaves the game, remove them from the active list
|
||||||
|
--- @param event EventData.on_player_left_game
|
||||||
|
local function on_player_left_game(event)
|
||||||
|
active_players[event.player_index] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a chart tag as protected if the player is in protected mode
|
||||||
|
--- @param event EventData.on_chart_tag_added
|
||||||
|
local function on_chart_tag_added(event)
|
||||||
|
if not event.player_index then return end
|
||||||
|
if not active_players[event.player_index] then return end
|
||||||
|
|
||||||
|
local tag = event.tag
|
||||||
|
local player = game.players[event.player_index]
|
||||||
|
map_tags[tag.force.name .. tag.tag_number] = true
|
||||||
|
player.print{ "exp-commands_protected-tags.create" }
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stop a tag from being edited or removed
|
||||||
|
--- @param event EventData.on_chart_tag_modified | EventData.on_chart_tag_removed
|
||||||
|
local function on_chart_tag_removed_or_modified(event)
|
||||||
|
local tag = event.tag
|
||||||
|
if not event.player_index then return end
|
||||||
|
if not map_tags[tag.force.name .. tag.tag_number] then return end
|
||||||
|
local player = game.players[event.player_index]
|
||||||
|
|
||||||
|
-- Check if the player is in protected mode, and inform them that it was protected
|
||||||
|
if active_players[event.player_index] then
|
||||||
|
player.print{ "exp-commands_protected-tags.edit" }
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check how the changes need to be reverted
|
||||||
|
if event.name == defines.events.on_chart_tag_modified then
|
||||||
|
-- Tag was modified, revert the changes
|
||||||
|
tag.text = event.old_text
|
||||||
|
tag.icon = event.old_icon
|
||||||
|
tag.surface = event.old_surface
|
||||||
|
tag.position = event.old_position
|
||||||
|
if event.old_player_index then
|
||||||
|
tag.last_user = game.players[event.old_player_index]
|
||||||
|
else
|
||||||
|
tag.last_user = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- Tag was removed, recreate the tag
|
||||||
|
local new_tag =
|
||||||
|
tag.force.add_chart_tag(tag.surface, {
|
||||||
|
last_user = tag.last_user,
|
||||||
|
position = tag.position,
|
||||||
|
icon = tag.icon,
|
||||||
|
text = tag.text,
|
||||||
|
})
|
||||||
|
|
||||||
|
--- @cast new_tag -nil
|
||||||
|
map_tags[tag.force.name .. tag.tag_number] = nil
|
||||||
|
map_tags[new_tag.force.name .. new_tag.tag_number] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if Commands.player_has_permission(player, cmd_protected_tag) then
|
||||||
|
-- Player is not in protected mode, but has access to the command
|
||||||
|
player.print({ "exp-commands_protected-tags.revert-has-access", cmd_protected_tag.name }, Commands.print_settings.error)
|
||||||
|
else
|
||||||
|
--- Player does not have access to protected mode
|
||||||
|
player.print({ "exp-commands_protected-tags.revert-no-access" }, Commands.print_settings.error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = defines.events
|
||||||
|
return {
|
||||||
|
events = {
|
||||||
|
[e.on_chart_tag_added] = on_chart_tag_added,
|
||||||
|
[e.on_player_left_game] = on_player_left_game,
|
||||||
|
[e.on_chart_tag_modified] = on_chart_tag_removed_or_modified,
|
||||||
|
[e.on_chart_tag_removed] = on_chart_tag_removed_or_modified,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
--[[-- Commands Module - Rainbow
|
--[[-- Commands - Rainbow
|
||||||
- Adds a command that prints your message in rainbow font
|
Adds a command that prints your message in rainbow font
|
||||||
@commands Rainbow
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local ExpUtil = require("modules/exp_util")
|
local Commands = require("modules/exp_commands")
|
||||||
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
local format_player_name = Commands.format_player_name_locale
|
||||||
local format_chat_colour = ExpUtil.format_rich_text_color --- @dep expcore.common
|
local format_text = Commands.format_rich_text_color
|
||||||
|
|
||||||
|
--- Wraps one component into the next
|
||||||
|
--- @param c1 number
|
||||||
|
--- @param c2 number
|
||||||
|
--- @return number, number
|
||||||
local function step_component(c1, c2)
|
local function step_component(c1, c2)
|
||||||
if c1 < 0 then
|
if c1 < 0 then
|
||||||
return 0, c2 + c1
|
return 0, c2 + c1
|
||||||
@@ -17,6 +20,9 @@ local function step_component(c1, c2)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Wraps all components of a colour ensuring it remains valid
|
||||||
|
--- @param color Color
|
||||||
|
--- @return Color
|
||||||
local function step_color(color)
|
local function step_color(color)
|
||||||
color.r, color.g = step_component(color.r, color.g)
|
color.r, color.g = step_component(color.r, color.g)
|
||||||
color.g, color.b = step_component(color.g, color.b)
|
color.g, color.b = step_component(color.g, color.b)
|
||||||
@@ -25,6 +31,10 @@ local function step_color(color)
|
|||||||
return color
|
return color
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the next colour in the rainbow by the given step
|
||||||
|
--- @param color Color
|
||||||
|
--- @param step number
|
||||||
|
--- @return Color
|
||||||
local function next_color(color, step)
|
local function next_color(color, step)
|
||||||
step = step or 0.1
|
step = step or 0.1
|
||||||
local new_color = { r = 0, g = 0, b = 0 }
|
local new_color = { r = 0, g = 0, b = 0 }
|
||||||
@@ -42,22 +52,21 @@ local function next_color(color, step)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Sends an rainbow message in the chat
|
--- Sends an rainbow message in the chat
|
||||||
-- @command rainbow
|
Commands.new("rainbow", { "exp-commands_rainbow" })
|
||||||
-- @tparam string message the message that will be printed in chat
|
:argument("message", { "exp-commands_rainbow.arg-message" }, Commands.types.string)
|
||||||
Commands.new_command("rainbow", { "expcom-rainbow.description" }, "Sends an rainbow message in the chat")
|
:enable_auto_concatenation()
|
||||||
:add_param("message", false)
|
|
||||||
:enable_auto_concat()
|
|
||||||
:register(function(player, message)
|
:register(function(player, message)
|
||||||
local player_name = player and player.name or "<Server>"
|
|
||||||
local player_color = player and player.color or nil
|
|
||||||
local color_step = 3 / message:len()
|
local color_step = 3 / message:len()
|
||||||
if color_step > 1 then color_step = 1 end
|
if color_step > 1 then color_step = 1 end
|
||||||
local current_color = { r = 1, g = 0, b = 0 }
|
local current_color = { r = 1, g = 0, b = 0 }
|
||||||
local output = format_chat_colour(player_name .. ": ", player_color)
|
|
||||||
output = output .. message:gsub("%S", function(letter)
|
game.print{
|
||||||
local rtn = format_chat_colour(letter, current_color)
|
"exp-commands_rainbow.response",
|
||||||
current_color = next_color(current_color, color_step)
|
format_player_name(player),
|
||||||
return rtn
|
message:gsub("%S", function(letter)
|
||||||
end)
|
local rtn = format_text(letter, current_color)
|
||||||
game.print(output)
|
current_color = next_color(current_color, color_step)
|
||||||
|
return rtn
|
||||||
|
end)
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
54
exp_scenario/module/commands/ratio.lua
Normal file
54
exp_scenario/module/commands/ratio.lua
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
--[[-- Commands - Ratio
|
||||||
|
Adds a command to calculate the number of machines needed to fulfil a desired production
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
Commands.new("ratio", { "exp-command_ratio.description" })
|
||||||
|
:optional("items-per-second", { "exp-command_ratio.arg-items-per-second" }, Commands.types.number)
|
||||||
|
:register(function(player, items_per_second)
|
||||||
|
--- @cast items_per_second number?
|
||||||
|
|
||||||
|
local machine = player.selected
|
||||||
|
if not machine then
|
||||||
|
return Commands.status.error{ "exp-command_ratio.not-selecting" }
|
||||||
|
end
|
||||||
|
|
||||||
|
if machine.type ~= "assembling-machine" and machine.type ~= "furnace" then
|
||||||
|
return Commands.status.error{ "exp-command_ratio.not-selecting" }
|
||||||
|
end
|
||||||
|
|
||||||
|
local recipe = machine.get_recipe()
|
||||||
|
if not recipe then
|
||||||
|
return Commands.status.error{ "exp-command_ratio.not-selecting" }
|
||||||
|
end
|
||||||
|
|
||||||
|
local products = recipe.products
|
||||||
|
local ingredients = recipe.ingredients
|
||||||
|
local crafts_per_second = machine.crafting_speed * machine.productivity_bonus / recipe.energy
|
||||||
|
|
||||||
|
local amount_of_machines = 1
|
||||||
|
if items_per_second then
|
||||||
|
amount_of_machines = math.ceil(products[1].amount * crafts_per_second)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, ingredient in ipairs(ingredients) do
|
||||||
|
Commands.print{
|
||||||
|
ingredient.type == "item" and "exp-command_ratio.item-out" or "exp-command_ratio.fluid-out",
|
||||||
|
math.round(ingredient.amount * crafts_per_second, 3),
|
||||||
|
ingredient.name
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, product in ipairs(products) do
|
||||||
|
Commands.print{
|
||||||
|
product.type == "item" and "exp-command_ratio.item-out" or "exp-command_ratio.fluid-out",
|
||||||
|
math.round(product.amount * crafts_per_second, 3),
|
||||||
|
product.name
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if amount_of_machines ~= 1 then
|
||||||
|
Commands.print{ "exp-command_ratio.machine-count", amount_of_machines }
|
||||||
|
end
|
||||||
|
end)
|
||||||
60
exp_scenario/module/commands/repair.lua
Normal file
60
exp_scenario/module/commands/repair.lua
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
--[[-- Commands - Repair
|
||||||
|
Adds a command that allows an admin to repair and revive a large area
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local config = require("modules.exp_legacy.config.repair") --- @dep config.repair
|
||||||
|
|
||||||
|
local huge = math.huge
|
||||||
|
|
||||||
|
--- Repairs entities on your force around you
|
||||||
|
Commands.new("repair", { "exp-commands_repair.description" })
|
||||||
|
:argument("range", { "exp-commands_repair.arg-range" }, Commands.types.integer_range(1, config.max_range))
|
||||||
|
:register(function(player, range)
|
||||||
|
--- @cast range number
|
||||||
|
local force = player.force
|
||||||
|
local surface = player.surface -- Allow remote view
|
||||||
|
local position = player.position -- Allow remote view
|
||||||
|
local response = { "" } --- @type LocalisedString
|
||||||
|
|
||||||
|
if config.allow_ghost_revive then
|
||||||
|
local revive_count = 0
|
||||||
|
local entities = surface.find_entities_filtered{
|
||||||
|
type = "entity-ghost",
|
||||||
|
position = position,
|
||||||
|
radius = range,
|
||||||
|
force = force,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
-- TODO test for ghost not being a blueprint, https://forums.factorio.com/viewtopic.php?f=28&t=119736
|
||||||
|
if not config.disallow[entity.ghost_name] and (config.allow_blueprint_repair or true) then
|
||||||
|
revive_count = revive_count + 1
|
||||||
|
entity.silent_revive()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
response[#response + 1] = { "exp-commands_repair.response-revive", revive_count }
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.allow_heal_entities then
|
||||||
|
local healed_count = 0
|
||||||
|
local entities = surface.find_entities_filtered{
|
||||||
|
position = position,
|
||||||
|
radius = range,
|
||||||
|
force = force,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
if entity.health and entity.get_health_ratio() ~= 1 then
|
||||||
|
healed_count = healed_count + 1
|
||||||
|
entity.health = huge
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
response[#response + 1] = { "exp-commands_repair.response-heal", healed_count }
|
||||||
|
end
|
||||||
|
|
||||||
|
return Commands.status.success(response)
|
||||||
|
end)
|
||||||
|
|
||||||
107
exp_scenario/module/commands/reports.lua
Normal file
107
exp_scenario/module/commands/reports.lua
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
--[[-- Commands - Reports
|
||||||
|
Adds a commands that allow players to report other players
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
local parse_input = Commands.parse_input
|
||||||
|
|
||||||
|
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||||
|
local player_has_flag = Roles.player_has_flag
|
||||||
|
|
||||||
|
local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports
|
||||||
|
|
||||||
|
--- @type Commands.InputParser
|
||||||
|
local function reportable_player(input, player)
|
||||||
|
local success, status, result = parse_input(input, player, Commands.types.player)
|
||||||
|
if not success then return status, result end
|
||||||
|
--- @cast result LuaPlayer
|
||||||
|
|
||||||
|
if player_has_flag(input, "report-immune") then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_reports.player-immune" }
|
||||||
|
elseif player == input then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_reports.self-report" }
|
||||||
|
else
|
||||||
|
return Commands.status.success(result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Reports a player and notifies admins
|
||||||
|
Commands.new("create-report", { "exp-commands_reports.description-create" })
|
||||||
|
:argument("player", { "exp-commands_reports.arg-player-create" }, reportable_player)
|
||||||
|
:argument("reason", { "exp-commands_reports.arg-reason" }, Commands.types.string)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "report" }
|
||||||
|
:register(function(player, other_player, reason)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast reason string
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
if Reports.report_player(other_player, player.name, reason) then
|
||||||
|
local user_message = { "exp-commands_reports.response", other_player_name, reason }
|
||||||
|
local admin_message = { "exp-commands_reports.response-admin", other_player_name, player_name, reason }
|
||||||
|
for _, player in ipairs(game.connected_players) do
|
||||||
|
if player.admin then
|
||||||
|
player.print(admin_message)
|
||||||
|
else
|
||||||
|
player.print(user_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_reports.already-reported" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Gets a list of all reports that a player has on them. If no player then lists all players and the number of reports on them.
|
||||||
|
Commands.new("get-reports", { "exp-commands_reports.description-get" })
|
||||||
|
:optional("player", { "exp-commands_reports.arg-player-get" }, Commands.types.player)
|
||||||
|
:add_aliases{ "reports" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer?
|
||||||
|
if other_player then
|
||||||
|
local reports = Reports.get_reports(other_player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
Commands.print{ "exp-commands_reports.player-title", other_player_name, #reports }
|
||||||
|
for by_player_name, reason in pairs(reports) do
|
||||||
|
local by_player_name_formatted = format_player_name(by_player_name)
|
||||||
|
Commands.print{ "exp-commands_reports.list-element", by_player_name_formatted, reason }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local reports = Reports.user_reports
|
||||||
|
Commands.print{ "exp-commands_reports.reports-title" }
|
||||||
|
for player_name in pairs(reports) do
|
||||||
|
local player_name_formatted = format_player_name(player_name)
|
||||||
|
local report_count = Reports.count_reports(player_name)
|
||||||
|
Commands.print{ "exp-commands_reports.list-element", player_name_formatted, report_count }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clears all reports from a player or just the report from one player.
|
||||||
|
Commands.new("clear-reports", { "exp-commands_reports.description-clear" })
|
||||||
|
:argument("player", { "exp-commands_reports.arg-player-clear" }, Commands.types.player)
|
||||||
|
:optional("from-player", { "exp-commands_reports.arg-from-player" }, Commands.types.player)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, from_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast from_player LuaPlayer?
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
if from_player then
|
||||||
|
if not Reports.remove_report(other_player, from_player.name, player.name) then
|
||||||
|
local from_player_name = format_player_name(other_player)
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_reports.not-reported-by", from_player_name }
|
||||||
|
else
|
||||||
|
game.print{ "exp-commands_reports.removed", other_player_name, player_name }
|
||||||
|
return Commands.status.success()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not Reports.remove_all(other_player, player.name) then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_reports.not-reported" }
|
||||||
|
else
|
||||||
|
game.print{ "exp-commands_reports.removed-all", other_player_name, player_name }
|
||||||
|
return Commands.status.success()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
71
exp_scenario/module/commands/research.lua
Normal file
71
exp_scenario/module/commands/research.lua
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
--[[-- Commands - Research
|
||||||
|
Adds a command to enable automatic research queueing
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Storage = require("modules/exp_util/storage")
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local config = require("modules.exp_legacy.config.research") --- @dep config.research
|
||||||
|
|
||||||
|
local research = {
|
||||||
|
res_queue_enable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.register(research, function(tbl)
|
||||||
|
research = tbl
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- @param force LuaForce
|
||||||
|
--- @param silent boolean True when no message should be printed
|
||||||
|
local function res_queue(force, silent)
|
||||||
|
local res_q = force.research_queue
|
||||||
|
local res = force.technologies["mining-productivity-4"]
|
||||||
|
|
||||||
|
if #res_q < config.queue_amount then
|
||||||
|
for i = 1, config.queue_amount - #res_q do
|
||||||
|
force.add_research(res)
|
||||||
|
|
||||||
|
if not silent then
|
||||||
|
game.print{ "exp-commands_research.queue", res.name, res.level + i }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the auto research state
|
||||||
|
Commands.new("set-auto-research", { "exp-commands_research.description" })
|
||||||
|
:optional("state", { "exp-commands_research.arg-state" }, Commands.types.boolean)
|
||||||
|
:add_aliases{ "auto-research" }
|
||||||
|
:register(function(player, state)
|
||||||
|
--- @cast state boolean?
|
||||||
|
if state == nil then
|
||||||
|
research.res_queue_enable = not research.res_queue_enable
|
||||||
|
else
|
||||||
|
research.res_queue_enable = state
|
||||||
|
end
|
||||||
|
|
||||||
|
if research.res_queue_enable then
|
||||||
|
res_queue(player.force --[[@as LuaForce]], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
game.print{ "exp-commands_research.auto-research", player_name, research.res_queue_enable }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- @param event EventData.on_research_finished
|
||||||
|
local function on_research_finished(event)
|
||||||
|
if not research.res_queue_enable then return end
|
||||||
|
|
||||||
|
local force = event.research.force
|
||||||
|
if force.rockets_launched > 0 and force.technologies["mining-productivity-4"].level > 4 then
|
||||||
|
res_queue(force, event.by_script)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = defines.events
|
||||||
|
return {
|
||||||
|
events = {
|
||||||
|
[e.on_research_finished] = on_research_finished,
|
||||||
|
}
|
||||||
|
}
|
||||||
63
exp_scenario/module/commands/roles.lua
Normal file
63
exp_scenario/module/commands/roles.lua
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
--[[-- Commands - Roles
|
||||||
|
Adds a commands that allow interaction with the role system
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
local format_text = Commands.format_rich_text_color_locale
|
||||||
|
|
||||||
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
|
local get_roles_ordered = Roles.get_roles_ordered
|
||||||
|
local get_player_roles = Roles.get_player_roles
|
||||||
|
|
||||||
|
--- Assigns a role to a player
|
||||||
|
Commands.new("assign-role", { "exp-commands_roles.description-assign" })
|
||||||
|
:argument("player", { "exp-commands_roles.arg-player-assign" }, Commands.types.lower_role_player)
|
||||||
|
:argument("role", { "exp-commands_roles.arg-role-assign" }, Commands.types.lower_role)
|
||||||
|
:add_aliases{ "assign" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, role)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast role any -- TODO
|
||||||
|
Roles.assign_player(other_player, role, player.name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Unassigns a role to a player
|
||||||
|
Commands.new("unassign-role", { "exp-commands_roles.description-unassign" })
|
||||||
|
:argument("player", { "exp-commands_roles.arg-player-unassign" }, Commands.types.lower_role_player)
|
||||||
|
:argument("role", { "exp-commands_roles.arg-role-unassign" }, Commands.types.lower_role)
|
||||||
|
:add_aliases{ "unassign" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, role)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast role any -- TODO
|
||||||
|
Roles.unassign_player(other_player, role, player.name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Lists all roles in they correct order
|
||||||
|
Commands.new("get-role", { "exp-commands_roles.description-get" })
|
||||||
|
:optional("player", { "exp-commands_roles.arg-player-get" }, Commands.types.player)
|
||||||
|
:add_aliases{ "roles" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer?
|
||||||
|
local roles = get_roles_ordered()
|
||||||
|
local roles_formatted = { "" } --- @type LocalisedString
|
||||||
|
local response = { "exp-commands_roles.list-roles", roles_formatted }
|
||||||
|
if other_player then
|
||||||
|
roles = get_player_roles(other_player)
|
||||||
|
response[1] = "exp-commands_roles.list-player"
|
||||||
|
response[3] = format_player_name(other_player)
|
||||||
|
end
|
||||||
|
|
||||||
|
for index, role in ipairs(roles) do
|
||||||
|
local role_name = format_text(role.name, role.custom_color or Commands.color.white)
|
||||||
|
roles_formatted[index + 1] = { "exp-commands_roles.list-element", role_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local last = #roles_formatted
|
||||||
|
--- @diagnostic disable-next-line nil-check
|
||||||
|
roles_formatted[last] = roles_formatted[last][2]
|
||||||
|
|
||||||
|
return Commands.status.success(response)
|
||||||
|
end)
|
||||||
181
exp_scenario/module/commands/search.lua
Normal file
181
exp_scenario/module/commands/search.lua
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
--[[-- Commands - Inventory Search
|
||||||
|
Adds commands that will search all players inventories for an item
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local format_number = require("util").format_number
|
||||||
|
|
||||||
|
--- A player who is of a lower role than the executing player
|
||||||
|
--- @type Commands.InputParser
|
||||||
|
local function parse_item(input, player)
|
||||||
|
-- First Case - internal name is given
|
||||||
|
-- Second Case - rich text is given
|
||||||
|
local item_name = input:lower():gsub(" ", "-")
|
||||||
|
local item = prototypes.item[item_name] or prototypes.item[input:match("%[item=([0-9a-z-]+)%]")]
|
||||||
|
if item then
|
||||||
|
return Commands.status.success(item)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No item found, we do not attempt to search all prototypes as this will be expensive
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_search.invalid-item", item_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @class SearchResult: { player: LuaPlayer, count: number, online_time: number }
|
||||||
|
|
||||||
|
--- Search all players for this item
|
||||||
|
--- @param players LuaPlayer[] Players to search
|
||||||
|
--- @param item LuaItemPrototype Item to find
|
||||||
|
--- @return SearchResult[]
|
||||||
|
local function search_players(players, item)
|
||||||
|
local found = {} --- @type SearchResult[]
|
||||||
|
local head = 1
|
||||||
|
|
||||||
|
-- Check the item count of all players
|
||||||
|
for _, player in pairs(players) do
|
||||||
|
local item_count = player.get_item_count(item.name)
|
||||||
|
if item_count > 0 then
|
||||||
|
-- Add the player to the array as they have the item
|
||||||
|
found[head] = { player = player, count = item_count, online_time = player.online_time }
|
||||||
|
head = head + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return found
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @alias SortFunction fun(result: SearchResult): number
|
||||||
|
|
||||||
|
--- Custom sort function which only retains 5 greatest values
|
||||||
|
--- @param results SearchResult[] Players to sort
|
||||||
|
--- @param func SortFunction Function to calculate value, higher better
|
||||||
|
--- @return SearchResult[] # Top 5 results
|
||||||
|
local function sort_results(results, func)
|
||||||
|
local sorted = {}
|
||||||
|
local values = {}
|
||||||
|
local threshold = 0
|
||||||
|
|
||||||
|
-- Loop over all provided players
|
||||||
|
for index, result in ipairs(results) do
|
||||||
|
local value = func(result)
|
||||||
|
-- Check if the item will make the top 5 elements
|
||||||
|
if index <= 5 or value > threshold then
|
||||||
|
local inserted = false
|
||||||
|
values[result] = value
|
||||||
|
|
||||||
|
-- Find where in the top 5 to insert the element
|
||||||
|
for next_index, next_result in ipairs(sorted) do
|
||||||
|
if value > values[next_result] then
|
||||||
|
table.insert(sorted, next_index, result)
|
||||||
|
inserted = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update the threshold, clean up the tables, and insert if needed
|
||||||
|
if sorted[6] then
|
||||||
|
threshold = values[sorted[5]]
|
||||||
|
values[sorted[6]] = nil
|
||||||
|
sorted[6] = nil
|
||||||
|
elseif not inserted then
|
||||||
|
-- index <= 5 so insert at the end
|
||||||
|
sorted[#sorted + 1] = result
|
||||||
|
threshold = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return sorted
|
||||||
|
end
|
||||||
|
|
||||||
|
local display_players_time_format = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true }
|
||||||
|
|
||||||
|
--- Display to the player the top players which were found
|
||||||
|
--- @param results SearchResult[]
|
||||||
|
--- @param item LuaItemPrototype
|
||||||
|
--- @return LocalisedString
|
||||||
|
local function format_response(results, item)
|
||||||
|
if #results == 0 then
|
||||||
|
return { "exp-commands_search.no-results", item.name }
|
||||||
|
end
|
||||||
|
|
||||||
|
local response = { "", { "exp-commands_search.title", item.name } } --- @type LocalisedString
|
||||||
|
for index, data in ipairs(results) do
|
||||||
|
response[index + 2] = {
|
||||||
|
"exp-commands_search.result",
|
||||||
|
index,
|
||||||
|
format_player_name(data.player),
|
||||||
|
format_number(data.count, false),
|
||||||
|
display_players_time_format(data.online_time),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return the the amount of an item a player has divided by their playtime
|
||||||
|
local function combined_sort(data)
|
||||||
|
return data.count / data.online_time
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a list of players sorted by quantity held and play time
|
||||||
|
Commands.new("search", { "exp-commands_search.description-search" })
|
||||||
|
:argument("item", { "exp-commands_search.arg-item" }, parse_item)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "s" }
|
||||||
|
:register(function(player, item)
|
||||||
|
--- @cast item LuaItemPrototype
|
||||||
|
local results = search_players(game.players, item)
|
||||||
|
local sorted = sort_results(results, combined_sort)
|
||||||
|
return Commands.status.success(format_response(sorted, item))
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Get a list of online players sorted by quantity held and play time
|
||||||
|
Commands.new("search-online", { "exp-commands_search.description-online" })
|
||||||
|
:argument("item", { "exp-commands_search.arg-item" }, parse_item)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "so" }
|
||||||
|
:register(function(player, item)
|
||||||
|
--- @cast item LuaItemPrototype
|
||||||
|
local results = search_players(game.connected_players, item)
|
||||||
|
local sorted = sort_results(results, combined_sort)
|
||||||
|
return Commands.status.success(format_response(sorted, item))
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Return the amount of an item a player has
|
||||||
|
--- @type SortFunction
|
||||||
|
local function sort_by_count(data)
|
||||||
|
return data.count
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a list of players sorted by the quantity of an item in their inventory
|
||||||
|
Commands.new("search-amount", { "exp-commands_search.description-amount" })
|
||||||
|
:argument("item", { "exp-commands_search.arg-item" }, parse_item)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "sa" } -- cant use /sc
|
||||||
|
:register(function(player, item)
|
||||||
|
--- @cast item LuaItemPrototype
|
||||||
|
local results = search_players(game.players, item)
|
||||||
|
local sorted = sort_results(results, sort_by_count)
|
||||||
|
return Commands.status.success(format_response(sorted, item))
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Return the index of the player, higher means they joined more recently
|
||||||
|
local function sort_by_recent(data)
|
||||||
|
return data.player.index
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a list of players who have the given item, sorted by how recently they joined
|
||||||
|
Commands.new("search-recent", { "exp-commands_search.description-recent" })
|
||||||
|
:argument("item", { "exp-commands_search.arg-item" }, parse_item)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "sr" } -- cant use /sc
|
||||||
|
:register(function(player, item)
|
||||||
|
--- @cast item LuaItemPrototype
|
||||||
|
local results = search_players(game.players, item)
|
||||||
|
local sorted = sort_results(results, sort_by_recent)
|
||||||
|
return Commands.status.success(format_response(sorted, item))
|
||||||
|
end)
|
||||||
29
exp_scenario/module/commands/spectate.lua
Normal file
29
exp_scenario/module/commands/spectate.lua
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
--[[-- Commands - Spectate
|
||||||
|
Adds commands relating to spectate and follow
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local Spectate = require("modules.exp_legacy.modules.control.spectate") --- @dep modules.control.spectate
|
||||||
|
|
||||||
|
--- Toggles spectator mode for the caller
|
||||||
|
Commands.new("spectate", { "exp-commands_spectate.description-spectate" })
|
||||||
|
:register(function(player)
|
||||||
|
if Spectate.is_spectating(player) then
|
||||||
|
Spectate.stop_spectate(player)
|
||||||
|
else
|
||||||
|
Spectate.start_spectate(player)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Enters follow mode for the caller, following the given player.
|
||||||
|
Commands.new("follow", { "exp-commands_spectate.description-follow" })
|
||||||
|
:argument("player", { "exp-command_spectate.arg-player" }, Commands.types.player_online)
|
||||||
|
:add_aliases{ "f" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
if player == other_player then
|
||||||
|
return Commands.status.invalid_input{ "exp-command_spectate.follow-self" }
|
||||||
|
else
|
||||||
|
Spectate.start_follow(player, other_player)
|
||||||
|
end
|
||||||
|
end)
|
||||||
89
exp_scenario/module/commands/surface.lua
Normal file
89
exp_scenario/module/commands/surface.lua
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
--[[-- Commands - Clear Item On Ground
|
||||||
|
Adds a command that clear item on ground so blueprint can deploy safely
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
local move_items = ExpUtil.move_items_to_surface
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
--- @param surface LuaSurface
|
||||||
|
--- @return LuaItemStack[]
|
||||||
|
local function get_ground_items(surface)
|
||||||
|
local items = {} --- @type LuaItemStack[]
|
||||||
|
local entities = surface.find_entities_filtered{ name = "item-on-ground" }
|
||||||
|
for index, entity in ipairs(entities) do
|
||||||
|
items[index] = entity.stack
|
||||||
|
end
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Clear all items on the ground, optional to select a single surface
|
||||||
|
Commands.new("clear-ground-items", { "exp-commands_surface.description-items" })
|
||||||
|
:optional("surface", { "exp-commands_surface.arg-surface" }, Commands.types.surface)
|
||||||
|
:register(function(player, surface)
|
||||||
|
--- @cast surface LuaSurface?
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
if surface then
|
||||||
|
move_items{
|
||||||
|
surface = surface,
|
||||||
|
items = get_ground_items(surface),
|
||||||
|
allow_creation = true,
|
||||||
|
name = "iron-chest",
|
||||||
|
}
|
||||||
|
game.print{ "exp-commands_surface.items-surface", player_name, surface.localised_name }
|
||||||
|
else
|
||||||
|
for _, surface in pairs(game.surfaces) do
|
||||||
|
move_items{
|
||||||
|
surface = surface,
|
||||||
|
items = get_ground_items(surface),
|
||||||
|
allow_creation = true,
|
||||||
|
name = "iron-chest",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
game.print{ "exp-commands_surface.items-all", player_name }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clear all blueprints, optional to select a single surface
|
||||||
|
Commands.new("clear-blueprints", { "exp-commands_surface.description-blueprints" })
|
||||||
|
:optional("surface", { "exp-commands_surface.arg-surface" }, Commands.types.surface)
|
||||||
|
:register(function(player, surface)
|
||||||
|
--- @cast surface LuaSurface?
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
if surface then
|
||||||
|
local entities = surface.find_entities_filtered{ type = "entity-ghost" }
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
entity.destroy()
|
||||||
|
end
|
||||||
|
game.print{ "exp-commands_surface.blueprint-surface", player_name, surface.localised_name }
|
||||||
|
else
|
||||||
|
for _, surface in pairs(game.surfaces) do
|
||||||
|
local entities = surface.find_entities_filtered{ type = "entity-ghost" }
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
entity.destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
game.print{ "exp-commands_surface.blueprint-all", player_name }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clear all blueprints in a radius around you
|
||||||
|
Commands.new("clear-blueprints-radius", { "exp-commands_surface.description-radius" })
|
||||||
|
:argument("radius", { "exp-commands_surface.arg-radius" }, Commands.types.number_range(1, 1000))
|
||||||
|
:register(function(player, radius)
|
||||||
|
--- @cast radius number
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local entities = player.surface.find_entities_filtered{
|
||||||
|
type = "entity-ghost",
|
||||||
|
position = player.position,
|
||||||
|
radius = radius,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
entity.destroy()
|
||||||
|
end
|
||||||
|
|
||||||
|
game.print{ "exp-commands_surface.blueprint-radius", player_name, radius, player.surface.localised_name }
|
||||||
|
end)
|
||||||
84
exp_scenario/module/commands/teleport.lua
Normal file
84
exp_scenario/module/commands/teleport.lua
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
--[[-- Commands - Teleport
|
||||||
|
Adds a command that allows players to teleport to other players and spawn
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
local teleport_player = ExpUtil.teleport_player
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
|
||||||
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
||||||
|
local player_allowed = Roles.player_allowed
|
||||||
|
|
||||||
|
--- Teleports a player to another player.
|
||||||
|
Commands.new("teleport", { "exp-commands_teleport.description-teleport" })
|
||||||
|
:argument("player", { "exp-commands_teleport.arg-player-teleport" }, Commands.types.player_alive)
|
||||||
|
:optional("target", { "exp-commands_teleport.arg-player-to" }, Commands.types.player_alive)
|
||||||
|
:add_aliases{ "tp" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, target_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast target_player LuaPlayer?
|
||||||
|
if target_player == nil then
|
||||||
|
-- When no player is given, then instead behave like /goto
|
||||||
|
if not teleport_player(player, other_player.physical_surface, other_player.physical_position) then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
elseif other_player == target_player then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_teleport.same-player" }
|
||||||
|
elseif not teleport_player(other_player, target_player.physical_surface, target_player.physical_position) then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Teleports a player to you.
|
||||||
|
Commands.new("bring", { "exp-commands_teleport.description-bring" })
|
||||||
|
:argument("player", { "exp-commands_teleport.arg-player-from" }, Commands.types.player_alive)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
if player == other_player then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_teleport.same-player" }
|
||||||
|
elseif not teleport_player(other_player, player.physical_surface, player.physical_position) then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Teleports you to a player.
|
||||||
|
Commands.new("goto", { "exp-commands_teleport.description-goto" })
|
||||||
|
:argument("player", { "exp-commands_teleport.arg-player-to" }, Commands.types.player_alive)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
if player == other_player then
|
||||||
|
return Commands.status.invalid_input{ "exp-commands_teleport.same-player" }
|
||||||
|
elseif not teleport_player(player, other_player.physical_surface, other_player.physical_position) then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Teleport to spawn
|
||||||
|
Commands.new("spawn", { "exp-commands_teleport.description-spawn" })
|
||||||
|
:optional("player", { "exp-commands_teleport.arg-player-spawn" }, Commands.types.player_alive)
|
||||||
|
:defaults{
|
||||||
|
player = function(player)
|
||||||
|
if player.character and player.character.health > 0 then
|
||||||
|
return player
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
:register(function(player, other_player)
|
||||||
|
if not other_player then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
elseif other_player == player then
|
||||||
|
if not teleport_player(player, game.surfaces.nauvis, { 0, 0 }, "dismount") then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
elseif player_allowed(player, "command/spawn/always") then
|
||||||
|
if not teleport_player(other_player, game.surfaces.nauvis, { 0, 0 }, "dismount") then
|
||||||
|
return Commands.status.error{ "exp-commands_teleport.unavailable" }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return Commands.status.unauthorised()
|
||||||
|
end
|
||||||
|
end)
|
||||||
29
exp_scenario/module/commands/trains.lua
Normal file
29
exp_scenario/module/commands/trains.lua
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
--[[-- Commands - Set Automatic Train
|
||||||
|
Adds a command that set all train back to automatic
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local format_number = require("util").format_number
|
||||||
|
|
||||||
|
--- Set all trains to automatic
|
||||||
|
Commands.new("set-trains-to-automatic", { "exp-commands_trains.description" })
|
||||||
|
:optional("surface", { "exp-commands_trains.arg-surface" }, Commands.types.surface)
|
||||||
|
:optional("force", { "exp-commands_trains.arg-force" }, Commands.types.force)
|
||||||
|
:register(function(player, surface, force)
|
||||||
|
--- @cast surface LuaSurface?
|
||||||
|
--- @cast force LuaForce?
|
||||||
|
local trains = game.train_manager.get_trains{
|
||||||
|
has_passenger = false,
|
||||||
|
is_manual = true,
|
||||||
|
surface = surface,
|
||||||
|
force = force,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, train in ipairs(trains) do
|
||||||
|
train.manual_mode = false
|
||||||
|
end
|
||||||
|
|
||||||
|
game.print{ "exp-commands_trains.response", format_player_name(player), format_number(#trains, false) }
|
||||||
|
end)
|
||||||
18
exp_scenario/module/commands/vlayer.lua
Normal file
18
exp_scenario/module/commands/vlayer.lua
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
--[[-- Commands - VLayer
|
||||||
|
Adds a virtual layer to store power to save space.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local vlayer = require("modules.exp_legacy.modules.control.vlayer")
|
||||||
|
|
||||||
|
--- Print all vlayer information
|
||||||
|
Commands.new("vlayer-info", { "exp-commands_vlayer.description" })
|
||||||
|
:register(function(player)
|
||||||
|
local index = 3
|
||||||
|
local response = { "", "exp-commands_vlayer.title" } --- @type LocalisedString
|
||||||
|
for title, value in pairs(vlayer.get_circuits()) do
|
||||||
|
response[index] = { "exp-commands_vlayer.result", title, value }
|
||||||
|
index = index + 1
|
||||||
|
end
|
||||||
|
return Commands.status.success(response)
|
||||||
|
end)
|
||||||
96
exp_scenario/module/commands/warnings.lua
Normal file
96
exp_scenario/module/commands/warnings.lua
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
--[[-- Commands - Warnings
|
||||||
|
Adds a commands that allow admins to warn other players
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Commands = require("modules/exp_commands")
|
||||||
|
local format_player_name = Commands.format_player_name_locale
|
||||||
|
|
||||||
|
local Warnings = require("modules.exp_legacy.modules.control.warnings") --- @dep modules.control.warnings
|
||||||
|
local config = require("modules.exp_legacy.config.warnings") --- @dep config.warnings
|
||||||
|
|
||||||
|
--- Gives a warning to a player; may lead to automatic script action.
|
||||||
|
Commands.new("create-warning", { "exp-commands_warnings.description-create" })
|
||||||
|
:argument("player", { "exp-commands_warnings.arg-player-create" }, Commands.types.lower_role_player)
|
||||||
|
:argument("reason", { "exp-commands_warnings.arg-reason" }, Commands.types.string)
|
||||||
|
:enable_auto_concatenation()
|
||||||
|
:add_aliases{ "warn" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player, reason)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
--- @cast reason string
|
||||||
|
Warnings.add_warning(other_player, player.name, reason)
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
game.print{ "exp-commands_warnings.create", other_player_name, player_name, reason }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Gets a list of all warnings that a player has on them. If no player then lists all players and the number of warnings on them.
|
||||||
|
Commands.new("get-warnings", { "exp-commands_warnings.description-get" })
|
||||||
|
:optional("player", { "exp-commands_warnings.arg-player-get" }, Commands.types.player)
|
||||||
|
:add_aliases{ "warnings" }
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer?
|
||||||
|
if other_player then
|
||||||
|
local warnings = Warnings.get_warnings(player)
|
||||||
|
local script_warnings = Warnings.get_script_warnings(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
Commands.print{ "exp-commands_warnings.player-title", other_player_name, #warnings, #script_warnings, config.temp_warning_limit }
|
||||||
|
for _, warning in pairs(warnings) do
|
||||||
|
local by_player_name_formatted = format_player_name(warning.by_player_name)
|
||||||
|
Commands.print{ "exp-commands_warnings.list-element-player", by_player_name_formatted, warning.reason }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local warnings = Warnings.user_warnings:get_all()
|
||||||
|
local script_warnings = Warnings.user_script_warnings
|
||||||
|
Commands.print{ "exp-commands_warnings.warnings-title" }
|
||||||
|
for player_name, player_warnings in pairs(warnings) do
|
||||||
|
local player_name_formatted = format_player_name(player_name)
|
||||||
|
local script_warning_count = script_warnings[player_name] and #script_warnings[player_name] or 0
|
||||||
|
Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, #player_warnings, script_warning_count, config.temp_warning_limit }
|
||||||
|
end
|
||||||
|
for player_name, player_warnings in pairs(script_warnings) do
|
||||||
|
if not warnings[player_name] then
|
||||||
|
local player_name_formatted = format_player_name(player_name)
|
||||||
|
Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, 0, #player_warnings, config.temp_warning_limit }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clears all warnings from a player
|
||||||
|
Commands.new("clear-warnings", { "exp-commands_warnings.description-clear" })
|
||||||
|
:argument("player", { "exp-commands_warnings.arg-player-clear" }, Commands.types.player)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
Warnings.clear_warnings(other_player, player.name)
|
||||||
|
Warnings.clear_script_warnings(other_player)
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
game.print{ "exp-commands_warnings.cleared", other_player_name, player_name }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clears all script warnings from a player
|
||||||
|
Commands.new("clear-script-warnings", { "exp-commands_warnings.description-clear-script" })
|
||||||
|
:argument("player", { "exp-commands_warnings.arg-player-clear" }, Commands.types.player)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
Warnings.clear_script_warnings(other_player)
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
game.print{ "exp-commands_warnings.cleared-script", other_player_name, player_name }
|
||||||
|
end)
|
||||||
|
|
||||||
|
--- Clears the last warning that was given to a player
|
||||||
|
Commands.new("clear-last-warnings", { "exp-commands_warnings.description-clear-last" })
|
||||||
|
:argument("player", { "exp-commands_warnings.arg-player-clear" }, Commands.types.player)
|
||||||
|
:add_flags{ "admin_only" }
|
||||||
|
:register(function(player, other_player)
|
||||||
|
--- @cast other_player LuaPlayer
|
||||||
|
Warnings.remove_warning(other_player, player.name)
|
||||||
|
local player_name = format_player_name(player)
|
||||||
|
local other_player_name = format_player_name(other_player)
|
||||||
|
game.print{ "exp-commands_warnings.cleared-last", other_player_name, player_name }
|
||||||
|
end)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user