diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/Character.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/Character.cs index 23cd60f7f4..30a87c5874 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/Character.cs @@ -550,7 +550,7 @@ partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResul } } - partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log) + partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log, bool triggerDeathEffects) { HintManager.OnCharacterKilled(this); @@ -564,7 +564,10 @@ partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfD RespawnManager.ShowDeathPromptIfNeeded(); - GameMain.NetworkMember.AddChatMessage(chatMessage.Value, ChatMessageType.Dead); + if (triggerDeathEffects) + { + GameMain.NetworkMember.AddChatMessage(chatMessage.Value, ChatMessageType.Dead); + } GameMain.LightManager.LosEnabled = false; controlled = null; if (Screen.Selected?.Cam is Camera cam) @@ -577,7 +580,10 @@ partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfD } } - PlaySound(CharacterSound.SoundType.Die); + if (triggerDeathEffects) + { + PlaySound(CharacterSound.SoundType.Die); + } } partial void DisposeProjSpecific() diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs index 5ef1cebff5..f78a1026e4 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs @@ -800,6 +800,7 @@ public static Character ReadSpawnData(IReadMessage inc) private void ReadStatus(IReadMessage msg) { + TriggerDeathEffects = msg.ReadBoolean(); bool isDead = msg.ReadBoolean(); if (isDead) { diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs index 86467b4210..5d2cc19ae8 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs @@ -13,7 +13,7 @@ partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResul GameMain.Server.KarmaManager.OnCharacterHealthChanged(this, attacker, attackResult.Damage, stun, attackResult.Afflictions); } - partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log) + partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log, bool triggerDeathEffects) { if (log) { diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs index 6d8c1801ee..ffdef15cb7 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs @@ -649,6 +649,7 @@ public virtual void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent /// Normally full affliction data is not written for dead characters, this can be used to force them to be written private void WriteStatus(IWriteMessage msg, bool forceAfflictionData = false) { + msg.WriteBoolean(TriggerDeathEffects); msg.WriteBoolean(IsDead); if (IsDead) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index 32dad407a4..121d97ed5f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -1157,6 +1157,9 @@ public bool IsDead } } + // If set to false, the character won't trigger death status effects, death sounds or have death notifications show up in their chat when they die. + public bool TriggerDeathEffects { get; set; } = true; + public bool EnableDespawn { get; set; } = true; public CauseOfDeath CauseOfDeath @@ -5027,7 +5030,10 @@ public void Kill(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAfflictio //it's important that we set isDead before executing the status effects, //otherwise a statuseffect might kill the character "again" and trigger a loop that crashes the game isDead = true; - ApplyStatusEffects(ActionType.OnDeath, 1.0f); + if (TriggerDeathEffects) + { + ApplyStatusEffects(ActionType.OnDeath, 1.0f); + } #if CLIENT // Keep permadeath status in sync (to show it correctly in the UI, the server takes care of the actual logic) @@ -5095,7 +5101,7 @@ static string GetCharacterType(Character character) AchievementManager.OnCharacterKilled(this, CauseOfDeath); } - KillProjSpecific(causeOfDeath, causeOfDeathAffliction, log); + KillProjSpecific(causeOfDeath, causeOfDeathAffliction, log, TriggerDeathEffects); if (info != null) { @@ -5132,7 +5138,7 @@ static string GetCharacterType(Character character) } GameMain.GameSession?.KillCharacter(this); } - partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log); + partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log, bool triggerDeathEffects); public void Revive(bool removeAfflictions = true, bool createNetworkEvent = false) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs index 84a77ba6a3..5ec3f05862 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs @@ -2173,7 +2173,7 @@ entity is Item item && } #endif } - if (characterSpawnInfo.RemovePreviousCharacter) { Entity.Spawner?.AddEntityToRemoveQueue(character); } + if (characterSpawnInfo.RemovePreviousCharacter) { character.TriggerDeathEffects = false; character.Kill(CauseOfDeathType.Unknown, null); Entity.Spawner?.AddEntityToRemoveQueue(character); } } } if (characterSpawnInfo.InheritEventTags) @@ -2305,6 +2305,8 @@ void OnItemContainerSpawned(Item item) } } } + character.TriggerDeathEffects = false; + character.Kill(CauseOfDeathType.Unknown, null); Entity.Spawner?.AddEntityToRemoveQueue(character); }