2019-01-01 18:09:01 +02:00
|
|
|
-- This file contains core utilities used by the redmew scenario.
|
|
|
|
|
2018-12-25 19:54:14 +02:00
|
|
|
-- Dependencies
|
2018-11-18 18:12:00 +02:00
|
|
|
local Game = require 'utils.game'
|
2018-12-29 19:39:20 +02:00
|
|
|
local Color = require 'resources.color_presets'
|
2019-01-23 22:27:31 +02:00
|
|
|
local Server = require 'features.server'
|
2018-12-25 19:54:14 +02:00
|
|
|
|
|
|
|
-- localized functions
|
|
|
|
local random = math.random
|
2019-01-23 23:19:52 +02:00
|
|
|
local sqrt = math.sqrt
|
|
|
|
local floor = math.floor
|
|
|
|
local format = string.format
|
|
|
|
local match = string.match
|
|
|
|
local insert = table.insert
|
|
|
|
local concat = table.concat
|
2018-12-25 19:54:14 +02:00
|
|
|
|
|
|
|
-- local constants
|
2018-11-18 18:12:00 +02:00
|
|
|
local prefix = '## - '
|
2018-11-26 06:03:08 +02:00
|
|
|
local minutes_to_ticks = 60 * 60
|
|
|
|
local hours_to_ticks = 60 * 60 * 60
|
|
|
|
local ticks_to_minutes = 1 / minutes_to_ticks
|
|
|
|
local ticks_to_hours = 1 / hours_to_ticks
|
2018-11-18 18:12:00 +02:00
|
|
|
|
2018-12-25 19:54:14 +02:00
|
|
|
-- local vars
|
|
|
|
local Module = {}
|
|
|
|
|
2018-11-26 06:03:08 +02:00
|
|
|
--- Measures distance between pos1 and pos2
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.distance(pos1, pos2)
|
2018-11-18 18:12:00 +02:00
|
|
|
local dx = pos2.x - pos1.x
|
|
|
|
local dy = pos2.y - pos1.y
|
2019-01-23 23:19:52 +02:00
|
|
|
return sqrt(dx * dx + dy * dy)
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
|
2018-11-26 06:03:08 +02:00
|
|
|
--- Takes msg and prints it to all players except provided player
|
2019-02-13 03:20:35 +02:00
|
|
|
-- @param msg <string|table> table if locale is used
|
2019-01-23 22:27:31 +02:00
|
|
|
-- @param player <LuaPlayer> the player not to send the message to
|
2019-02-12 16:35:35 +02:00
|
|
|
-- @param color <table> the color to use for the message, defaults to white
|
2019-02-11 19:08:23 +02:00
|
|
|
function Module.print_except(msg, player, color)
|
2019-01-23 22:27:31 +02:00
|
|
|
if not color then
|
|
|
|
color = Color.white
|
|
|
|
end
|
|
|
|
|
2018-11-26 06:03:08 +02:00
|
|
|
for _, p in pairs(game.connected_players) do
|
|
|
|
if p ~= player then
|
2019-01-23 22:27:31 +02:00
|
|
|
p.print(msg, color)
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-11-23 19:07:44 +02:00
|
|
|
--- Prints a message to all online admins
|
2019-02-13 03:20:35 +02:00
|
|
|
-- @param msg <string|table> table if locale is used
|
|
|
|
-- @param source <LuaPlayer|string|nil> string must be the name of a player, nil for server.
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.print_admins(msg, source)
|
2018-11-18 18:12:00 +02:00
|
|
|
local source_name
|
|
|
|
local chat_color
|
|
|
|
if source then
|
|
|
|
if type(source) == 'string' then
|
|
|
|
source_name = source
|
2018-11-19 02:16:12 +02:00
|
|
|
chat_color = game.players[source].chat_color
|
2018-11-18 18:12:00 +02:00
|
|
|
else
|
|
|
|
source_name = source.name
|
|
|
|
chat_color = source.chat_color
|
|
|
|
end
|
|
|
|
else
|
2018-11-20 12:46:42 +02:00
|
|
|
source_name = 'Server'
|
2019-01-12 02:12:55 +02:00
|
|
|
chat_color = Color.yellow
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
2019-01-23 23:19:52 +02:00
|
|
|
local formatted_msg = format('%s(ADMIN) %s: %s', prefix, source_name, msg) -- to the server
|
2018-11-23 00:04:01 +02:00
|
|
|
print(formatted_msg)
|
2018-11-18 18:12:00 +02:00
|
|
|
for _, p in pairs(game.connected_players) do
|
|
|
|
if p.admin then
|
2018-11-23 00:04:01 +02:00
|
|
|
p.print(formatted_msg, chat_color)
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-11-23 19:07:44 +02:00
|
|
|
--- Returns a valid string with the name of the actor of a command.
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.get_actor()
|
2018-11-18 18:12:00 +02:00
|
|
|
if game.player then
|
|
|
|
return game.player.name
|
|
|
|
end
|
|
|
|
return '<server>'
|
|
|
|
end
|
|
|
|
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.cast_bool(var)
|
2018-11-18 18:12:00 +02:00
|
|
|
if var then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.find_entities_by_last_user(player, surface, filters)
|
2018-11-18 18:12:00 +02:00
|
|
|
if type(player) == 'string' or not player then
|
2018-11-20 12:46:42 +02:00
|
|
|
error("bad argument #1 to '" .. debug.getinfo(1, 'n').name .. "' (number or LuaPlayer expected, got " .. type(player) .. ')', 1)
|
2018-11-18 18:12:00 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
if type(surface) ~= 'table' and type(surface) ~= 'number' then
|
2018-11-20 12:46:42 +02:00
|
|
|
error("bad argument #2 to '" .. debug.getinfo(1, 'n').name .. "' (number or LuaSurface expected, got " .. type(surface) .. ')', 1)
|
2018-11-18 18:12:00 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
local entities = {}
|
2018-11-20 12:46:42 +02:00
|
|
|
local filter = filters or {}
|
2018-11-18 18:12:00 +02:00
|
|
|
if type(surface) == 'number' then
|
|
|
|
surface = game.surfaces[surface]
|
|
|
|
end
|
|
|
|
if type(player) == 'number' then
|
|
|
|
player = Game.get_player_by_index(player)
|
|
|
|
end
|
2018-11-20 12:46:42 +02:00
|
|
|
filter.force = player.force.name
|
|
|
|
for _, e in pairs(surface.find_entities_filtered(filter)) do
|
2018-11-18 18:12:00 +02:00
|
|
|
if e.last_user == player then
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(entities, e)
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
return entities
|
|
|
|
end
|
|
|
|
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.ternary(c, t, f)
|
2018-11-18 18:12:00 +02:00
|
|
|
if c then
|
|
|
|
return t
|
|
|
|
else
|
|
|
|
return f
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-11-26 06:03:08 +02:00
|
|
|
--- Takes a time in ticks and returns a string with the time in format "x hour(s) x minute(s)"
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.format_time(ticks)
|
2018-11-18 18:12:00 +02:00
|
|
|
local result = {}
|
|
|
|
|
2019-01-23 23:19:52 +02:00
|
|
|
local hours = floor(ticks * ticks_to_hours)
|
2018-11-18 18:12:00 +02:00
|
|
|
if hours > 0 then
|
|
|
|
ticks = ticks - hours * hours_to_ticks
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(result, hours)
|
2018-11-18 18:12:00 +02:00
|
|
|
if hours == 1 then
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(result, 'hour')
|
2018-11-18 18:12:00 +02:00
|
|
|
else
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(result, 'hours')
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-23 23:19:52 +02:00
|
|
|
local minutes = floor(ticks * ticks_to_minutes)
|
|
|
|
insert(result, minutes)
|
2018-11-18 18:12:00 +02:00
|
|
|
if minutes == 1 then
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(result, 'minute')
|
2018-11-18 18:12:00 +02:00
|
|
|
else
|
2019-01-23 23:19:52 +02:00
|
|
|
insert(result, 'minutes')
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
|
2019-01-23 23:19:52 +02:00
|
|
|
return concat(result, ' ')
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
|
2018-11-23 19:07:44 +02:00
|
|
|
--- Prints a message letting the player know they cannot run a command
|
2018-11-26 06:03:08 +02:00
|
|
|
-- @param name string name of the command
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.cant_run(name)
|
2018-11-18 18:12:00 +02:00
|
|
|
Game.player_print("Can't run command (" .. name .. ') - insufficient permission.')
|
|
|
|
end
|
|
|
|
|
2018-11-23 19:07:44 +02:00
|
|
|
--- Logs the use of a command and its user
|
2018-11-26 06:03:08 +02:00
|
|
|
-- @param actor string with the actor's name (usually acquired by calling get_actor)
|
|
|
|
-- @param command the command's name as table element
|
|
|
|
-- @param parameters the command's parameters as a table (optional)
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.log_command(actor, command, parameters)
|
2019-01-23 23:19:52 +02:00
|
|
|
local action = concat {'[Admin-Command] ', actor, ' used: ', command}
|
2018-11-18 18:12:00 +02:00
|
|
|
if parameters then
|
2019-01-23 23:19:52 +02:00
|
|
|
action = concat {action, ' ', parameters}
|
2018-11-18 18:12:00 +02:00
|
|
|
end
|
|
|
|
log(action)
|
|
|
|
end
|
|
|
|
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.comma_value(n) -- credit http://richard.warburton.it
|
2019-01-23 23:19:52 +02:00
|
|
|
local left, num, right = match(n, '^([^%d]*%d)(%d*)(.-)$')
|
2018-11-18 18:12:00 +02:00
|
|
|
return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right
|
|
|
|
end
|
|
|
|
|
2018-11-26 06:03:08 +02:00
|
|
|
--- Asserts the argument is one of type arg_types
|
|
|
|
-- @param arg the variable to check
|
|
|
|
-- @param arg_types the type as a table of sings
|
|
|
|
-- @return boolean
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.verify_mult_types(arg, arg_types)
|
2018-11-26 06:03:08 +02:00
|
|
|
for _, arg_type in pairs(arg_types) do
|
|
|
|
if type(arg) == arg_type then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2018-12-25 19:54:14 +02:00
|
|
|
--- Returns a random RGB color as a table
|
2019-01-01 17:03:41 +02:00
|
|
|
function Module.random_RGB()
|
2018-12-25 19:54:14 +02:00
|
|
|
return {r = random(0, 255), g = random(0, 255), b = random(0, 255)}
|
|
|
|
end
|
|
|
|
|
2019-01-02 15:42:18 +02:00
|
|
|
--- Sets a table element to value while also returning value.
|
|
|
|
-- @param tbl table to change the element of
|
|
|
|
-- @param key string
|
|
|
|
-- @param value nil|boolean|number|string|table to set the element to
|
|
|
|
-- @return value
|
|
|
|
function Module.set_and_return(tbl, key, value)
|
|
|
|
tbl[key] = value
|
|
|
|
return value
|
|
|
|
end
|
|
|
|
|
2019-01-23 22:27:31 +02:00
|
|
|
--- Takes msg and prints it to all players. Also prints to the log and discord
|
|
|
|
-- @param msg <string> The message to print
|
|
|
|
-- @param warning_prefix <string> The name of the module/warning
|
2019-01-24 06:37:11 +02:00
|
|
|
function Module.action_warning(warning_prefix, msg)
|
2019-01-23 22:27:31 +02:00
|
|
|
game.print(prefix .. msg, Color.yellow)
|
2019-01-23 23:19:52 +02:00
|
|
|
msg = format('%s %s', warning_prefix, msg)
|
2019-01-23 22:27:31 +02:00
|
|
|
log(msg)
|
|
|
|
Server.to_discord_bold(msg)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Takes msg and prints it to all players except provided player. Also prints to the log and discord
|
|
|
|
-- @param msg <string> The message to print
|
|
|
|
-- @param warning_prefix <string> The name of the module/warning
|
|
|
|
-- @param player <LuaPlayer> the player not to send the message to
|
2019-01-24 06:37:11 +02:00
|
|
|
function Module.silent_action_warning(warning_prefix, msg, player)
|
2019-02-11 19:08:23 +02:00
|
|
|
Module.print_except(prefix .. msg, player, Color.yellow)
|
2019-01-23 23:19:52 +02:00
|
|
|
msg = format('%s %s', warning_prefix, msg)
|
2019-01-23 22:27:31 +02:00
|
|
|
log(msg)
|
|
|
|
Server.to_discord_bold(msg)
|
|
|
|
end
|
|
|
|
|
2019-01-01 17:03:41 +02:00
|
|
|
-- add utility functions that exist in base factorio/util
|
|
|
|
require 'util'
|
|
|
|
|
|
|
|
--- Moves a position according to the parameters given
|
|
|
|
-- Notice: only accepts cardinal directions as direction
|
|
|
|
-- @param position <table> table containing a map position
|
|
|
|
-- @param direction <defines.direction> north, east, south, west
|
|
|
|
-- @param distance <number>
|
|
|
|
-- @return <table> modified position
|
|
|
|
Module.move_position = util.moveposition
|
|
|
|
|
|
|
|
--- Takes a direction and gives you the opposite
|
|
|
|
-- @param direction <defines.direction> north, east, south, west, northeast, northwest, southeast, southwest
|
|
|
|
-- @return <number> representing the direction
|
|
|
|
Module.opposite_direction = util.oppositedirection
|
|
|
|
|
|
|
|
--- Takes the string of a module and returns whether is it available or not
|
|
|
|
-- @param name <string> the name of the module (ex. 'utils.core')
|
|
|
|
-- @return <boolean>
|
|
|
|
Module.is_module_available = util.ismoduleavailable
|
|
|
|
|
2018-11-18 18:12:00 +02:00
|
|
|
return Module
|