mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
Split walkabout from custom_commands
Fix walkabout edge cases Closes #22
This commit is contained in:
parent
7fa48bc583
commit
3a83d4182a
@ -29,13 +29,14 @@ require 'features.nuke_control'
|
||||
require 'features.player_colors'
|
||||
require 'features.reactor_meltdown'
|
||||
require 'features.train_station_names'
|
||||
require 'features.walkabout'
|
||||
|
||||
-- Contains various commands for users and admins alike
|
||||
require 'features.custom_commands'
|
||||
|
||||
-- GUIs the order determines the order they appear from left to right.
|
||||
-- These can be safely disabled. Some map presets will add GUI modules themselves.
|
||||
local info = require 'features.gui.info'
|
||||
require 'features.gui.info'
|
||||
require 'features.gui.player_list'
|
||||
require 'features.gui.poll'
|
||||
require 'features.gui.tag_group'
|
||||
|
@ -91,6 +91,11 @@ local function kill(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
if global.walking[player.index] == true or global.walking[target.index] == true then
|
||||
player.print("A player on walkabout cannot be killed by a mere fish, don't waste your efforts.")
|
||||
return
|
||||
end
|
||||
|
||||
if not target and player then
|
||||
if not do_fish_kill(player, true) then
|
||||
Game.player_print("Sorry, you don't have a character to kill.")
|
||||
@ -121,112 +126,6 @@ local function kill(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
--- A table of players currently on walkabout
|
||||
global.walking = {}
|
||||
|
||||
--- Return player from walkabout
|
||||
local custom_commands_return_player =
|
||||
Token.register(
|
||||
function(args)
|
||||
local player = args.player
|
||||
if not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
global.walking[player.index] = false
|
||||
|
||||
local walkabout_character = player.character
|
||||
if walkabout_character and walkabout_character.valid then
|
||||
walkabout_character.destroy()
|
||||
end
|
||||
|
||||
local character = args.character
|
||||
if character ~= nil and character.valid then
|
||||
player.character = character
|
||||
else
|
||||
player.create_character()
|
||||
player.teleport(args.position)
|
||||
end
|
||||
|
||||
player.force = args.force
|
||||
|
||||
game.print(args.player.name .. ' came back from his walkabout.')
|
||||
end
|
||||
)
|
||||
|
||||
--- Takes a target and puts them on walkabot (admin only)
|
||||
local function walkabout(cmd)
|
||||
if game.player and not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local params = {}
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
end
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
local player_name = params[1]
|
||||
local duration = 60
|
||||
if #params > 2 then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) == nil then
|
||||
Game.player_print(params[2] .. ' is not a number.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) then
|
||||
duration = tonumber(params[2])
|
||||
end
|
||||
if duration < 15 then
|
||||
duration = 15
|
||||
end
|
||||
|
||||
local player = game.players[player_name]
|
||||
if player == nil or not player.valid or global.walking[player.index] then
|
||||
Game.player_print(player_name .. ' could not go on a walkabout.')
|
||||
return
|
||||
end
|
||||
local chunks = {}
|
||||
for chunk in player.surface.get_chunks() do
|
||||
table.insert(chunks, chunk)
|
||||
end
|
||||
|
||||
local surface = player.surface
|
||||
local chunk = surface.get_random_chunk()
|
||||
local pos = {x = chunk.x * 32, y = chunk.y * 32}
|
||||
local non_colliding_pos = surface.find_non_colliding_position('player', pos, 100, 1)
|
||||
|
||||
local character = player.character
|
||||
if character and character.valid then
|
||||
character.walking_state = {walking = false}
|
||||
end
|
||||
|
||||
if non_colliding_pos then
|
||||
game.print(player_name .. ' went on a walkabout, to find himself.')
|
||||
Task.set_timeout(
|
||||
duration,
|
||||
custom_commands_return_player,
|
||||
{
|
||||
player = player,
|
||||
force = player.force,
|
||||
position = {x = player.position.x, y = player.position.y},
|
||||
character = character
|
||||
}
|
||||
)
|
||||
player.character = nil
|
||||
player.create_character()
|
||||
player.teleport(non_colliding_pos)
|
||||
player.force = 'neutral'
|
||||
global.walking[player.index] = true
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
else
|
||||
Game.player_print('Walkabout failed: could not find non colliding position')
|
||||
end
|
||||
end
|
||||
|
||||
--- Promote or demote a player between guest and regular (admin only)
|
||||
local function regular(cmd)
|
||||
if game.player and not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
|
157
features/walkabout.lua
Normal file
157
features/walkabout.lua
Normal file
@ -0,0 +1,157 @@
|
||||
local global ={}
|
||||
local Task = require 'utils.Task'
|
||||
local Game = require "utils.game"
|
||||
local Event = require "utils.event"
|
||||
local Token = require 'utils.global_token'
|
||||
local Utils = require 'utils.utils'
|
||||
|
||||
global.walking = {}
|
||||
global.walking_storage = {}
|
||||
|
||||
--- Returns a player from walkabout after the timeout.
|
||||
-- If the player is no longer logged in, store their info
|
||||
-- in the global table walking_storage
|
||||
local custom_commands_return_player =
|
||||
Token.register(
|
||||
function(args)
|
||||
local player = args.player
|
||||
local index = player.index
|
||||
if not player.valid then
|
||||
return
|
||||
end
|
||||
-- If walking is false it means they got cleaned by clean_on_join
|
||||
if global.walking[index] == false then
|
||||
return
|
||||
end
|
||||
|
||||
-- If the player is no longer connected, store that information.
|
||||
if player.connected then
|
||||
global.walking[index] = false
|
||||
|
||||
local walkabout_character = player.character
|
||||
if walkabout_character and walkabout_character.valid then
|
||||
walkabout_character.destroy()
|
||||
end
|
||||
|
||||
local character = args.character
|
||||
if character ~= nil and character.valid then
|
||||
player.character = character
|
||||
else
|
||||
player.create_character()
|
||||
player.teleport(args.position)
|
||||
end
|
||||
|
||||
player.force = args.force
|
||||
|
||||
game.print(args.player.name .. ' came back from his walkabout.')
|
||||
else
|
||||
local data = {index = index, character = args.character, force = args.force, position = args.position}
|
||||
table.insert(global.walking_storage, data)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--- Sends a player on a walkabout:
|
||||
-- They are teleported far away, placed on a neutral force, and are given a new character.
|
||||
-- They are turned after the timeout by custom_commands_return_player
|
||||
local function walkabout(cmd)
|
||||
if game.player and not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local params = {}
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
end
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
local player_name = params[1]
|
||||
local duration = 60
|
||||
if #params > 2 then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) == nil then
|
||||
Game.player_print(params[2] .. ' is not a number.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) then
|
||||
duration = tonumber(params[2])
|
||||
end
|
||||
if duration < 15 then
|
||||
duration = 15
|
||||
end
|
||||
|
||||
local player = game.players[player_name]
|
||||
if player == nil or not player.valid or global.walking[player.index] then
|
||||
Game.player_print(player_name .. ' could not go on a walkabout.')
|
||||
return
|
||||
end
|
||||
local chunks = {}
|
||||
for chunk in player.surface.get_chunks() do
|
||||
table.insert(chunks, chunk)
|
||||
end
|
||||
|
||||
local surface = player.surface
|
||||
local chunk = surface.get_random_chunk()
|
||||
local pos = {x = chunk.x * 32, y = chunk.y * 32}
|
||||
local non_colliding_pos = surface.find_non_colliding_position('player', pos, 100, 1)
|
||||
|
||||
local character = player.character
|
||||
if character and character.valid then
|
||||
character.walking_state = {walking = false}
|
||||
end
|
||||
|
||||
if non_colliding_pos then
|
||||
game.print(player_name .. ' went on a walkabout, to find himself.')
|
||||
Task.set_timeout(
|
||||
duration,
|
||||
custom_commands_return_player,
|
||||
{
|
||||
player = player,
|
||||
force = player.force,
|
||||
position = {x = player.position.x, y = player.position.y},
|
||||
character = character
|
||||
}
|
||||
)
|
||||
player.character = nil
|
||||
player.create_character()
|
||||
player.teleport(non_colliding_pos)
|
||||
player.force = 'neutral'
|
||||
global.walking[player.index] = true
|
||||
else
|
||||
Game.player_print('Walkabout failed: could not find non colliding position')
|
||||
end
|
||||
end
|
||||
|
||||
--- Cleans the walkabout status off players who disconnected during walkabout.
|
||||
-- Restores their original force, character, and position.
|
||||
function clean_on_join(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local index = player.index
|
||||
if global.walking[index] then
|
||||
global.walking[index] = false
|
||||
for _, s in pairs (global.walking_storage) do
|
||||
if s.index == index then
|
||||
|
||||
local walkabout_character = player.character
|
||||
if walkabout_character and walkabout_character.valid then
|
||||
walkabout_character.destroy()
|
||||
end
|
||||
|
||||
local character = s.character
|
||||
if character ~= nil and character.valid then
|
||||
player.character = character
|
||||
else
|
||||
player.create_character()
|
||||
player.teleport(s.position)
|
||||
end
|
||||
|
||||
player.force = s.force
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, clean_on_join)
|
||||
commands.add_command('walkabout', '<player> <duration> - Send someone on a walk. (Admins only)', walkabout)
|
Loading…
Reference in New Issue
Block a user