示例#1
0
        /// <summary>
        /// Applies the elemental effects of a players skill to the target.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="player">The player.</param>
        /// <param name="skillEntry">The skill entry.</param>
        /// <returns>The success of the appliance.</returns>
        public static bool TryApplyElementalEffects(this IAttackable target, Player player, SkillEntry skillEntry)
        {
            skillEntry.ThrowNotInitializedProperty(skillEntry.Skill is null, nameof(skillEntry.Skill));
            var modifier = skillEntry.Skill.ElementalModifierTarget;

            if (modifier is null)
            {
                return(false);
            }

            var resistance = target.Attributes[modifier];

            if (resistance >= 1.0f || !Rand.NextRandomBool(1.0f - resistance))
            {
                return(false);
            }

            var applied = false;

            if (skillEntry.Skill.MagicEffectDef is { } effectDefinition &&
                !target.MagicEffectList.ActiveEffects.ContainsKey(effectDefinition.Number))
            {
                // power-up is the wrong term here... it's more like a power-down ;-)
                target.ApplyMagicEffect(player, skillEntry);
                applied = true;
            }

            if (modifier == Stats.LightningResistance)
            {
                target.MoveRandomly();
                applied = true;
            }

            return(applied);
        }
示例#2
0
        /// <summary>
        /// Applies the elemental effects of a players skill to the target.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="player">The player.</param>
        /// <param name="skillEntry">The skill entry.</param>
        public static void ApplyElementalEffects(this IAttackable target, Player player, SkillEntry skillEntry)
        {
            var modifier = skillEntry.Skill.ElementalModifierTarget;

            if (modifier == null)
            {
                return;
            }

            var resistance = target.Attributes[modifier];

            if (resistance >= 1.0f)
            {
                return;
            }

            if (Rand.NextRandomBool(1.0f - resistance))
            {
                // power-up is the wrong term here... it's more like a power-down ;-)
                if (skillEntry.Skill.MagicEffectDef != null)
                {
                    target.ApplyMagicEffect(player, skillEntry);
                }

                if (modifier == Stats.LightningResistance)
                {
                    target.MoveRandomly();
                }
            }
        }
示例#3
0
        /// <summary>
        /// Gets the hit information, calculates which part of the damage damages the shield and which the health.
        /// </summary>
        /// <param name="defender">The defender.</param>
        /// <param name="damage">The damage.</param>
        /// <param name="attributes">The attributes.</param>
        /// <param name="attacker">The attacker.</param>
        /// <returns>The calculated hit info.</returns>
        public static HitInfo GetHitInfo(this IAttackable defender, uint damage, DamageAttributes attributes, IAttackable attacker)
        {
            var shieldBypass = Rand.NextRandomBool(attacker.Attributes[Stats.ShieldBypassChance]);

            if (shieldBypass || defender.Attributes[Stats.CurrentShield] < 1)
            {
                return(new HitInfo(damage, 0, attributes));
            }

            var shieldRatio = 0.90;

            shieldRatio -= attacker.Attributes[Stats.ShieldDecreaseRateIncrease];
            shieldRatio += defender.Attributes[Stats.ShieldRateIncrease];
            shieldRatio  = Math.Max(0, shieldRatio);
            shieldRatio  = Math.Min(1, shieldRatio);
            return(new HitInfo((uint)(damage * (1 - shieldRatio)), (uint)(damage * shieldRatio), attributes));
        }
示例#4
0
        /// <summary>
        /// Calculates the damage, using a skill.
        /// </summary>
        /// <param name="attacker">The object which is attacking.</param>
        /// <param name="defender">The object which is defending.</param>
        /// <param name="skill">The skill which is used.</param>
        /// <returns>The hit information.</returns>
        public static HitInfo CalculateDamage(this IAttackable attacker, IAttackable defender, SkillEntry skill)
        {
            if (!attacker.IsAttackSuccessfulTo(defender))
            {
                return(new HitInfo(0, 0, DamageAttributes.Undefined));
            }

            DamageAttributes attributes        = DamageAttributes.Undefined;
            bool             isCriticalHit     = Rand.NextRandomBool(attacker.Attributes[Stats.CriticalDamageChance]);
            bool             isExcellentHit    = Rand.NextRandomBool(attacker.Attributes[Stats.ExcellentDamageChance]);
            bool             isIgnoringDefense = Rand.NextRandomBool(attacker.Attributes[Stats.DefenseIgnoreChance]);

            attacker.GetBaseDmg(skill, out int baseMinDamage, out int baseMaxDamage);
            int dmg;

            if (isExcellentHit)
            {
                dmg         = (int)(baseMaxDamage * 1.2);
                attributes |= DamageAttributes.Excellent;
            }
            else if (isCriticalHit)
            {
                dmg         = baseMaxDamage;
                attributes |= DamageAttributes.Critical;
            }
            else if (baseMaxDamage <= baseMinDamage)
            {
                dmg = baseMinDamage;
            }
            else
            {
                dmg = Rand.NextInt(baseMinDamage, baseMaxDamage);
            }

            if (!isIgnoringDefense)
            {
                var defenseAttribute = GetDefenseAttribute(attacker);
                dmg        -= (int)defender.Attributes[defenseAttribute];
                attributes |= DamageAttributes.IgnoreDefense;
            }

            dmg = Math.Max(dmg, 0);

            dmg = (int)(dmg * defender.Attributes[Stats.DamageReceiveDecrement]);
            dmg = (int)(dmg * attacker.Attributes[Stats.AttackDamageIncrease]);

            if (skill != null)
            {
                dmg = (int)(dmg * attacker.Attributes[Stats.SkillMultiplier]);
            }

            bool isDoubleDamage = Rand.NextRandomBool(attacker.Attributes[Stats.DoubleDamageChance]);

            if (isDoubleDamage)
            {
                dmg        *= 2;
                attributes |= DamageAttributes.Double;
            }

            // now we have the final damage calculated. We have to calculate which part of the damage damages the shield and which the health.
            HitInfo hi;
            var     shieldBypass = Rand.NextRandomBool(attacker.Attributes[Stats.ShieldBypassChance]);

            if (shieldBypass || defender.Attributes[Stats.CurrentShield] < 1)
            {
                hi = new HitInfo((uint)dmg, 0, 0);
            }
            else
            {
                var shieldRatio = 0.90;
                shieldRatio -= attacker.Attributes[Stats.ShieldDecreaseRateIncrease];
                shieldRatio += defender.Attributes[Stats.ShieldRateIncrease];
                shieldRatio  = Math.Max(0, shieldRatio);
                shieldRatio  = Math.Min(1, shieldRatio);
                hi           = new HitInfo((uint)(dmg * (1 - shieldRatio)), (uint)(dmg * shieldRatio), attributes);
            }

            return(hi);
        }
