private static bool IsAttackSuccessfulTo(this IAttackable attacker, IAttackable defender) { var hitChance = attacker.GetHitChanceTo(defender); return(Rand.NextRandomBool(hitChance)); }
/// <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); dmg -= (int)defender.Attributes[defenseAttribute]; } 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 = (int)(dmg * attacker.Attributes[Stats.SkillMultiplier]); } 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)); }
uint IRandomizer.NextUInt(uint min, uint max) { return(Rand.NextUInt(min, max)); }
double IRandomizer.NextDouble() { return(Rand.NextDouble()); }
int IRandomizer.NextInt(int min, int max) { return(Rand.NextInt(min, max)); }
bool IRandomizer.NextRandomBool(double chance) { return(Rand.NextRandomBool(chance)); }
bool IRandomizer.NextRandomBool(int chance, int basis) { return(Rand.NextRandomBool(chance, basis)); }
bool IRandomizer.NextRandomBool(int percent) { return(Rand.NextRandomBool(percent)); }
bool IRandomizer.NextRandomBool() { return(Rand.NextRandomBool()); }