From ceaba2f5caca0bf64ee42b48c99b9a794fb17cf6 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 23 Apr 2018 13:55:08 +0300 Subject: [PATCH] Fixed some entities occasionally not being removed at the end of a round. CargoMission removed the cargo items at the end of a round without checking if the items have already been removed, which could cause another entity to be removed from the entity dictionary if it's taken the ID of the cargo item. This prevented the new entity from being removed in Entity.RemoveAll, causing errors during the next round. Closes #278 --- .../Source/Characters/Character.cs | 2 ++ .../Source/Events/Missions/CargoMission.cs | 7 +++++-- .../Source/Items/Components/ItemContainer.cs | 2 +- .../BarotraumaShared/Source/Items/Item.cs | 7 +++++++ .../BarotraumaShared/Source/Map/Entity.cs | 20 ++++++++++++++++++- .../Source/Networking/EntitySpawner.cs | 2 +- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index 1495cc0ac..8d681550d 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -2025,7 +2025,9 @@ namespace Barotrauma if (Removed) { DebugConsole.ThrowError("Attempting to remove an already removed character\n" + Environment.StackTrace); + return; } + DebugConsole.Log("Removing character " + Name + " (ID: " + ID + ")"); base.Remove(); diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs index 77039b48b..7f6c8006c 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs @@ -96,7 +96,7 @@ namespace Barotrauma { if (Submarine.MainSub != null && Submarine.MainSub.AtEndPosition) { - int deliveredItemCount = items.Count(i => i.CurrentHull != null && i.Condition > 0.0f); + int deliveredItemCount = items.Count(i => i.CurrentHull != null && !i.Removed && i.Condition > 0.0f); if (deliveredItemCount >= requiredDeliveryAmount) { @@ -106,7 +106,10 @@ namespace Barotrauma } } - items.ForEach(i => i.Remove()); + foreach (Item item in items) + { + if (!item.Removed) item.Remove(); + } } } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs index 9016ba8fd..e9fae6c86 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs @@ -219,7 +219,7 @@ namespace Barotrauma.Items.Components foreach (Item item in Inventory.Items) { if (item == null) continue; - item.Remove(); + item.Drop(); } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 463f5eb62..45071b9fe 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1860,6 +1860,13 @@ namespace Barotrauma public override void Remove() { + if (Removed) + { + DebugConsole.ThrowError("Attempting to remove an already removed item\n" + Environment.StackTrace); + return; + } + DebugConsole.Log("Removing item " + Name + " (ID: " + ID + ")"); + base.Remove(); foreach (Character character in Character.CharacterList) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Entity.cs b/Barotrauma/BarotraumaShared/Source/Map/Entity.cs index f2d49d803..ac0046d75 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Entity.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Entity.cs @@ -42,10 +42,13 @@ namespace Barotrauma Entity existingEntity; if (dictionary.TryGetValue(value, out existingEntity)) { - System.Diagnostics.Debug.WriteLine(existingEntity+" had the same ID as "+this); + System.Diagnostics.Debug.WriteLine(existingEntity + " had the same ID as " + this + " (" + value + ")"); + DebugConsole.Log(existingEntity + " had the same ID as " + this + " (" + value + ")"); dictionary.Remove(value); dictionary.Add(id, existingEntity); existingEntity.id = id; + DebugConsole.Log("The id of " + existingEntity + " is now " + id); + DebugConsole.Log("The id of " + this + " is now " + value); } id = value; @@ -183,6 +186,21 @@ namespace Barotrauma public virtual void Remove() { + DebugConsole.Log("Removing entity " + this.ToString() + " (" + ID + ") from entity dictionary."); + Entity existingEntity; + if (!dictionary.TryGetValue(ID, out existingEntity)) + { + DebugConsole.Log("Entity " + this.ToString() + " (" + ID + ") not present in entity dictionary."); + } + else if (existingEntity != this) + { + DebugConsole.Log("Entity ID mismatch in entity dictionary. Entity " + existingEntity + " had the ID " + ID); + foreach (var keyValuePair in dictionary.Where(kvp => kvp.Value == this).ToList()) + { + dictionary.Remove(keyValuePair.Key); + } + } + dictionary.Remove(ID); Removed = true; } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs b/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs index 448cbd819..961abccf2 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs @@ -196,7 +196,7 @@ namespace Barotrauma else if (entities.Entity is Character) { message.Write((byte)SpawnableType.Character); - DebugConsole.NewMessage("WRITING CHARACTER DATA: " + (entities.Entity).ToString(),Color.Cyan); + DebugConsole.NewMessage("WRITING CHARACTER DATA: " + (entities.Entity).ToString() + " (ID: " + entities.Entity.ID + ")", Color.Cyan); ((Character)entities.Entity).WriteSpawnData(message); } }