commit 7cc231bc51890e7fde50bbac3413328dd7bc5189 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Wed Mar 20 14:23:06 2019 +0200 Fixed server creating network events in Item.Load due to CreateServerEvent calls in some of the ItemComponent properties (e.g. LightComponent.IsOn). Caused syncing problems because the entity spawn events aren't created until the item has been loaded, leading to situations where clients fail to read events because the entity doesn't exist at their end yet (see #1293). TODO: get rid of console errors when attempting to create events during component initialization in the Item constructor. commit ac1bf32edf125d95d56775e1e8ce54ac7671328c Author: itchyOwl <lauri.harkanen@gmail.com> Date: Wed Mar 20 13:49:55 2019 +0200 Fix Hammerhead attack causing warping. Adjust the targeting priorities. commit e3e032d7c3a753397269bb4236c1494ab0809004 Author: itchyOwl <lauri.harkanen@gmail.com> Date: Wed Mar 20 13:48:47 2019 +0200 Enemy AI fixes: - Fix enemies "fleeing" after they have been shot. There was a steering issue when they targeted characters that were inside the sub when they were outside of it - Fix the previous target resetting too often - Fix the wall target resetting too often - Use world positions instead of sim positions where possible, because the sub positions are then taken into account commit 847cf5ffd9212a542000dbf12332b2c08756579a Author: Daniel Asteljoki <daniel.asteljoki@gmail.com> Date: Wed Mar 20 12:00:15 2019 +0200 Remora: added power connection between sub and drone, removed non-scaling hull parts commit a9c2e8cc124713e90dd44a9adf2fcbb3204b2c4d Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Wed Mar 20 11:24:37 2019 +0200 Server sets clients' last received campaign save/update IDs to one before the current up-to-date IDs (instead of zero) when a campaign changes. Zero would get interpreted as a more up-to-date ID if the IDs of the current campaign are close to ushort.MaxValue where the IDs wrap around. commit 07d82b64e6990eacaf8905aed1a5d7c61224e47d Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Tue Mar 19 18:24:01 2019 +0200 Log level inequality error messages & client error reports handled by the server to GameAnalytics
206 lines
7.4 KiB
C#
206 lines
7.4 KiB
C#
using Barotrauma.Networking;
|
|
using Microsoft.Xna.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
partial class EntitySpawner : Entity, IServerSerializable
|
|
{
|
|
const int MaxEntitiesPerWrite = 10;
|
|
|
|
private enum SpawnableType { Item, Character };
|
|
|
|
interface IEntitySpawnInfo
|
|
{
|
|
Entity Spawn();
|
|
}
|
|
|
|
class ItemSpawnInfo : IEntitySpawnInfo
|
|
{
|
|
public readonly ItemPrefab Prefab;
|
|
|
|
public readonly Vector2 Position;
|
|
public readonly Inventory Inventory;
|
|
public readonly Submarine Submarine;
|
|
public readonly float Condition;
|
|
|
|
public ItemSpawnInfo(ItemPrefab prefab, Vector2 worldPosition, float? condition = null)
|
|
{
|
|
Prefab = prefab ?? throw new ArgumentException("ItemSpawnInfo prefab cannot be null.");
|
|
Position = worldPosition;
|
|
Condition = condition ?? prefab.Health;
|
|
}
|
|
|
|
public ItemSpawnInfo(ItemPrefab prefab, Vector2 position, Submarine sub, float? condition = null)
|
|
{
|
|
Prefab = prefab ?? throw new ArgumentException("ItemSpawnInfo prefab cannot be null.");
|
|
Position = position;
|
|
Submarine = sub;
|
|
Condition = condition ?? prefab.Health;
|
|
}
|
|
|
|
public ItemSpawnInfo(ItemPrefab prefab, Inventory inventory, float? condition = null)
|
|
{
|
|
Prefab = prefab ?? throw new ArgumentException("ItemSpawnInfo prefab cannot be null.");
|
|
Inventory = inventory;
|
|
Condition = condition ?? prefab.Health;
|
|
}
|
|
|
|
public Entity Spawn()
|
|
{
|
|
if (Prefab == null)
|
|
{
|
|
return null;
|
|
}
|
|
Item spawnedItem = null;
|
|
if (Inventory != null)
|
|
{
|
|
spawnedItem = new Item(Prefab, Vector2.Zero, null);
|
|
Inventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots);
|
|
}
|
|
else
|
|
{
|
|
spawnedItem = new Item(Prefab, Position, Submarine);
|
|
}
|
|
return spawnedItem;
|
|
}
|
|
}
|
|
|
|
private readonly Queue<IEntitySpawnInfo> spawnQueue;
|
|
private readonly Queue<Entity> removeQueue;
|
|
|
|
public class SpawnOrRemove
|
|
{
|
|
public readonly Entity Entity;
|
|
|
|
public readonly bool Remove = false;
|
|
|
|
public SpawnOrRemove(Entity entity, bool remove)
|
|
{
|
|
Entity = entity;
|
|
Remove = remove;
|
|
}
|
|
}
|
|
|
|
public EntitySpawner()
|
|
: base(null)
|
|
{
|
|
spawnQueue = new Queue<IEntitySpawnInfo>();
|
|
removeQueue = new Queue<Entity>();
|
|
}
|
|
|
|
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 worldPosition, float? condition = null)
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
if (itemPrefab == null)
|
|
{
|
|
string errorMsg = "Attempted to add a null item to entity spawn queue.\n" + Environment.StackTrace;
|
|
DebugConsole.ThrowError(errorMsg);
|
|
GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
|
return;
|
|
}
|
|
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition, condition));
|
|
}
|
|
|
|
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, Submarine sub, float? condition = null)
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
if (itemPrefab == null)
|
|
{
|
|
string errorMsg = "Attempted to add a null item to entity spawn queue.\n" + Environment.StackTrace;
|
|
DebugConsole.ThrowError(errorMsg);
|
|
GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
|
return;
|
|
}
|
|
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub, condition));
|
|
}
|
|
|
|
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null)
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
if (itemPrefab == null)
|
|
{
|
|
string errorMsg = "Attempted to add a null item to entity spawn queue.\n" + Environment.StackTrace;
|
|
DebugConsole.ThrowError(errorMsg);
|
|
GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
|
return;
|
|
}
|
|
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory, condition));
|
|
}
|
|
|
|
public void AddToRemoveQueue(Entity entity)
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
if (removeQueue.Contains(entity) || entity.Removed || entity == null) { return; }
|
|
if (entity is Character)
|
|
{
|
|
Character character = entity as Character;
|
|
#if SERVER
|
|
if (GameMain.Server != null)
|
|
{
|
|
Client client = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
|
|
if (client != null) GameMain.Server.SetClientCharacter(client, null);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
removeQueue.Enqueue(entity);
|
|
}
|
|
|
|
public void AddToRemoveQueue(Item item)
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
if (removeQueue.Contains(item) || item.Removed) { return; }
|
|
|
|
removeQueue.Enqueue(item);
|
|
if (item.ContainedItems == null) return;
|
|
foreach (Item containedItem in item.ContainedItems)
|
|
{
|
|
if (containedItem != null) AddToRemoveQueue(containedItem);
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
|
while (spawnQueue.Count > 0)
|
|
{
|
|
var entitySpawnInfo = spawnQueue.Dequeue();
|
|
|
|
var spawnedEntity = entitySpawnInfo.Spawn();
|
|
if (spawnedEntity != null)
|
|
{
|
|
#if SERVER
|
|
CreateNetworkEvent(spawnedEntity, false);
|
|
#endif
|
|
if (spawnedEntity is Item)
|
|
{
|
|
((Item)spawnedEntity).Condition = ((ItemSpawnInfo)entitySpawnInfo).Condition;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (removeQueue.Count > 0)
|
|
{
|
|
var removedEntity = removeQueue.Dequeue();
|
|
|
|
#if SERVER
|
|
if (GameMain.Server != null)
|
|
{
|
|
CreateNetworkEvent(removedEntity, true);
|
|
}
|
|
#endif
|
|
|
|
removedEntity.Remove();
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
removeQueue.Clear();
|
|
spawnQueue.Clear();
|
|
}
|
|
}
|
|
}
|