コード例 #1
0
        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);
            }