private byte GetDamageColor(DamageAttributes attributes) { var colorResult = DamageColor.NormalRed; if (attributes.HasFlag(DamageAttributes.IgnoreDefense)) { colorResult = DamageColor.IgnoreDefenseCyan; } else if (attributes.HasFlag(DamageAttributes.Excellent)) { colorResult = DamageColor.ExcellentLightGreen; } else if (attributes.HasFlag(DamageAttributes.Critical)) { colorResult = DamageColor.CriticalBlue; } byte result = (byte)colorResult; if (attributes.HasFlag(DamageAttributes.Double)) { result |= (byte)SpecialDamage.Double; } if (attributes.HasFlag(DamageAttributes.Triple)) { result |= (byte)SpecialDamage.Triple; } return(result); }
private ObjectHit.DamageKind GetDamageKind(DamageAttributes attributes) { if (attributes.HasFlag(DamageAttributes.IgnoreDefense)) { return(ObjectHit.DamageKind.IgnoreDefenseCyan); } if (attributes.HasFlag(DamageAttributes.Excellent)) { return(ObjectHit.DamageKind.ExcellentLightGreen); } if (attributes.HasFlag(DamageAttributes.Critical)) { return(ObjectHit.DamageKind.CriticalBlue); } if (attributes.HasFlag(DamageAttributes.Reflected)) { return(ObjectHit.DamageKind.ReflectedDarkPink); } if (attributes.HasFlag(DamageAttributes.Poison)) { return(ObjectHit.DamageKind.PoisonDarkGreen); } return(ObjectHit.DamageKind.NormalRed); }
/// <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)); }
/// <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); }
/// <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)); }
/// <summary> /// Initializes a new instance of the <see cref="HitInfo"/> struct. /// </summary> /// <param name="healthDamage">The damage which reduces the health points.</param> /// <param name="shieldDamage"> The damage which reduces the shield points.</param> /// <param name="attributes">The attributes.</param> public HitInfo(uint healthDamage, uint shieldDamage, DamageAttributes attributes) { this.HealthDamage = healthDamage; this.ShieldDamage = shieldDamage; this.Attributes = attributes; }
/// <summary> /// Initializes a new instance of the <see cref="HitInfo"/> struct. /// </summary> /// <param name="damageHP">The damage which reduces the health points.</param> /// <param name="damageSD"> The damage which reduces the shield points.</param> /// <param name="attributes">The attributes.</param> public HitInfo(uint damageHP, uint damageSD, DamageAttributes attributes) { this.DamageHP = damageHP; this.DamageSD = damageSD; this.Attributes = attributes; }