From 5c06210265e5b71a753c574616a0e3b51919f014 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 23 May 2019 15:17:55 +0300 Subject: [PATCH] (c01fdfc22) Attempt to fix items dropping out of the inventory in multiplayer, part 527: Inventory.ServerRead first drops all items that are in incorrect slots from the inventory, and then places the current items into correct slots. I think the problem was that the items were not necessarily dropped at the exact position of the character, because the physics update is run between the item position update and reading the network event. This occasionally caused the item to end up in a position where the character can't pick it again when placing the items into correct slots. Now the position of the item is forced to the position of the character during the dropping, and the CanClientAccess check is not done on items that were already in the character's inventory. --- .../BarotraumaServer/Source/Items/Inventory.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs b/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs index 6d13e1aaf..6083c156e 100644 --- a/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs @@ -62,7 +62,16 @@ namespace Barotrauma if (newItemIDs[i] == 0 || (newItem != Items[i])) { - if (Items[i] != null) Items[i].Drop(null); + if (Items[i] != null) + { + Item droppedItem = Items[i]; + Entity prevOwner = Owner; + droppedItem.Drop(null); + if (droppedItem.body != null && prevOwner != null) + { + droppedItem.body.SetTransform(prevOwner.SimPosition, 0.0f); + } + } System.Diagnostics.Debug.Assert(Items[i] == null); } } @@ -79,7 +88,10 @@ namespace Barotrauma var holdable = item.GetComponent(); if (holdable != null && !holdable.CanBeDeattached()) continue; - if (!item.CanClientAccess(c)) continue; + if (!prevItems.Contains(item) && !item.CanClientAccess(c)) + { + continue; + } } TryPutItem(item, i, true, true, c.Character, false); for (int j = 0; j < capacity; j++)