Remove the inventory bonus raise on the armor inventory event

on_player_armor_inventory_changed for the restored armor is raised at
the end of the download's tick, after the inventory bonus of the armor's
equipment applied, so the raise is removed there instead of in the next
tick's on_tick. The raise is only made for armor with a grid, as the
event needs the armor to be restored.

A player leaving on the tick of a download no longer has the raise
removed from the character first, which shrank the main inventory
before the bonus applied and spilled the extra slots. The raise is
taken off the uploaded inventory bonus instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ILLISISandClaude Opus 5.5 committed 2026-10-18 22:34:34 +11:00
1 parent b32f5416a1
commit 4228b40562
2 files changed
+20 -20

No files matched your search

+15 -16
View File
@@ -86,9 +86,6 @@ end
-- This function is called internally when a player leaves the game to
-- serialize the player for upload.
function player_sync.serialize_player(player, player_record)
-- Leaving on the tick of a download, the temporary bonus must not be uploaded
remove_inventory_bonus_raise(get_script_data(), player.name)
-- Editor mode is not supported.
if player.controller_type == defines.controllers.editor then
player.toggle_map_editor()
@@ -116,6 +113,15 @@ function player_sync.serialize_player(player, player_record)
local serialized_player = serialize.serialize_player(player, failed_deserialization, player_record.components)
serialized_player.generation = player_record.generation
-- Leaving on the tick of a download the temporary bonus is still there and must not be uploaded. Removing it
-- from the character here would shrink the main inventory before the armor's bonus applies and spill items.
local raises = get_script_data().inventory_bonus_raises
local raise = raises and raises[player.name]
local character = serialized_player.character
if raise and character and raise.character == player.character then
character.character_inventory_slots_bonus = character.character_inventory_slots_bonus - raise.bonus
end
return serialized_player
end
@@ -150,6 +156,8 @@ function player_sync.deserialize_player(player, finished_record)
-- Deserialize downloaded player data
local serialized_player = compat.json_to_table(finished_record.data)
assert(type(serialized_player) == "table", "wrong type for serialized_player")
-- An earlier raise not removed yet is replaced, the character's inventory bonus is restored with the data
script_data.inventory_bonus_raises[player.name] = nil
local failed, spill, inventory_bonus_raise =
serialize.deserialize_player(player, serialized_player, finished_record.components, local_controller)
script_data.failed_deserialization[player.name] = failed
@@ -158,7 +166,6 @@ function player_sync.deserialize_player(player, finished_record)
script_data.inventory_bonus_raises[player.name] = {
character = player.character,
bonus = inventory_bonus_raise,
tick = game.tick,
}
end
@@ -419,18 +426,10 @@ player_sync.events[defines.events.on_player_joined_game] = function(event)
script_data.active_uploads[player.name] = nil
end
-- The inventory bonus of armor equipment applies on the tick after a download, the temporary bonus is no longer needed
player_sync.events[defines.events.on_tick] = function(event)
local script_data = get_script_data()
local raises = script_data.inventory_bonus_raises
if not raises or next(raises) == nil then
return
end
for player_name, raise in pairs(raises) do
if raise.tick < event.tick then
remove_inventory_bonus_raise(script_data, player_name)
end
end
-- Raised for a restored armor after its equipment's inventory bonus applied, the temporary bonus is no longer needed
player_sync.events[defines.events.on_player_armor_inventory_changed] = function(event)
local player = assert(game.get_player(event.player_index))
remove_inventory_bonus_raise(get_script_data(), player.name)
end
player_sync.on_nth_tick = {}
+5 -4
View File
@@ -83,7 +83,7 @@ local function last_slot_index(serialized)
end
--- Raise the inventory bonus of a character with its armor restored to fit a serialized main inventory
--- @return integer raise Slots added to character_inventory_slots_bonus, to be removed again on the next tick
--- @return integer raise Slots added to character_inventory_slots_bonus, removed again once the armor's bonus applies
local function raise_inventory_bonus(character, main)
local raise = math.max(0, last_slot_index(main) - #character.get_main_inventory())
character.character_inventory_slots_bonus = character.character_inventory_slots_bonus + raise
@@ -1386,12 +1386,13 @@ function serialize.deserialize_player(player, serialized, components, local_cont
serialize.deserialize_character(character, stats)
end
local craft = character and queue
-- The bonus of the armor's equipment (toolbelts) only applies on the next tick, so once the armor is
-- restored the main inventory is raised to fit the data
-- The bonus of the armor's equipment (toolbelts) only applies at the end of the tick, so once the armor is
-- restored the main inventory is raised to fit the data. Only for armor with a grid, restoring it raises
-- on_player_armor_inventory_changed which removes the raise.
spill = serialize.place_items(
serialize.item_destinations(player), inventories, not craft and queue and queue.ingredients or nil,
function()
if stats and inventories.main then
if stats and inventories.main and character and character.grid then
inventory_bonus_raise = raise_inventory_bonus(character, inventories.main)
end
end