public static bool SharedOnDamageToCharacter( ICharacter targetCharacter, WeaponFinalCache weaponCache, double damageMultiplier, out double damageApplied) { var targetPublicState = targetCharacter.GetPublicState <ICharacterPublicState>(); var targetCurrentStats = targetPublicState.CurrentStats; if (targetCurrentStats.HealthCurrent <= 0) { // target character is dead, cannot apply damage to it damageApplied = 0; return(false); } { if (!targetCharacter.IsNpc && weaponCache.Character is ICharacter damagingCharacter && NewbieProtectionSystem.SharedIsNewbie(damagingCharacter)) { // no damage from newbie damageApplied = 0; if (Api.IsClient) { // display message to newbie NewbieProtectionSystem.ClientShowNewbieCannotDamageOtherPlayersOrLootBags(isLootBag: false); } // but the hit is registered so it's not possible to shoot through a character return(true); } } if (Api.IsClient) { // we don't simulate the damage on the client side damageApplied = 0; if (weaponCache.Character is ICharacter damagingCharacter) { // potentially a PvP case PveSystem.ClientShowDuelModeRequiredNotificationIfNecessary( damagingCharacter, targetCharacter); } return(true); } var attackerCharacter = weaponCache.Character; if (!(attackerCharacter is null) && attackerCharacter.IsNpc && targetCharacter.IsNpc) { // no creature-to-creature damage damageApplied = 0; return(false); } // calculate and apply damage on server var targetFinalStatsCache = targetCharacter.GetPrivateState <BaseCharacterPrivateState>() .FinalStatsCache; var totalDamage = ServerCalculateTotalDamage( weaponCache, targetCharacter, targetFinalStatsCache, damageMultiplier, clampDefenseTo1: true); if (totalDamage <= 0) { // damage suppressed damageApplied = 0; return(true); } // Clamp the max receivable damage to x5 from the max health. // This will help in case when the too much damage is dealt (mega-bomb!) // to ensure the equipment will not receive excessive damaged. totalDamage = Math.Min(totalDamage, 5 * targetCurrentStats.HealthMax); // apply damage if (!(attackerCharacter is null)) { targetCurrentStats.ServerReduceHealth(totalDamage, damageSource: attackerCharacter); }