Fix edge cases with physical location and controller

This commit is contained in:
Cooldude2606 committed 2026-04-22 22:37:42 +01:00
1 parent add0088704
commit 8be95c140a
3 files changed
+43 -6

No files matched your search

@@ -16,6 +16,8 @@ local get_script_data = require("modules/inventory_sync/get_script_data")
local progress_dialog = require("modules/inventory_sync/gui/progress_dialog")
local dialog_failed_download = require("modules/inventory_sync/gui/dialog_failed_download")
local v2_remote_controller = compat.version_ge("2.0.0")
-- Returns true if the player is currently in a cutscene
local function is_in_cutscene(player)
return player.controller_type == defines.controllers.cutscene
@@ -114,6 +116,11 @@ function inventory_sync.deserialize_player(player, finished_record)
-- Restore player position and driving state
restore_position(player, finished_record)
-- Return to remote if needed (restore position may exit remote view)
if serialized_player.remote then
player.set_controller{ type = defines.controllers.remote }
end
-- Transfer items from stashed inventory
if stashed_corpse then
local stash = stashed_corpse.get_inventory(defines.inventory.character_corpse)
@@ -440,8 +447,13 @@ function inventory_sync.initiate_inventory_download(player, player_record, gener
-- player data is downloading
if player_record.sync then
-- Store original position to teleport back to
record.surface = player.surface
record.position = player.position
if v2_remote_controller then
record.surface = player.physical_surface
record.position = player.physical_position
else
record.surface = player.surface
record.position = player.position
end
if player.driving then
record.vehicle = player.vehicle
end
@@ -1,9 +1,14 @@
local compat = require("modules/clusterio/compat")
local can_enter_vehicle = {
[defines.controllers.character] = true,
[defines.controllers.god] = true,
[defines.controllers.editor] = true,
[defines.controllers.remote] = true,
}
local v2_surface_platform = compat.version_ge("2.0.0")
--- @param player LuaPlayer
--- @param record table
return function(player, record)
@@ -20,6 +25,8 @@ return function(player, record)
player.teleport(safe_position, player.surface)
end
end
elseif v2_surface_platform and record.surface and record.surface.platform and can_enter_vehicle[player.controller_type] then
player.enter_space_platform(record.surface.platform)
elseif record.surface and record.position then
player.teleport(record.position, record.surface)
end
+22 -4
View File
@@ -6,6 +6,7 @@ local serialize = {}
local v2_logistic_api = compat.version_ge("2.0.0")
local v2_storage_api = compat.version_ge("2.0.0")
local v2_remote_controller = compat.version_ge("2.0.0")
local recipe_notifications_api = compat.version_ge("2.0.67")
function serialize.serialize_inventories(source, inventories)
@@ -428,6 +429,7 @@ end
--- @field generation number
--- @field name string
--- @field controller string
--- @field remote boolean
--- @field color Color
--- @field chat_color Color
--- @field tag string
@@ -450,6 +452,7 @@ function serialize.serialize_player(player, failed_deserialization)
local serialized = {
generation = 0, -- Gets replaced later
controller = controller_to_name[player.controller_type],
remote = false,
name = player.name,
color = player.color,
chat_color = player.chat_color,
@@ -460,6 +463,11 @@ function serialize.serialize_player(player, failed_deserialization)
ticks_to_respawn = player.ticks_to_respawn,
}
if v2_remote_controller then
serialized.remote = player.controller_type == defines.controllers.remote
serialized.controller = controller_to_name[player.physical_controller_type]
end
-- For the waiting to respawn state the inventory logistic requests and filters are hidden on the player
if player.controller_type == defines.controllers.ghost and player.ticks_to_respawn then
player.ticks_to_respawn = nil -- Respawn now
@@ -482,7 +490,9 @@ function serialize.serialize_player(player, failed_deserialization)
end
-- Serialize non-character inventories
if player.controller_type == defines.controllers.god then
if player.controller_type == defines.controllers.god
or v2_remote_controller and player.physical_controller_type == defines.controllers.god
then
serialized.inventories = serialize.serialize_inventories(player, { main = defines.inventory.god_main })
end
@@ -541,8 +551,8 @@ function serialize.deserialize_player(player, serialized)
local target_controller = defines.controllers[serialized.controller]
if player.controller_type ~= target_controller or serialized.controller == "ghost" then
if serialized.controller == "character" or serialized.controller == "remote" then
-- Character and Remote both require a character, but must not destroy an existing one
if serialized.controller == "character" then
-- Create a character but do not destroy an existing one
ensure_character(player)
if player.controller_type ~= target_controller then
player.set_controller{ type = target_controller }
@@ -570,7 +580,7 @@ function serialize.deserialize_player(player, serialized)
character.destroy()
end
else
elseif serialized.controller ~= "remote" then
-- All other controllers should not have a character
local character = player.character
if character and character.valid then
@@ -579,6 +589,9 @@ function serialize.deserialize_player(player, serialized)
if player.controller_type ~= target_controller then
player.set_controller{ type = target_controller }
end
else
error("Remote should not be 'serialized.controller'")
end
end
@@ -624,6 +637,11 @@ function serialize.deserialize_player(player, serialized)
serialize.deserialize_crafting_notifications(player, serialized.recipe_notifications)
end
-- Return to remote view after physical controller has been synced
if serialized.remote then
player.set_controller{ type = defines.controllers.remote }
end
return next(failed_deserialization) and failed_deserialization or nil
end