diff --git a/features/corpse_util.lua b/features/corpse_util.lua index b55006df..b7067617 100644 --- a/features/corpse_util.lua +++ b/features/corpse_util.lua @@ -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 diff --git a/features/dump_offline_inventories.lua b/features/dump_offline_inventories.lua index f26a939b..badca895 100644 --- a/features/dump_offline_inventories.lua +++ b/features/dump_offline_inventories.lua @@ -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 -) \ No newline at end of file +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) \ No newline at end of file diff --git a/map_gen/maps/crash_site/scenario.lua b/map_gen/maps/crash_site/scenario.lua index e0d662e8..f53a02b8 100644 --- a/map_gen/maps/crash_site/scenario.lua +++ b/map_gen/maps/crash_site/scenario.lua @@ -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.