diff --git a/Subsurface/Source/Characters/CharacterHUD.cs b/Subsurface/Source/Characters/CharacterHUD.cs index 8d1cd8572..4ee4f6230 100644 --- a/Subsurface/Source/Characters/CharacterHUD.cs +++ b/Subsurface/Source/Characters/CharacterHUD.cs @@ -264,8 +264,15 @@ namespace Barotrauma GUIComponent.ForceMouseOn(null); if (Character.Controlled != null) { - Character.Controlled.Kill(Character.Controlled.CauseOfDeath); - Character.Controlled = null; + if (GameMain.Client != null) + { + GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Status }); + } + else + { + Character.Controlled.Kill(Character.Controlled.CauseOfDeath); + Character.Controlled = null; + } } return true; }; diff --git a/Subsurface/Source/Characters/CharacterNetworking.cs b/Subsurface/Source/Characters/CharacterNetworking.cs index b5d8aad79..ab974530f 100644 --- a/Subsurface/Source/Characters/CharacterNetworking.cs +++ b/Subsurface/Source/Characters/CharacterNetworking.cs @@ -235,15 +235,19 @@ namespace Barotrauma if (extraData != null) { - if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.InventoryState) + switch ((NetEntityEvent.Type)extraData[0]) { - msg.Write(true); - inventory.ClientWrite(msg, extraData); - } - else if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.Repair) - { - msg.Write(false); - msg.Write(AnimController.Anim == AnimController.Animation.CPR); + case NetEntityEvent.Type.InventoryState: + msg.WriteRangedInteger(0, 2, 0); + inventory.ClientWrite(msg, extraData); + break; + case NetEntityEvent.Type.Repair: + msg.WriteRangedInteger(0, 2, 1); + msg.Write(AnimController.Anim == AnimController.Animation.CPR); + break; + case NetEntityEvent.Type.Status: + msg.WriteRangedInteger(0, 2, 2); + break; } msg.WritePadBits(); } @@ -338,24 +342,41 @@ namespace Barotrauma break; case ClientNetObject.ENTITY_STATE: - bool isInventoryUpdate = msg.ReadBoolean(); - if (isInventoryUpdate) + int eventType = msg.ReadRangedInteger(0,2); + switch (eventType) { - inventory.ServerRead(type, msg, c); - } - else - { - if (c.Character != this) - { + case 0: + inventory.ServerRead(type, msg, c); + break; + case 1: + if (c.Character != this) + { #if DEBUG - DebugConsole.Log("Received a character update message from a client who's not controlling the character"); + DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif - return; - } + return; + } + + bool doingCPR = msg.ReadBoolean(); + AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None; + break; + case 2: + if (c.Character != this) + { +#if DEBUG + DebugConsole.Log("Received a character update message from a client who's not controlling the character"); +#endif + return; + } + + if (IsUnconscious) + { + Kill(lastAttackCauseOfDeath); + } + break; - bool doingCPR = msg.ReadBoolean(); - AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None; } + msg.ReadPadBits(); break; } diff --git a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index 3b45edd46..9b6774810 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -107,13 +107,21 @@ namespace Barotrauma.Networking { foreach (BufferedEvent bufferedEvent in bufferedEvents) { - if (bufferedEvent.Character == null) + if (bufferedEvent.Character == null || bufferedEvent.Character.IsDead) { bufferedEvent.IsProcessed = true; continue; } - if (NetIdUtils.IdMoreRecent(bufferedEvent.CharacterStateID, bufferedEvent.Character.LastProcessedID)) continue; + //delay reading the events until the inputs for the corresponding frame have been processed + + //UNLESS the character is unconscious, in which case we'll read the messages immediately (because further inputs will be ignored) + //atm the "give in" command is the only thing unconscious characters can do, other types of events are ignored + if (!bufferedEvent.Character.IsUnconscious && + NetIdUtils.IdMoreRecent(bufferedEvent.CharacterStateID, bufferedEvent.Character.LastProcessedID)) + { + continue; + } try {