mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 23:24:52 +09:00
Merge pull request #894 from Cooldude2606/fix/892
Fix accessing main inventory when in map view
This commit is contained in:
3 files changed
+91
-42
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
|
||||
@@ -116,9 +118,9 @@ function inventory_sync.deserialize_player(player, finished_record)
|
||||
|
||||
-- Transfer items from stashed inventory
|
||||
if stashed_corpse then
|
||||
local main = player.get_main_inventory()
|
||||
local stash = stashed_corpse.get_inventory(defines.inventory.character_corpse)
|
||||
if main then
|
||||
if player.character then
|
||||
local main = player.character.get_main_inventory()
|
||||
for i = 1, #stash do
|
||||
-- Try transferring a stack
|
||||
local source = stash[i]
|
||||
@@ -312,7 +314,7 @@ function inventory_sync.sync_player(acquire_response)
|
||||
end
|
||||
|
||||
function inventory_sync.finish_download(player, finished_record)
|
||||
local status, result = pcall(inventory_sync.deserialize_player, player, finished_record)
|
||||
local status, result = xpcall(inventory_sync.deserialize_player, debug.traceback, player, finished_record)
|
||||
if not status then
|
||||
log("ERROR: Deserializing player " .. player.name .. " failed: " .. result)
|
||||
player.print("ERROR: Deserializing player data failed: " .. result)
|
||||
@@ -382,7 +384,7 @@ inventory_sync.events[defines.events.on_pre_player_left_game] = function(event)
|
||||
end
|
||||
|
||||
player_record.generation = player_record.generation + 1
|
||||
local status, result = pcall(inventory_sync.serialize_player, player, player_record)
|
||||
local status, result = xpcall(inventory_sync.serialize_player, debug.traceback, player, player_record)
|
||||
if not status then
|
||||
log("ERROR: Serializing player " .. player.name .. " failed: " .. result)
|
||||
player.print("ERROR: Serializing player data failed: " .. result)
|
||||
@@ -440,8 +442,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,18 @@
|
||||
local compat = require("modules/clusterio/compat")
|
||||
|
||||
local can_enter_vehicle = {
|
||||
[defines.controllers.character] = true,
|
||||
[defines.controllers.god] = true,
|
||||
[defines.controllers.editor] = true,
|
||||
}
|
||||
|
||||
if defines.controllers.remote then
|
||||
-- Does not exist in 1.1, so we need this nil check
|
||||
can_enter_vehicle[defines.controllers.remote] = true
|
||||
end
|
||||
|
||||
local v2_surface_platform = compat.version_ge("2.0.0")
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param record table
|
||||
return function(player, record)
|
||||
@@ -20,6 +29,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
|
||||
|
||||
@@ -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)
|
||||
@@ -203,7 +204,7 @@ function serialize.serialize_crafting_queue(player)
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
|
||||
|
||||
-- Save current items
|
||||
local inventory = player.get_main_inventory()
|
||||
local inventory = player.character.get_main_inventory()
|
||||
local old_items = inventory.get_contents()
|
||||
local crafting_queue_progress = player.crafting_queue_progress
|
||||
|
||||
@@ -317,7 +318,7 @@ function serialize.serialize_crafting_queue(player)
|
||||
end
|
||||
|
||||
function serialize.deserialize_crafting_queue(player, serialized)
|
||||
local inventory = player.get_main_inventory()
|
||||
local inventory = player.character.get_main_inventory()
|
||||
|
||||
-- Give player some more inventory space to avoid duplicating items
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
|
||||
@@ -460,6 +461,11 @@ function serialize.serialize_player(player, failed_deserialization)
|
||||
ticks_to_respawn = player.ticks_to_respawn,
|
||||
}
|
||||
|
||||
-- In 2.0 we want to sync the physical controller to ignore remote view
|
||||
if v2_remote_controller then
|
||||
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 +488,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
|
||||
|
||||
@@ -510,6 +518,26 @@ function serialize.serialize_player(player, failed_deserialization)
|
||||
return serialized
|
||||
end
|
||||
|
||||
--- Ensure a player has a character, works from any controller type
|
||||
--- @param player LuaPlayer
|
||||
--- @return LuaEntity
|
||||
local function ensure_character(player)
|
||||
-- Do nothing if the player has a valid character
|
||||
local character = player.character
|
||||
if character and character.valid then
|
||||
return character
|
||||
end
|
||||
|
||||
-- Switch to god controller if create_character would fail
|
||||
if player.controller_type ~= defines.controllers.god then
|
||||
player.set_controller{ type = defines.controllers.god }
|
||||
end
|
||||
|
||||
-- Create and return the character
|
||||
assert(player.create_character(), "Failed to create character")
|
||||
return player.character
|
||||
end
|
||||
|
||||
--- @class FailedDeserializationPlayerData
|
||||
--- @field recipe_notifications string[]?
|
||||
|
||||
@@ -519,46 +547,49 @@ end
|
||||
function serialize.deserialize_player(player, serialized)
|
||||
local failed_deserialization = {}
|
||||
|
||||
if player.controller_type ~= defines.controllers[serialized.controller] or serialized.controller == "ghost" then
|
||||
-- If targeting the character or ghost controller then create a character
|
||||
if serialized.controller == "character" or serialized.controller == "ghost" then
|
||||
if player.controller_type == defines.controllers.ghost or player.controller_type == defines.controllers.spectator then
|
||||
player.set_controller({ type = defines.controllers.god })
|
||||
end
|
||||
if player.controller_type == defines.controllers.god then
|
||||
player.create_character()
|
||||
local target_controller = defines.controllers[serialized.controller]
|
||||
if player.controller_type ~= target_controller or serialized.controller == "ghost" then
|
||||
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 }
|
||||
end
|
||||
|
||||
-- The ghost state stores hidden logistic and filters which are only accessible in the character controller
|
||||
if serialized.controller == "ghost" then
|
||||
elseif serialized.controller == "ghost" then
|
||||
-- Ghost state stores hidden logistic and filters which are only accessible in the character controller
|
||||
local character = ensure_character(player)
|
||||
if serialized.personal_logistic_slots then
|
||||
serialize.deserialize_personal_logistic_slots(player, serialized.personal_logistic_slots)
|
||||
end
|
||||
if serialized.inventories then
|
||||
serialize.deserialize_inventories(player, serialized.inventories, character_inventories)
|
||||
local character = player.character
|
||||
if serialized.ticks_to_respawn then
|
||||
player.ticks_to_respawn = serialized.ticks_to_respawn
|
||||
else
|
||||
-- We have to set ticks to respawn to save the hidden state into the player but we
|
||||
-- can't unset tick_to_respawn by setting it back to nil as that triggers a respawn.
|
||||
player.ticks_to_respawn = 0
|
||||
player.set_controller({ type = defines.controllers.god })
|
||||
player.set_controller({ type = defines.controllers.ghost })
|
||||
end
|
||||
if character and character.valid then
|
||||
character.destroy()
|
||||
end
|
||||
end
|
||||
if serialized.ticks_to_respawn then
|
||||
player.ticks_to_respawn = serialized.ticks_to_respawn
|
||||
else
|
||||
-- We have to set ticks to respawn to save the hidden state into the player but we
|
||||
-- can't unset tick_to_respawn by setting it back to nil as that triggers a respawn.
|
||||
player.ticks_to_respawn = 0
|
||||
player.set_controller{ type = defines.controllers.god }
|
||||
player.set_controller{ type = defines.controllers.ghost }
|
||||
end
|
||||
if character and character.valid then
|
||||
character.destroy()
|
||||
end
|
||||
|
||||
elseif serialized.controller ~= "remote" then
|
||||
-- All other controllers should not have a character
|
||||
local character = player.character
|
||||
if character and character.valid then
|
||||
character.destroy()
|
||||
end
|
||||
if player.controller_type ~= target_controller then
|
||||
player.set_controller{ type = target_controller }
|
||||
end
|
||||
|
||||
else
|
||||
-- Targeting the god or spectator controller, if coming from the
|
||||
-- character controller then destroy the character
|
||||
if player.controller_type == defines.controllers.character then
|
||||
player.character.destroy()
|
||||
end
|
||||
|
||||
-- Switching to god or spectator is a matter of setting the controller
|
||||
if player.controller_type ~= defines.controllers[serialized.controller] then
|
||||
player.set_controller({ type = defines.controllers[serialized.controller] })
|
||||
end
|
||||
error("Remote should not be 'serialized.controller'")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in new issue
Block a user