EntityEvents and EntitySpawner used to work independently of each other, with separate IDs, and there was no guarantee that spawning and events would happen in the correct order. For example, a client could fail to read events during midround syncing because the entity has been removed, or read an event for an incorrect entity because the entity has been removed and the ID taken by some other entity.
143 lines
3.8 KiB
C#
143 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using Lidgren.Network;
|
|
using Microsoft.Xna.Framework;
|
|
using Barotrauma.Networking;
|
|
using System.Linq;
|
|
using System;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
class Entity
|
|
{
|
|
private static Dictionary<ushort, Entity> dictionary = new Dictionary<ushort, Entity>();
|
|
|
|
public static EntitySpawner Spawner;
|
|
|
|
private ushort id;
|
|
|
|
protected AITarget aiTarget;
|
|
//protected float soundRange;
|
|
//protected float sightRange;
|
|
|
|
public ushort ID
|
|
{
|
|
get
|
|
{
|
|
return id;
|
|
}
|
|
set
|
|
{
|
|
Entity thisEntity;
|
|
if (dictionary.TryGetValue(id, out thisEntity) && thisEntity == this)
|
|
{
|
|
dictionary.Remove(id);
|
|
}
|
|
//if there's already an entity with the same ID, give it the old ID of this one
|
|
Entity existingEntity;
|
|
if (dictionary.TryGetValue(value, out existingEntity))
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(existingEntity+" had the same ID as "+this);
|
|
dictionary.Remove(value);
|
|
dictionary.Add(id, existingEntity);
|
|
existingEntity.id = id;
|
|
}
|
|
|
|
id = value;
|
|
dictionary.Add(id, this);
|
|
}
|
|
}
|
|
|
|
public virtual Vector2 SimPosition
|
|
{
|
|
get { return Vector2.Zero; }
|
|
}
|
|
|
|
public virtual Vector2 Position
|
|
{
|
|
get { return Vector2.Zero; }
|
|
}
|
|
|
|
public virtual Vector2 WorldPosition
|
|
{
|
|
get { return Submarine == null ? Position : Submarine.Position + Position; }
|
|
}
|
|
|
|
public virtual Vector2 DrawPosition
|
|
{
|
|
get { return Submarine == null ? Position : Submarine.DrawPosition + Position; }
|
|
}
|
|
|
|
public Submarine Submarine
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public AITarget AiTarget
|
|
{
|
|
get { return aiTarget; }
|
|
}
|
|
|
|
public Entity(Submarine submarine)
|
|
{
|
|
this.Submarine = submarine;
|
|
|
|
//give an unique ID
|
|
bool IDfound;
|
|
id = submarine == null ? (ushort)1 : submarine.IdOffset;
|
|
do
|
|
{
|
|
id += 1;
|
|
IDfound = dictionary.ContainsKey(id);
|
|
} while (IDfound);
|
|
|
|
dictionary.Add(id, this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find an entity based on the ID
|
|
/// </summary>
|
|
public static Entity FindEntityByID(ushort ID)
|
|
{
|
|
Entity matchingEntity;
|
|
dictionary.TryGetValue(ID, out matchingEntity);
|
|
|
|
return matchingEntity;
|
|
}
|
|
|
|
public static void RemoveAll()
|
|
{
|
|
List<Entity> list = new List<Entity>(dictionary.Values);
|
|
foreach (Entity e in list)
|
|
{
|
|
try
|
|
{
|
|
e.Remove();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugConsole.ThrowError("Error while removing entity \"" + e.ToString() + "\"", exception);
|
|
}
|
|
}
|
|
dictionary.Clear();
|
|
}
|
|
|
|
public virtual void Remove()
|
|
{
|
|
dictionary.Remove(ID);
|
|
}
|
|
|
|
public static void DumpIds(int count)
|
|
{
|
|
List<Entity> entities = dictionary.Values.OrderByDescending(e => e.id).ToList();
|
|
|
|
count = Math.Min(entities.Count, count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
DebugConsole.ThrowError(entities[i].id + ": " + entities[i].ToString());
|
|
}
|
|
}
|
|
}
|
|
}
|