Fixed "collection was modified" exceptions when a huskified human is killed while enumerating the character list (e.g. when killed by an explosion)

This commit is contained in:
Joonas Rikkonen
2017-08-09 19:37:37 +03:00
parent 6eba16ff4e
commit f7f738765b
@@ -1,4 +1,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System.Collections;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Xml.Linq; using System.Xml.Linq;
@@ -140,13 +142,22 @@ namespace Barotrauma
private void CharacterDead(Character character, CauseOfDeath causeOfDeath) private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
{ {
if (GameMain.Client != null) return; if (GameMain.Client != null) return;
//create the AI husk in a coroutine to ensure that we don't modify the character list while enumerating it
CoroutineManager.StartCoroutine(CreateAIHusk(character));
}
private IEnumerable<object> CreateAIHusk(Character character)
{
character.Enabled = false;
Entity.Spawner.AddToRemoveQueue(character);
var husk = Character.Create( var husk = Character.Create(
Path.Combine("Content", "Characters", "Human", "humanhusk.xml"), Path.Combine("Content", "Characters", "Human", "humanhusk.xml"),
character.WorldPosition, character.WorldPosition,
character.Info, character.Info,
false, true); false, true);
foreach (Limb limb in husk.AnimController.Limbs) foreach (Limb limb in husk.AnimController.Limbs)
{ {
if (limb.type == LimbType.None) if (limb.type == LimbType.None)
@@ -155,18 +166,21 @@ namespace Barotrauma
continue; continue;
} }
var matchingLimb = character.AnimController.GetLimb(limb.type); var matchingLimb = character.AnimController.GetLimb(limb.type);
limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); if (matchingLimb?.body != null)
{
limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation);
limb.body.LinearVelocity = matchingLimb.LinearVelocity;
limb.body.AngularVelocity = matchingLimb.body.AngularVelocity;
}
} }
for (int i = 0; i < character.Inventory.Items.Length; i++) for (int i = 0; i < character.Inventory.Items.Length; i++)
{ {
if (character.Inventory.Items[i] == null) continue; if (character.Inventory.Items[i] == null) continue;
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, null); husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, null);
} }
character.Enabled = false; yield return CoroutineStatus.Success;
Entity.Spawner.AddToRemoveQueue(character);
} }
} }
} }