public static void OnCharacterDeath(ICharacter deadCharacter) { var publicState = deadCharacter.GetPublicState <ICharacterPublicState>(); if (!publicState.IsDead) { publicState.CurrentStats.ServerSetHealthCurrent(0); return; } // recreate physics (as dead character doesn't have any physics) deadCharacter.ProtoCharacter.SharedCreatePhysics(deadCharacter); Action <ICharacter> onCharacterDeath; if (deadCharacter.ProtoCharacter is IProtoCharacterMob protoCharacterMob) { onCharacterDeath = CharacterDeath; if (onCharacterDeath is not null) { Api.SafeInvoke(() => onCharacterDeath(deadCharacter)); } protoCharacterMob.ServerOnDeath(deadCharacter); return; } // player character death // remember the death position (useful for the respawn) var privateState = PlayerCharacter.GetPrivateState(deadCharacter); privateState.LastDeathPosition = deadCharacter.TilePosition; privateState.LastDeathTime = Api.Server.Game.FrameTime; ServerTimersSystem.AddAction(delaySeconds: PlayerTeleportToGraveyardDelaySeconds, () => TeleportDeadPlayerCharacterToGraveyard(deadCharacter)); var isPvPdeath = CharacterDamageTrackingSystem.ServerGetPvPdamagePercent(deadCharacter) >= 0.5; // register death (required even if the player is not a newbie) NewbieProtectionSystem.ServerRegisterDeath(deadCharacter, isPvPdeath, out var shouldSufferDeathConsequences); if (shouldSufferDeathConsequences) { DropPlayerLoot(deadCharacter); } else { Api.Logger.Important("Player character is dead - newbie PvP case, no loot drop or other consequences", deadCharacter); } onCharacterDeath = CharacterDeath; if (onCharacterDeath is not null) { Api.SafeInvoke(() => onCharacterDeath(deadCharacter)); } }