Fixed entity IDs occasionally getting messed up due to the gaps and hulls created by docking ports. Clients would simply use the existing hulls and gaps when a network event for an already docked port is received, even though they may have been removed and replaced with ones with different IDs.

This commit is contained in:
Joonas Rikkonen
2018-07-23 21:36:43 +03:00
parent be5f168b76
commit 002e63f1eb
@@ -27,7 +27,7 @@ namespace Barotrauma.Items.Components
private Joint joint; private Joint joint;
private Hull[] hulls; private readonly Hull[] hulls = new Hull[2];
private ushort?[] hullIds; private ushort?[] hullIds;
private Door door; private Door door;
@@ -238,7 +238,7 @@ namespace Barotrauma.Items.Components
{ {
if (GameMain.Client != null && !isNetworkMessage) return; if (GameMain.Client != null && !isNetworkMessage) return;
if (dockingTarget==null) if (dockingTarget == null)
{ {
DebugConsole.ThrowError("Error - attempted to lock a docking port that's not connected to anything"); DebugConsole.ThrowError("Error - attempted to lock a docking port that's not connected to anything");
return; return;
@@ -267,6 +267,9 @@ namespace Barotrauma.Items.Components
item.CreateServerEvent(this); item.CreateServerEvent(this);
} }
List<MapEntity> removedEntities = item.linkedTo.Where(e => e.Removed).ToList();
foreach (MapEntity removed in removedEntities) item.linkedTo.Remove(removed);
if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull)) if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull))
{ {
CreateHull(); CreateHull();
@@ -377,7 +380,6 @@ namespace Barotrauma.Items.Components
var hullRects = new Rectangle[] { item.WorldRect, dockingTarget.item.WorldRect }; var hullRects = new Rectangle[] { item.WorldRect, dockingTarget.item.WorldRect };
var subs = new Submarine[] { item.Submarine, dockingTarget.item.Submarine }; var subs = new Submarine[] { item.Submarine, dockingTarget.item.Submarine };
hulls = new Hull[2];
bodies = new Body[4]; bodies = new Body[4];
if (dockingTarget.door != null) if (dockingTarget.door != null)
@@ -406,6 +408,7 @@ namespace Barotrauma.Items.Components
hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition)); hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition));
hulls[i] = new Hull(MapEntityPrefab.Find("Hull"), hullRects[i], subs[i]); hulls[i] = new Hull(MapEntityPrefab.Find("Hull"), hullRects[i], subs[i]);
hulls[i].AddToGrid(subs[i]); hulls[i].AddToGrid(subs[i]);
if (hullIds[i] != null) hulls[i].ID = (ushort)hullIds[i];
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
{ {
@@ -436,7 +439,6 @@ namespace Barotrauma.Items.Components
hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition)); hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition));
hulls[i] = new Hull(MapEntityPrefab.Find("Hull"), hullRects[i], subs[i]); hulls[i] = new Hull(MapEntityPrefab.Find("Hull"), hullRects[i], subs[i]);
hulls[i].AddToGrid(subs[i]); hulls[i].AddToGrid(subs[i]);
if (hullIds[i] != null) hulls[i].ID = (ushort)hullIds[i]; if (hullIds[i] != null) hulls[i].ID = (ushort)hullIds[i];
} }
@@ -561,12 +563,8 @@ namespace Barotrauma.Items.Components
joint = null; joint = null;
} }
if (hulls != null) hulls[0]?.Remove(); hulls[0] = null;
{ hulls[1]?.Remove(); hulls[1] = null;
hulls[0].Remove();
hulls[1].Remove();
hulls = null;
}
if (gap != null) if (gap != null)
{ {
@@ -576,10 +574,9 @@ namespace Barotrauma.Items.Components
hullIds[0] = null; hullIds[0] = null;
hullIds[1] = null; hullIds[1] = null;
gapId = null; gapId = null;
if (bodies!=null) if (bodies != null)
{ {
foreach (Body body in bodies) foreach (Body body in bodies)
{ {
@@ -749,6 +746,21 @@ namespace Barotrauma.Items.Components
{ {
bool isDocked = msg.ReadBoolean(); bool isDocked = msg.ReadBoolean();
for (int i = 0; i < 2; i++)
{
if (hulls[i] == null) continue;
item.linkedTo.Remove(hulls[i]);
hulls[i].Remove();
hulls[i] = null;
}
if (gap != null)
{
item.linkedTo.Remove(gap);
gap.Remove();
gap = null;
}
if (isDocked) if (isDocked)
{ {
ushort dockingTargetID = msg.ReadUInt16(); ushort dockingTargetID = msg.ReadUInt16();