示例#5
0
        private static bool IsAttackSuccessfulTo(this IAttackable attacker, IAttackable defender)
        {
            var hitChance = attacker.GetHitChanceTo(defender);

            return(Rand.NextRandomBool(hitChance));
        }
示例#6
0
        /// <summary>
        /// Calculates the damage, using a skill.
        /// </summary>
        /// <param name="attacker">The object which is attacking.</param>
        /// <param name="defender">The object which is defending.</param>
        /// <param name="skill">The skill which is used.</param>
        /// <returns>The hit information.</returns>
        public static HitInfo CalculateDamage(this IAttackable attacker, IAttackable defender, SkillEntry skill)
        {
            if (!attacker.IsAttackSuccessfulTo(defender))
            {
                return(new HitInfo(0, 0, DamageAttributes.Undefined));
            }

            DamageAttributes attributes        = DamageAttributes.Undefined;
            bool             isCriticalHit     = Rand.NextRandomBool(attacker.Attributes[Stats.CriticalDamageChance]);
            bool             isExcellentHit    = Rand.NextRandomBool(attacker.Attributes[Stats.ExcellentDamageChance]);
            bool             isIgnoringDefense = Rand.NextRandomBool(attacker.Attributes[Stats.DefenseIgnoreChance]);

            attacker.GetBaseDmg(skill, out int baseMinDamage, out int baseMaxDamage);
            int dmg;

            if (isExcellentHit)
            {
                dmg         = (int)(baseMaxDamage * 1.2);
                attributes |= DamageAttributes.Excellent;
            }
            else if (isCriticalHit)
            {
                dmg         = baseMaxDamage;
                attributes |= DamageAttributes.Critical;
            }
            else if (baseMaxDamage <= baseMinDamage)
            {
                dmg = baseMinDamage;
            }
            else
            {
                dmg = Rand.NextInt(baseMinDamage, baseMaxDamage);
            }

            if (!isIgnoringDefense)
            {
                var defenseAttribute = defender.GetDefenseAttribute(attacker);
                var defense          = (int)defender.Attributes[defenseAttribute];
                if (defender.Attributes[Stats.IsShieldEquipped] > 0)
                {
                    defense += (int)(defense * defender.Attributes[Stats.DefenseIncreaseWithEquippedShield]);
                }

                dmg -= defense;
            }
            else
            {
                attributes |= DamageAttributes.IgnoreDefense;
            }

            dmg = Math.Max(dmg, 0);

            dmg = (int)(dmg * defender.Attributes[Stats.DamageReceiveDecrement]);
            dmg = (int)(dmg * attacker.Attributes[Stats.AttackDamageIncrease]);

            if (skill != null)
            {
                dmg = dmg + (int)attacker.Attributes[Stats.SkillDamageBonus];
                dmg = (int)(dmg * attacker.Attributes[Stats.SkillMultiplier]);
            }

            if (attacker.Attributes[Stats.IsTwoHandedWeaponEquipped] > 0)
            {
                dmg = (int)(dmg * attacker.Attributes[Stats.TwoHandedWeaponDamageIncrease]);
            }

            if (attacker is Player && defender is Player)
            {
                dmg += (int)attacker.Attributes[Stats.FinalDamageIncreasePvp];
            }

            bool isDoubleDamage = Rand.NextRandomBool(attacker.Attributes[Stats.DoubleDamageChance]);

            if (isDoubleDamage)
            {
                dmg        *= 2;
                attributes |= DamageAttributes.Double;
            }

            var minimumDamage = attacker.Attributes[Stats.Level] / 10;

            return(defender.GetHitInfo(Math.Max((uint)dmg, (uint)minimumDamage), attributes, attacker));
        }
示例#7
0
文件: Rand.cs 项目: najoast/OpenMU
 bool IRandomizer.NextRandomBool(double chance)
 {
     return(Rand.NextRandomBool(chance));
 }
示例#8
0
文件: Rand.cs 项目: najoast/OpenMU
 bool IRandomizer.NextRandomBool(int chance, int basis)
 {
     return(Rand.NextRandomBool(chance, basis));
 }
示例#9
0
文件: Rand.cs 项目: najoast/OpenMU
 bool IRandomizer.NextRandomBool(int percent)
 {
     return(Rand.NextRandomBool(percent));
 }
示例#10
0
文件: Rand.cs 项目: najoast/OpenMU
 bool IRandomizer.NextRandomBool()
 {
     return(Rand.NextRandomBool());
 }