1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-04-13 11:40:45 +02:00

dump_offline_inventories fixes.

This commit is contained in:
James Gillham 2021-03-03 20:13:25 +00:00
parent e9d197999c
commit 02e2b59103
3 changed files with 79 additions and 49 deletions

View File

@ -23,6 +23,10 @@ Global.register(player_corpses, function(tbl)
player_corpses = tbl
end)
local function add_tag(tag, player_index, death_tick)
player_corpses[player_index * 0x100000000 + death_tick] = tag
end
local function player_died(event)
local player_index = event.player_index
local player = game.get_player(player_index)
@ -83,7 +87,7 @@ local function player_died(event)
end
end
player_corpses[player_index * 0x100000000 + tick] = tag
add_tag(tag, player_index, tick)
end
local function remove_tag(player_index, tick)
@ -99,14 +103,16 @@ local function remove_tag(player_index, tick)
tag.destroy()
end
local function corpse_expired(event)
local entity = event.corpse
if entity and entity.valid then
remove_tag(entity.character_corpse_player_index, entity.character_corpse_tick_of_death)
local function remove_corpse_tag(corpse)
if corpse and corpse.valid then
remove_tag(corpse.character_corpse_player_index, corpse.character_corpse_tick_of_death)
end
end
local function corpse_expired(event)
remove_corpse_tag(event.corpse)
end
local corpse_util_mined_entity = Token.register(function(data)
if not data.entity.valid then
remove_tag(data.player_index, data.tick)
@ -131,14 +137,14 @@ local function mined_entity(event)
local player_index = event.player_index
local corpse_owner_index = entity.character_corpse_player_index
if player_index == corpse_owner_index then
if player_index == corpse_owner_index or not entity.active then
return
end
local player = game.get_player(player_index)
local corpse_owner = game.get_player(corpse_owner_index)
if player and corpse_owner and entity.active then
if player and corpse_owner then
local message = table.concat {player.name, ' has looted ', corpse_owner.name, "'s corpse"}
Utils.action_warning('[Corpse]', message)
end
@ -153,28 +159,53 @@ local function on_gui_opened(event)
local player_index = event.player_index
local corpse_owner_index = entity.character_corpse_player_index
if player_index == corpse_owner_index then
if player_index == corpse_owner_index or not entity.active then
return
end
local player = game.get_player(player_index)
local corpse_owner = game.get_player(corpse_owner_index)
if player and corpse_owner and entity.active then
if player and corpse_owner then
local message = table.concat {player.name, ' is looting ', corpse_owner.name, "'s corpse"}
Utils.action_warning('[Corpse]', message)
end
end
local function on_gui_closed(event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
end
local entity = event.entity
if not entity or not entity.valid or entity.name ~= 'character-corpse' then
return
end
local inv_corpse = entity.get_inventory(defines.inventory.character_corpse)
if not inv_corpse or not inv_corpse.valid then
return
end
if inv_corpse.is_empty() then
remove_corpse_tag(entity)
entity.destroy()
end
end
Event.add(defines.events.on_player_died, player_died)
Event.add(defines.events.on_character_corpse_expired, corpse_expired)
Event.add(defines.events.on_pre_player_mined_item, mined_entity)
Event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_gui_closed, on_gui_closed)
function Public.clear()
table.clear_table(player_corpses)
end
Public.add_tag = add_tag
Public._player_died = player_died
Public.player_corpses = player_corpses

View File

@ -6,26 +6,33 @@ local Event = require 'utils.event'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Global = require 'utils.global'
local corpse_util = require 'features.corpse_util'
local CorpseUtil = require 'features.corpse_util'
local set_timeout_in_ticks = Task.set_timeout_in_ticks
local config = global.config.dump_offline_inventories
local offline_timout_mins = config.offline_timout_mins
local offline_player_queue = {}
Global.register({offline_player_queue = offline_player_queue}, function(tbl)
offline_player_queue = tbl.offline_player_queue
Global.register(offline_player_queue, function(tbl)
offline_player_queue = tbl
end)
local spawn_player_corpse =
Token.register(
function(data)
local player = data.player
if not player or not player.valid or player.connected or not offline_player_queue[player.index] or offline_player_queue[player.index].tick ~= data.tick then
if not player or not player.valid then
return
end
game.print("Debug: callback reached")
local player_index = player.index
local queue_data = offline_player_queue[player_index]
if queue_data ~= data.tick then
return
end
offline_player_queue[player_index] = nil
local inv_main = player.get_inventory(defines.inventory.character_main)
local inv_trash = player.get_inventory(defines.inventory.character_trash)
@ -34,8 +41,12 @@ local spawn_player_corpse =
local inv_corpse_size = (#inv_main - inv_main.count_empty_stacks()) + (#inv_trash - inv_trash.count_empty_stacks())
if inv_corpse_size <= 0 then
return
end
local position = player.position
local corpse = player.surface.create_entity{name="character-corpse", position=position, inventory_size = inv_corpse_size, player_index = player.index}
local corpse = player.surface.create_entity{name = "character-corpse", position = position, inventory_size = inv_corpse_size, player_index = player_index}
corpse.active = false
local inv_corpse = corpse.get_inventory(defines.inventory.character_corpse)
@ -50,47 +61,35 @@ local spawn_player_corpse =
inv_main.clear()
inv_trash.clear()
offline_player_queue[data.player.index] = nil
local text = player.name .. "'s inventory (offline)"
local tag = player.force.add_chart_tag(player.surface, {
icon = {type = 'item', name = 'modular-armor'},
position = position,
text = text
})
if tag then
corpse_util.player_corpses[player.index * 0x100000000 + game.tick] = tag
CorpseUtil.add_tag(tag, player_index, game.tick)
end
end
)
Event.add(
defines.events.on_player_joined_game,
function(event)
offline_player_queue[event.player_index] = nil -- ensures they're not in the offline_player_queue for wealth redistribution
end
)
local function start_timer(event, timeout)
local player_index = event.player_index
local player = game.get_player(player_index)
Event.add(
defines.events.on_pre_player_left_game,
function(event)
local player_index = event.player_index
local player = game.get_player(player_index)
if player and player.valid and player.character then -- if player leaves before respawning they wont have a character and we don't need to add them to the list
offline_player_queue[player_index] = game.tick -- tick is used to check that the callback happens after X minutes as multiple callbacks may be active if the player logs off and on multiple times
set_timeout_in_ticks(offline_timout_mins*60*60, spawn_player_corpse, {player = player, tick = game.tick})
end
if player and player.valid and player.character then -- if player leaves before respawning they wont have a character and we don't need to add them to the list
local tick = game.tick
offline_player_queue[player_index] = tick -- tick is used to check that the callback happens after X minutes as multiple callbacks may be active if the player logs off and on multiple times
set_timeout_in_ticks(timeout, spawn_player_corpse, {player = player, tick = tick})
end
)
end
Event.add(
defines.events.on_player_banned,
function(event)
local player_index = event.player_index
local player = game.get_player(player_index)
if player and player.valid and player.character then -- if player leaves before respawning they wont have a character and we don't need to add them to the list
offline_player_queue[player_index] = game.tick -- tick is used to check that the callback happens after X minutes as multiple callbacks may be active if the player logs off and on multiple times
set_timeout_in_ticks(60, spawn_player_corpse, {player = player, tick = game.tick})
end
end
)
Event.add(defines.events.on_pre_player_left_game, function(event)
local timeout = offline_timout_mins * 60 * 60
start_timer(event, timeout)
end)
Event.add(defines.events.on_player_banned, function(event)
start_timer(event, 60)
end)

View File

@ -44,13 +44,13 @@ local function control(config)
local map_gen_settings = config.map_gen_settings or default_map_gen_settings
RS.set_map_gen_settings(map_gen_settings)
end
--[[]]
RedmewConfig.market.enabled = false
RedmewConfig.biter_attacks.enabled = false
RedmewConfig.dump_offline_inventories = {
enabled = true,
offline_timout_mins = 1, -- time after which a player logs off that their inventory is provided to the team
}]]
offline_timout_mins = 0.5, -- time after which a player logs off that their inventory is provided to the team
}
-- leave seeds nil to have them filled in based on the map seed.