Merge branch 'new-netcode' of https://gitlab.com/poe.regalis/barotrauma into new-netcode

# Conflicts:
#	Subsurface/Source/Characters/Character.cs
This commit is contained in:
juanjp600
2017-01-08 12:30:56 -03:00
10 changed files with 284 additions and 135 deletions
@@ -155,8 +155,8 @@ namespace Barotrauma
if (!flip) return; if (!flip) return;
flipTimer += deltaTime; flipTimer += deltaTime;
if (TargetDir != dir) if (TargetDir != Direction.None && TargetDir != dir)
{ {
if (flipTimer>1.0f || character.IsRemotePlayer) if (flipTimer>1.0f || character.IsRemotePlayer)
{ {
+46 -49
View File
@@ -825,7 +825,7 @@ namespace Barotrauma
public void Control(float deltaTime, Camera cam) public void Control(float deltaTime, Camera cam)
{ {
if (isDead || AnimController.StunTimer>0.0f) return; if (!AllowInput) return;
Vector2 targetMovement = GetTargetMovement(); Vector2 targetMovement = GetTargetMovement();
@@ -1346,30 +1346,31 @@ namespace Barotrauma
if (GameMain.Server != null && !(this is AICharacter) && AllowInput) if (GameMain.Server != null && !(this is AICharacter) && AllowInput)
{ {
if (memInput.Count == 0) if (memInput.Count == 0)
{
if (AllowInput) AnimController.Frozen = true;
return;
}
AnimController.Frozen = false;
prevDequeuedInput = dequeuedInput;
dequeuedInput = memInput[memInput.Count - 1];
memInput.RemoveAt(memInput.Count - 1);
cursorPosition = memMousePos[memMousePos.Count - 1];
memMousePos.RemoveAt(memMousePos.Count - 1);
TransformCursorPos();
if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.2f)
{ {
while (memInput.Count > 5 && memInput[memInput.Count - 1] == InputNetFlags.None) AnimController.Frozen = true;
}
else
{
AnimController.Frozen = false;
prevDequeuedInput = dequeuedInput;
dequeuedInput = memInput[memInput.Count - 1];
memInput.RemoveAt(memInput.Count - 1);
cursorPosition = memMousePos[memMousePos.Count - 1];
memMousePos.RemoveAt(memMousePos.Count - 1);
TransformCursorPos();
if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.2f)
{ {
//remove inputs where the player is not moving at all while (memInput.Count > 5 && memInput[memInput.Count - 1] == 0)
//helps the server catch up, shouldn't affect final position {
memInput.RemoveAt(memInput.Count - 1); //remove inputs where the player is not moving at all
memMousePos.RemoveAt(memMousePos.Count - 1); //helps the server catch up, shouldn't affect final position
memInput.RemoveAt(memInput.Count - 1);
memMousePos.RemoveAt(memMousePos.Count - 1);
}
} }
} }
} }
@@ -1465,12 +1466,7 @@ namespace Barotrauma
ControlLocalPlayer(deltaTime, cam); ControlLocalPlayer(deltaTime, cam);
} }
if (controlled == this || Control(deltaTime, cam);
!(this is AICharacter) ||
!((AICharacter)this).AIController.Enabled)
{
Control(deltaTime, cam);
}
if (selectedConstruction != null && !selectedConstruction.IsInPickRange(WorldPosition)) if (selectedConstruction != null && !selectedConstruction.IsInPickRange(WorldPosition))
{ {
@@ -1822,7 +1818,7 @@ namespace Barotrauma
{ {
if (!isNetworkMessage) if (!isNetworkMessage)
{ {
if (GameMain.NetworkMember != null && controlled != this) return; if (GameMain.Client != null) return;
} }
Health = minHealth; Health = minHealth;
@@ -2071,18 +2067,16 @@ namespace Barotrauma
{ {
msg.Write(ID); msg.Write(ID);
NetBuffer tempBuffer = new NetBuffer();
if (this == c.Character) if (this == c.Character)
{ {
//length of the message tempBuffer.Write(true);
msg.Write((byte)(4+4+4)); tempBuffer.Write((UInt32)(LastNetworkUpdateID - memInput.Count - 1));
msg.Write(true);
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count - 1));
} }
else else
{ {
//length of the message tempBuffer.Write(false);
msg.Write((byte)(4+4+1 + 1 + 1));
msg.Write(false);
bool aiming = false; bool aiming = false;
bool use = false; bool use = false;
@@ -2100,33 +2094,36 @@ namespace Barotrauma
networkUpdateSent = true; networkUpdateSent = true;
} }
msg.Write(aiming); tempBuffer.Write(aiming);
msg.Write(use); tempBuffer.Write(use);
if (selectedCharacter != null || selectedConstruction != null) if (selectedCharacter != null || selectedConstruction != null)
{ {
msg.Write(true); tempBuffer.Write(true);
msg.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID); tempBuffer.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID);
} }
else else
{ {
msg.Write(false); tempBuffer.Write(false);
} }
if (aiming) if (aiming)
{ {
//TODO: write this with less accuracy? //TODO: write this with less accuracy?
msg.Write(cursorPosition.X);
msg.Write(cursorPosition.Y); tempBuffer.Write(cursorPosition.X);
tempBuffer.Write(cursorPosition.Y);
} }
msg.Write(AnimController.TargetDir == Direction.Right); tempBuffer.Write(AnimController.TargetDir == Direction.Right);
} }
msg.Write(SimPosition.X); tempBuffer.Write(SimPosition.X);
msg.Write(SimPosition.Y); tempBuffer.Write(SimPosition.Y);
msg.Write((byte)tempBuffer.LengthBytes);
msg.Write(tempBuffer);
msg.WritePadBits(); msg.WritePadBits();
} }
@@ -45,9 +45,14 @@ namespace Barotrauma.Items.Components
list.Add(this); list.Add(this);
} }
public bool CanTransmit()
{
return HasRequiredContainedItems(true);
}
public void Transmit(string signal) public void Transmit(string signal)
{ {
if (!HasRequiredContainedItems(true)) return; if (!CanTransmit()) return;
var receivers = GetReceiversInRange(); var receivers = GetReceiversInRange();
foreach (WifiComponent w in receivers) foreach (WifiComponent w in receivers)
@@ -60,14 +65,22 @@ namespace Barotrauma.Items.Components
private List<WifiComponent> GetReceiversInRange() private List<WifiComponent> GetReceiversInRange()
{ {
return list.FindAll(w => return list.FindAll(w => w != this && w.CanReceive(this));
w != this && w.channel == channel && }
Vector2.Distance(item.WorldPosition, w.item.WorldPosition) <= Range);
public bool CanReceive(WifiComponent sender)
{
if (!HasRequiredContainedItems(false)) return false;
if (sender == null || sender.channel != channel) return false;
return Vector2.Distance(item.WorldPosition, sender.item.WorldPosition) <= sender.Range;
} }
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power=0.0f) public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power=0.0f)
{ {
if (!HasRequiredContainedItems(false)) return; var senderComponent = sender.GetComponent<WifiComponent>();
if (senderComponent != null && !CanReceive(senderComponent)) return;
if (LinkToChat) if (LinkToChat)
{ {
@@ -76,7 +89,10 @@ namespace Barotrauma.Items.Components
item.ParentInventory.Owner == Character.Controlled && item.ParentInventory.Owner == Character.Controlled &&
GameMain.NetworkMember != null) GameMain.NetworkMember != null)
{ {
signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, range); if (senderComponent != null)
{
signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, senderComponent.range);
}
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio); GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio);
} }
+5 -9
View File
@@ -40,10 +40,11 @@ namespace Barotrauma.Networking
} }
public static UInt32 LastID = 0; public static UInt32 LastID = 0;
public UInt32 netStateID = 0;
public UInt32 NetStateID public UInt32 NetStateID
{ {
get { return netStateID; } get;
set;
} }
private ChatMessage(string senderName, string text, ChatMessageType type, Character sender) private ChatMessage(string senderName, string text, ChatMessageType type, Character sender)
@@ -56,12 +57,6 @@ namespace Barotrauma.Networking
SenderName = senderName; SenderName = senderName;
TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text; TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text;
if (GameMain.Server != null)
{
LastID++;
netStateID = LastID;
}
} }
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender) public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender)
@@ -140,7 +135,8 @@ namespace Barotrauma.Networking
if (c.lastSentChatMsgID < ID) if (c.lastSentChatMsgID < ID)
{ {
//this chat message is new to the server //this chat message is new to the server
GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name); GameMain.Server.SendChatMessage(txt, null, c);
//GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name);
c.lastSentChatMsgID = ID; c.lastSentChatMsgID = ID;
} }
} }
+1 -1
View File
@@ -41,7 +41,7 @@ namespace Barotrauma.Networking
public UInt32 lastRecvEntitySpawnID = 0; public UInt32 lastRecvEntitySpawnID = 0;
public List<string> ChatMessages = new List<string>(); public List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
public float ChatSpamSpeed; public float ChatSpamSpeed;
public float ChatSpamTimer; public float ChatSpamTimer;
public int ChatSpamCount; public int ChatSpamCount;
@@ -152,6 +152,18 @@ namespace Barotrauma
NetStateID = (UInt32)spawnHistory.Count; NetStateID = (UInt32)spawnHistory.Count;
} }
public void AddToSpawnedList(IEnumerable<Entity> entities)
{
if (GameMain.Server == null) return;
if (entities == null) return;
foreach (Entity entity in entities)
{
spawnHistory.Add(new SpawnOrRemove(entity, false));
NetStateID = (UInt32)spawnHistory.Count;
}
}
public void ServerWrite(Lidgren.Network.NetBuffer message, Client client, object[] extraData = null) public void ServerWrite(Lidgren.Network.NetBuffer message, Client client, object[] extraData = null)
{ {
if (GameMain.Server == null) return; if (GameMain.Server == null) return;
+5 -5
View File
@@ -847,18 +847,18 @@ namespace Barotrauma.Networking
client.SendMessage(outmsg, NetDeliveryMethod.Unreliable); client.SendMessage(outmsg, NetDeliveryMethod.Unreliable);
} }
public override void SendChatMessage(string message, ChatMessageType? type = null) public void SendChatMessage(string message)
{ {
if (client.ServerConnection == null) return; if (client.ServerConnection == null) return;
type = ChatMessageType.Default;
ChatMessage chatMessage = ChatMessage.Create( ChatMessage chatMessage = ChatMessage.Create(
gameStarted && myCharacter != null ? myCharacter.Name : name, gameStarted && myCharacter != null ? myCharacter.Name : name,
message, (ChatMessageType)type, gameStarted ? myCharacter : null); message,
ChatMessageType.Default,
gameStarted ? myCharacter : null);
lastQueueChatMsgID++; lastQueueChatMsgID++;
chatMessage.netStateID = lastQueueChatMsgID; chatMessage.NetStateID = lastQueueChatMsgID;
chatMsgQueue.Add(chatMessage); chatMsgQueue.Add(chatMessage);
} }
+177 -34
View File
@@ -542,7 +542,7 @@ namespace Barotrauma.Networking
// } // }
//} //}
foreach (Character c in Character.CharacterList) /*foreach (Character c in Character.CharacterList)
{ {
if (c.IsDead) continue; if (c.IsDead) continue;
@@ -554,7 +554,7 @@ namespace Barotrauma.Networking
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; //if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
} }
} }*/
sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; sparseUpdateTimer = DateTime.Now + sparseUpdateInterval;
} }
@@ -658,17 +658,11 @@ namespace Barotrauma.Networking
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
outmsg.Write(c.lastSentEntityEventID); outmsg.Write(c.lastSentEntityEventID);
foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children) c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID);
foreach (ChatMessage cMsg in c.chatMsgQueue)
{ {
if (gc is GUITextBlock && gc.UserData is ChatMessage) cMsg.ServerWrite(outmsg, c);
{ }
ChatMessage cMsg = (ChatMessage)gc.UserData;
if (cMsg.NetStateID > c.lastRecvChatMsgID)
{
cMsg.ServerWrite(outmsg, c);
}
}
}
if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID) if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID)
{ {
@@ -681,7 +675,7 @@ namespace Barotrauma.Networking
{ {
if (character is AICharacter) if (character is AICharacter)
{ {
//TODO: don't send if the ai character is far from the client //TODO: don't send if the ai character is far from the client
//(some sort of distance-based culling might be a good idea for player-controlled characters as well) //(some sort of distance-based culling might be a good idea for player-controlled characters as well)
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
character.ServerWrite(outmsg, c); character.ServerWrite(outmsg, c);
@@ -766,20 +760,12 @@ namespace Barotrauma.Networking
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children) c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID);
foreach (ChatMessage cMsg in c.chatMsgQueue)
{ {
if (gc is GUITextBlock) cMsg.ServerWrite(outmsg, c);
{ }
if (gc.UserData is ChatMessage)
{
ChatMessage cMsg = (ChatMessage)gc.UserData;
if (cMsg.NetStateID > c.lastRecvChatMsgID)
{
cMsg.ServerWrite(outmsg,c);
}
}
}
}
outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE); outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE);
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable); server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
} }
@@ -960,8 +946,7 @@ namespace Barotrauma.Networking
foreach (Character c in GameMain.GameSession.CrewManager.characters) foreach (Character c in GameMain.GameSession.CrewManager.characters)
{ {
Entity.Spawner.AddToSpawnedList(c); Entity.Spawner.AddToSpawnedList(c);
Entity.Spawner.AddToSpawnedList(c.SpawnItems);
c.SpawnItems.ForEach(item => Entity.Spawner.AddToSpawnedList(item));
} }
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients); SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients);
@@ -1215,16 +1200,174 @@ namespace Barotrauma.Networking
} }
} }
public override void SendChatMessage(string message, ChatMessageType? type = null) /// <summary>
/// Add the message to the chatbox and pass it to all clients who can receive it
/// </summary>
public void SendChatMessage(string message, ChatMessageType? type = null, Client senderClient = null)
{ {
type = ChatMessageType.Default; Character senderCharacter = null;
string senderName = "";
if (type==null)
{
string tempStr;
string command = ChatMessage.GetChatMessageCommand(message, out tempStr);
switch (command)
{
case "r":
case "radio":
type = ChatMessageType.Radio;
break;
case "d":
case "dead":
type = ChatMessageType.Dead;
break;
default:
type = ChatMessageType.Default;
break;
}
}
ChatMessage chatMessage = ChatMessage.Create( if (gameStarted)
gameStarted && myCharacter != null ? myCharacter.Name : name, {
message, (ChatMessageType)type, gameStarted ? myCharacter : null); //msg sent by the server
if (senderClient == null)
{
senderCharacter = myCharacter;
senderName = myCharacter == null ? name : myCharacter.Name;
}
else //msg sent by a client
{
senderCharacter = senderClient.Character;
senderName = senderCharacter == null ? senderClient.name : senderCharacter.Name;
//sender doesn't have an alive character -> only ChatMessageType.Dead allowed
if (senderCharacter == null || senderCharacter.IsDead)
{
type = ChatMessageType.Dead;
}
}
}
else
{
//msg sent by the server
if (senderClient == null)
{
senderName = name;
}
else //msg sent by a client
{
//game not started -> clients can only send normal chatmessages
type = ChatMessageType.Default;
senderName = senderClient.name;
}
}
AddChatMessage(chatMessage); //check if the client is allowed to send the message
WifiComponent senderRadio = null;
switch (type)
{
case ChatMessageType.Radio:
if (senderCharacter == null) return;
//return if senderCharacter doesn't have a working radio
var radio = senderCharacter.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (radio == null) return;
senderRadio = radio.GetComponent<WifiComponent>();
if (!senderRadio.CanTransmit()) return;
break;
case ChatMessageType.Dead:
//character still alive -> not allowed
if (senderClient != null && senderCharacter != null && !senderCharacter.IsDead)
{
return;
}
break;
}
//check which clients can receive the message and apply distance effects
foreach (Client client in ConnectedClients)
{
string modifiedMessage = message;
switch (type)
{
case ChatMessageType.Default:
case ChatMessageType.Radio:
if (senderCharacter != null &&
client.Character != null && !client.Character.IsDead)
{
modifiedMessage = ApplyChatMsgDistanceEffects(message, (ChatMessageType)type, senderCharacter, client.Character);
//too far to hear the msg -> don't send
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
}
break;
case ChatMessageType.Dead:
if (client.Character != null && !client.Character.IsDead) continue;
break;
}
var chatMsg = ChatMessage.Create(
senderName,
modifiedMessage,
(ChatMessageType)type,
senderCharacter);
chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ?
client.chatMsgQueue.Last().NetStateID + 1 :
client.lastRecvChatMsgID+1;
client.chatMsgQueue.Add(chatMsg);
}
string myReceivedMessage = message;
if (gameStarted && myCharacter != null)
{
myReceivedMessage = ApplyChatMsgDistanceEffects(message, (ChatMessageType)type, senderCharacter, myCharacter);
}
if (!string.IsNullOrWhiteSpace(myReceivedMessage))
{
AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName);
}
}
private string ApplyChatMsgDistanceEffects(string message, ChatMessageType type, Character sender, Character receiver)
{
if (sender == null) return "";
switch (type)
{
case ChatMessageType.Default:
if (!receiver.IsDead)
{
return ChatMessage.ApplyDistanceEffect(receiver, sender, message, ChatMessage.SpeakRange);
}
break;
case ChatMessageType.Radio:
if (!receiver.IsDead)
{
var receiverItem = receiver.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
//client doesn't have a radio -> don't send
if (receiverItem == null) return "";
var senderItem = sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (senderItem == null) return "";
var receiverRadio = receiverItem.GetComponent<WifiComponent>();
var senderRadio = senderItem.GetComponent<WifiComponent>();
if (!receiverRadio.CanReceive(senderRadio)) return "";
return ChatMessage.ApplyDistanceEffect(receiverItem, senderItem, message, senderRadio.Range);
}
break;
}
return message;
} }
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
+8 -24
View File
@@ -195,7 +195,14 @@ namespace Barotrauma.Networking
if (string.IsNullOrWhiteSpace(message)) return false; if (string.IsNullOrWhiteSpace(message)) return false;
SendChatMessage(message); if (this == GameMain.Server)
{
GameMain.Server.SendChatMessage(message, null, null);
}
else if (this == GameMain.Client)
{
GameMain.Client.SendChatMessage(message);
}
if (textBox == chatMsgBox) textBox.Deselect(); if (textBox == chatMsgBox) textBox.Deselect();
@@ -209,33 +216,12 @@ namespace Barotrauma.Networking
public void AddChatMessage(ChatMessage message) public void AddChatMessage(ChatMessage message)
{ {
if (message.Type == ChatMessageType.Radio &&
Character.Controlled != null &&
message.Sender != null && message.Sender != myCharacter)
{
var radio = message.Sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (radio == null) return;
message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Radio]);
var radioComponent = radio.GetComponent<WifiComponent>();
radioComponent.Transmit(message.TextWithSender);
return;
}
GameServer.Log(message.TextWithSender, message.Color); GameServer.Log(message.TextWithSender, message.Color);
string displayedText = message.Text; string displayedText = message.Text;
if (message.Sender != null) if (message.Sender != null)
{ {
if (message.Type == ChatMessageType.Default && Character.Controlled != null)
{
displayedText = message.ApplyDistanceEffect(Character.Controlled);
if (string.IsNullOrWhiteSpace(displayedText)) return;
}
message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Default]); message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Default]);
} }
@@ -279,8 +265,6 @@ namespace Barotrauma.Networking
GUI.PlayUISound(soundType); GUI.PlayUISound(soundType);
} }
public virtual void SendChatMessage(string message, ChatMessageType? type = null) { }
public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { } public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { }
public virtual void AddToGUIUpdateList() public virtual void AddToGUIUpdateList()
@@ -412,6 +412,8 @@ namespace Barotrauma.Networking
bool myCharacter = i >= clients.Count; bool myCharacter = i >= clients.Count;
var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, !myCharacter, false); var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, !myCharacter, false);
Entity.Spawner.AddToSpawnedList(character);
character.TeamID = 1; character.TeamID = 1;
if (myCharacter) if (myCharacter)
@@ -424,9 +426,7 @@ namespace Barotrauma.Networking
{ {
clients[i].Character = character; clients[i].Character = character;
} }
spawnedCharacters.Add(character);
Vector2 pos = cargoSp == null ? character.Position : cargoSp.Position; Vector2 pos = cargoSp == null ? character.Position : cargoSp.Position;
if (divingSuitPrefab != null && oxyPrefab != null) if (divingSuitPrefab != null && oxyPrefab != null)
@@ -450,10 +450,11 @@ namespace Barotrauma.Networking
spawnedItems.Add(scooter); spawnedItems.Add(scooter);
spawnedItems.Add(battery); spawnedItems.Add(battery);
} }
spawnedItems.ForEach(s => Item.Spawner.AddToSpawnedList(s));
character.GiveJobItems(mainSubSpawnPoints[i]); character.GiveJobItems(mainSubSpawnPoints[i]);
Entity.Spawner.AddToSpawnedList(character.SpawnItems);
Entity.Spawner.AddToSpawnedList(spawnedItems);
GameMain.GameSession.CrewManager.characters.Add(character); GameMain.GameSession.CrewManager.characters.Add(character);
} }