/// <summary> /// Returns the percent of damage absorbed by layered armor + clothing /// </summary> /// <param name="armors">The list of armor/clothing covering the targeted body part</param> public float GetArmorMod(List <WorldObject> armors, WorldObject damageSource, DamageType damageType, CreatureSkill skill = null) { var effectiveAL = 0.0f; foreach (var armor in armors) { effectiveAL += GetArmorMod(armor, damageSource, damageType); } // life spells // additive: armor/imperil var bodyArmorMod = damageSource != null && damageSource.IgnoreMagicResist ? 0 : AttackTarget.EnchantmentManager.GetBodyArmorMod(); if (bodyArmorMod > 0 && damageSource != null && skill != null && damageSource.HasImbuedEffect(ImbuedEffectType.ArmorRending)) { bodyArmorMod = (int)Math.Round(bodyArmorMod * GetArmorRendingMod(skill)); } //Console.WriteLine("=="); //Console.WriteLine("Armor Self: " + bodyArmorMod); effectiveAL += bodyArmorMod; var armorMod = SkillFormula.CalcArmorMod(effectiveAL); //Console.WriteLine("Total AL: " + effectiveAL); //Console.WriteLine("Armor mod: " + armorMod); return(armorMod); }
public static readonly float DefaultMaxVelocity = 20.0f; // ? public float GetMaxMissileRange() { var weapon = GetEquippedWeapon(); var maxVelocity = weapon != null?weapon.GetProperty(PropertyFloat.MaximumVelocity) ?? DefaultMaxVelocity : DefaultMaxVelocity; //var missileRange = (float)Math.Pow(maxVelocity, 2.0f) * 0.1020408163265306f; var missileRange = (float)Math.Pow(maxVelocity, 2.0f) * 0.0682547266398198f; var strengthMod = SkillFormula.GetAttributeMod(PropertyAttribute.Strength, (int)Strength.Current); var maxRange = Math.Min(missileRange * strengthMod, MissileRangeCap); // any kind of other caps for monsters specifically? // throwing lugian rocks @ 85 yards seems a bit far... //Console.WriteLine($"{Name}.GetMaxMissileRange(): maxVelocity={maxVelocity}, strengthMod={strengthMod}, maxRange={maxRange}"); // for client display /*var maxRangeYards = maxRange * MetersToYards; * if (maxRangeYards >= 10.0f) * maxRangeYards -= maxRangeYards % 5.0f; * else * maxRangeYards = (float)Math.Ceiling(maxRangeYards);*/ return(maxRange); }
/// <summary> /// Returns the percent of damage absorbed by layered armor + clothing /// </summary> /// <param name="armors">The list of armor/clothing covering the targeted body part</param> public float GetArmorMod(DamageType damageType, List <WorldObject> armors, WorldObject damageSource, float armorRendingMod = 1.0f) { var effectiveAL = 0.0f; foreach (var armor in armors) { effectiveAL += GetArmorMod(armor, damageSource, damageType); } // life spells // additive: armor/imperil var bodyArmorMod = damageSource != null && damageSource.IgnoreMagicResist ? 0.0f : AttackTarget.EnchantmentManager.GetBodyArmorMod(); // handle armor rending mod here? //if (bodyArmorMod > 0) //bodyArmorMod *= armorRendingMod; //Console.WriteLine("=="); //Console.WriteLine("Armor Self: " + bodyArmorMod); effectiveAL += bodyArmorMod; // Armor Rending reduces physical armor too? if (effectiveAL > 0) { effectiveAL *= armorRendingMod; } var armorMod = SkillFormula.CalcArmorMod(effectiveAL); //Console.WriteLine("Total AL: " + effectiveAL); //Console.WriteLine("Armor mod: " + armorMod); return(armorMod); }
/// <summary> /// Returns the attribute damage bonus for a physical attack /// </summary> /// <param name="attackType">Uses strength for melee, coordination for missile</param> public float GetAttributeMod(WorldObject weapon) { var isBow = weapon != null && weapon.IsBow; //var attribute = isBow || GetCurrentWeaponSkill() == Skill.FinesseWeapons ? Coordination : Strength; var attribute = isBow || weapon?.WeaponSkill == Skill.FinesseWeapons ? Coordination : Strength; return(SkillFormula.GetAttributeMod((int)attribute.Current, isBow)); }
public float CalculateDamage(WorldObject target, WorldObject damageSource, ref bool criticalHit) { var creature = target as Creature; // evasion chance var evadeChance = GetEvadeChance(target); if (Physics.Common.Random.RollDice(0.0f, 1.0f) < evadeChance) { return(0.0f); } // get weapon base damage var baseDamageRange = GetBaseDamage(); var baseDamage = Physics.Common.Random.RollDice(baseDamageRange.Min, baseDamageRange.Max); // get damage mods var powerAccuracyMod = GetPowerAccuracyMod(); var attributeMod = GetAttributeMod(); var damage = baseDamage * attributeMod * powerAccuracyMod; // critical hit var critical = 0.1f; if (Physics.Common.Random.RollDice(0.0f, 1.0f) < critical) { damage = baseDamageRange.Max * attributeMod * powerAccuracyMod * 2.0f; criticalHit = true; } // get random body part @ attack height var bodyPart = BodyParts.GetBodyPart(AttackHeight); // get target armor var armor = GetArmor(target, bodyPart); // get target resistance DamageType damageType; if (damageSource?.ItemType == ItemType.MissileWeapon) { damageType = (DamageType)damageSource.GetProperty(PropertyInt.DamageType); } else { damageType = GetDamageType(); } var resistance = GetResistance(target, bodyPart, damageType); // scale damage for armor and shield var armorMod = SkillFormula.CalcArmorMod(resistance); var shieldMod = creature.GetShieldMod(this, damageType); return(damage * armorMod * shieldMod); }
/// <summary> /// Returns the attribute damage bonus for a physical attack /// </summary> /// <param name="attackType">Uses strength for melee, coordination for missile</param> public float GetAttributeMod(WorldObject weapon) { if (weapon != null && weapon.IsBow) { return(SkillFormula.GetAttributeMod(PropertyAttribute.Coordination, (int)Coordination.Current)); } else { return(SkillFormula.GetAttributeMod(PropertyAttribute.Strength, (int)Strength.Current)); } }
/// <summary> /// Returns the attribute damage bonus for a physical attack /// </summary> /// <param name="attackType">Uses strength for melee, coordination for missile</param> public float GetAttributeMod(AttackType attackType) { if (attackType == AttackType.Melee) { return(SkillFormula.GetAttributeMod(PropertyAttribute.Strength, (int)Strength.Current)); } else if (attackType == AttackType.Missile) { return(SkillFormula.GetAttributeMod(PropertyAttribute.Coordination, (int)Coordination.Current)); } else { return(1.0f); } }
public float CalculateDamage(WorldObject target, ref bool criticalHit) { // evasion chance var evadeChance = GetEvadeChance(target); if (Physics.Common.Random.RollDice(0.0f, 1.0f) < evadeChance) { return(0.0f); } // get weapon base damage var baseDamageRange = GetBaseDamage(); var baseDamage = Physics.Common.Random.RollDice(baseDamageRange.Min, baseDamageRange.Max); // get damage mods var powerAccuracyMod = GetPowerAccuracyMod(); var attributeMod = GetAttributeMod(); var damage = baseDamage * attributeMod * powerAccuracyMod; // critical hit var critical = 0.1f; if (Physics.Common.Random.RollDice(0.0f, 1.0f) < critical) { damage = baseDamageRange.Max * attributeMod * powerAccuracyMod * 2.0f; criticalHit = true; } // get random body part @ attack height var bodyPart = BodyParts.GetBodyPart(AttackHeight); // get target armor var armor = GetArmor(target, bodyPart); // get target resistance var damageType = GetDamageType(); var resistance = GetResistance(target, bodyPart, damageType); // scale damage for armor damage *= SkillFormula.CalcArmorMod(resistance); return(damage); }
/// <summary> /// Returns the percent of damage absorbed by layered armor + clothing /// </summary> /// <param name="armors">The list of armor/clothing covering the targeted body part</param> public float GetArmorMod(List <WorldObject> armors, WorldObject damageSource, DamageType damageType) { var effectiveAL = 0.0f; foreach (var armor in armors) { effectiveAL += GetArmorMod(armor, damageSource, damageType); } // life spells // additive: armor/imperil var bodyArmorMod = damageSource != null && damageSource.IgnoreMagicResist ? 0 : AttackTarget.EnchantmentManager.GetBodyArmorMod(); //Console.WriteLine("=="); //Console.WriteLine("Armor Self: " + bodyArmorMod); effectiveAL += bodyArmorMod; var armorMod = SkillFormula.CalcArmorMod(effectiveAL); //Console.WriteLine("Total AL: " + effectiveAL); //Console.WriteLine("Armor mod: " + armorMod); return(armorMod); }
public float CalculateDamage(WorldObject target, WorldObject damageSource, ref bool criticalHit, ref bool sneakAttack) { var creature = target as Creature; // evasion chance var evadeChance = GetEvadeChance(target); if (Physics.Common.Random.RollDice(0.0f, 1.0f) < evadeChance) { return(0.0f); } // get weapon base damage var baseDamageRange = GetBaseDamage(); var baseDamage = Physics.Common.Random.RollDice(baseDamageRange.Min, baseDamageRange.Max); // get damage mods var attackType = GetAttackType(); var attributeMod = GetAttributeMod(attackType); var powerAccuracyMod = GetPowerAccuracyMod(); var recklessnessMod = GetRecklessnessMod(this, creature); var sneakAttackMod = GetSneakAttackMod(target); sneakAttack = sneakAttackMod > 1.0f; var damageRatingMod = AdditiveCombine(recklessnessMod, sneakAttackMod, GetRatingMod(EnchantmentManager.GetDamageRating())); //Console.WriteLine("Damage rating: " + ModToRating(damageRatingMod)); var damage = baseDamage * attributeMod * powerAccuracyMod * damageRatingMod; // critical hit var critical = GetWeaponPhysicalCritFrequencyModifier(this); if (Physics.Common.Random.RollDice(0.0f, 1.0f) < critical) { damage = baseDamageRange.Max * attributeMod * powerAccuracyMod * sneakAttackMod * (2.0f + GetWeaponCritMultiplierModifier(this)); criticalHit = true; } // get random body part @ attack height var bodyPart = BodyParts.GetBodyPart(target, AttackHeight.Value); if (bodyPart == null) { return(0.0f); } var creaturePart = new Creature_BodyPart(creature, bodyPart); // get target armor var armor = creaturePart.BaseArmorMod; // get target resistance DamageType damageType; if (damageSource?.ItemType == ItemType.MissileWeapon) { damageType = (DamageType)damageSource.GetProperty(PropertyInt.DamageType); } else { damageType = GetDamageType(); } creaturePart.WeaponResistanceMod = GetWeaponResistanceModifier(this, damageType); var resistance = GetResistance(creaturePart, damageType); // ratings var damageResistRatingMod = GetNegativeRatingMod(creature.EnchantmentManager.GetDamageResistRating()); //Console.WriteLine("Damage resistance rating: " + NegativeModToRating(damageResistRatingMod)); // scale damage for armor and shield var armorMod = SkillFormula.CalcArmorMod(resistance); var shieldMod = creature.GetShieldMod(this, damageType); var slayerMod = GetWeaponCreatureSlayerModifier(this, target as Creature); var elementalDamageMod = GetMissileElementalDamageModifier(this, target as Creature, damageType); return((damage + elementalDamageMod) * armorMod * shieldMod * slayerMod * damageResistRatingMod); }
/// <summary> /// Return the scalar damage absorbed by a shield /// </summary> public float GetShieldMod(WorldObject attacker, DamageType damageType, WorldObject weapon) { // ensure combat stance if (CombatMode == CombatMode.NonCombat) { return(1.0f); } // does the player have a shield equipped? var shield = GetEquippedShield(); if (shield == null) { return(1.0f); } // phantom weapons ignore all armor and shields if (weapon != null && weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor)) { return(1.0f); } // is monster in front of player, // within shield effectiveness area? var effectiveAngle = 180.0f; var angle = GetAngle(attacker); if (Math.Abs(angle) > effectiveAngle / 2.0f) { return(1.0f); } // get base shield AL var baseSL = shield.GetProperty(PropertyInt.ArmorLevel) ?? 0.0f; // shield AL item enchantment additives: // impenetrability, brittlemail var ignoreMagicArmor = weapon != null ? weapon.IgnoreMagicArmor : false; var modSL = ignoreMagicArmor ? 0 : shield.EnchantmentManager.GetArmorMod(); var effectiveSL = baseSL + modSL; // get shield RL against damage type var baseRL = GetResistance(shield, damageType); // shield RL item enchantment additives: // banes, lures var modRL = ignoreMagicArmor ? 0 : shield.EnchantmentManager.GetArmorModVsType(damageType); var effectiveRL = (float)(baseRL + modRL); // resistance clamp effectiveRL = Math.Clamp(effectiveRL, -2.0f, 2.0f); // handle negative SL if (effectiveSL < 0) { effectiveRL = 1.0f / effectiveRL; } var effectiveLevel = effectiveSL * effectiveRL; // SL cap: // Trained / untrained: 1/2 shield skill // Spec: shield skill // SL cap is applied *after* item enchantments var shieldSkill = GetCreatureSkill(Skill.Shield); var shieldCap = shieldSkill.Current; if (shieldSkill.AdvancementClass != SkillAdvancementClass.Specialized) { shieldCap = (uint)Math.Round(shieldCap / 2.0f); } effectiveLevel = Math.Min(effectiveLevel, shieldCap); // SL is multiplied by existing AL var shieldMod = SkillFormula.CalcArmorMod(effectiveLevel); //Console.WriteLine("ShieldMod: " + shieldMod); return(shieldMod); }
/// <summary> /// Main entry point for getting the armor mod /// </summary> public float GetArmorMod(DamageType damageType, List <WorldObject> armorLayers, Creature attacker, WorldObject weapon, float armorRendingMod = 1.0f) { var effectiveArmorVsType = GetEffectiveArmorVsType(damageType, armorLayers, attacker, weapon, armorRendingMod); return(SkillFormula.CalcArmorMod(effectiveArmorVsType)); }
public float GetShieldMod(WorldObject attacker, DamageType damageType) { // does the player have a shield equipped? var shield = GetEquippedShield(); if (shield == null) { return(1.0f); } // is monster in front of player, // within shield effectiveness area? var effectiveAngle = 135.0f; var angle = GetAngle(attacker); if (Math.Abs(angle) > effectiveAngle / 2.0f) { return(1.0f); } // get base shield AL var baseSL = shield.GetProperty(PropertyInt.ArmorLevel) ?? 0.0f; // shield AL item enchantment additives: // impenetrability, brittlemail var modSL = EnchantmentManager.GetArmorMod(); var effectiveSL = baseSL + modSL; // get shield RL against damage type var baseRL = GetResistance(shield, damageType); // shield RL item enchantment additives: // banes, lures var modRL = EnchantmentManager.GetArmorModVsType(damageType); var effectiveRL = (float)(baseRL + modRL); // resistance cap if (effectiveRL > 2.0f) { effectiveRL = 2.0f; } var effectiveLevel = effectiveSL * effectiveRL; // SL cap: // Trained / untrained: 1/2 shield skill // Spec: shield skill // SL cap is applied *after* item enchantments var shieldSkill = GetCreatureSkill(Skill.Shield); var shieldCap = shieldSkill.Current; if (shieldSkill.Status != SkillStatus.Specialized) { shieldCap = (uint)Math.Round(shieldCap / 2.0f); } effectiveLevel = Math.Min(effectiveLevel, shieldCap); // SL is multiplied by existing AL var shieldMod = SkillFormula.CalcArmorMod(effectiveLevel); //Console.WriteLine("ShieldMod: " + shieldMod); return(shieldMod); }
/// <summary> /// Main entry point for getting the armor mod /// </summary> public float GetArmorMod(DamageType damageType, List <WorldObject> armorLayers, WorldObject damageSource, float armorRendingMod = 1.0f) { var effectiveArmorVsType = GetEffectiveArmorVsType(damageType, armorLayers, damageSource, armorRendingMod); return(SkillFormula.CalcArmorMod(effectiveArmorVsType)); }
public float?CalculateDamage(WorldObject target, WorldObject damageSource, ref bool criticalHit, ref bool sneakAttack) { var creature = target as Creature; // evasion chance var evadeChance = GetEvadeChance(target); if (ThreadSafeRandom.Next(0.0f, 1.0f) < evadeChance) { return(null); } // get weapon base damage var weapon = GetEquippedWeapon(); var baseDamageRange = GetBaseDamage(); var baseDamage = ThreadSafeRandom.Next(baseDamageRange.Min, baseDamageRange.Max); // get damage mods var attackType = GetCombatType(); var attributeMod = GetAttributeMod(weapon); var powerAccuracyMod = GetPowerMod(weapon); var recklessnessMod = GetRecklessnessMod(this, creature); var sneakAttackMod = GetSneakAttackMod(target); sneakAttack = sneakAttackMod > 1.0f; // heritage damge mod var heritageMod = GetHeritageBonus(weapon) ? 1.05f : 1.0f; var damageRatingMod = AdditiveCombine(recklessnessMod, sneakAttackMod, heritageMod, GetRatingMod(EnchantmentManager.GetDamageRating())); //Console.WriteLine("Damage rating: " + ModToRating(damageRatingMod)); var damage = baseDamage * attributeMod * powerAccuracyMod * damageRatingMod; // critical hit var attackSkill = GetCreatureSkill(GetCurrentWeaponSkill()); var critical = GetWeaponCritChanceModifier(this, attackSkill); if (ThreadSafeRandom.Next(0.0f, 1.0f) < critical) { var criticalDamageMod = 1.0f + GetWeaponCritDamageMod(this, attackSkill); damage = baseDamageRange.Max * attributeMod * powerAccuracyMod * sneakAttackMod * criticalDamageMod; criticalHit = true; } // get random body part @ attack height var bodyPart = BodyParts.GetBodyPart(target, AttackHeight.Value); if (bodyPart == null) { return(null); } var creaturePart = new Creature_BodyPart(creature, bodyPart, damageSource != null ? damageSource.IgnoreMagicArmor : false, damageSource != null ? damageSource.IgnoreMagicResist : false); if (weapon != null && weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending)) { creaturePart.WeaponArmorMod = GetArmorRendingMod(attackSkill); } // get target armor var armor = creaturePart.BaseArmorMod; // get target resistance DamageType damageType; if (damageSource?.ItemType == ItemType.MissileWeapon) { damageType = (DamageType)damageSource.GetProperty(PropertyInt.DamageType); } else { damageType = GetDamageType(); } creaturePart.WeaponResistanceMod = GetWeaponResistanceModifier(this, attackSkill, damageType); var resistance = GetResistance(creaturePart, damageType); // ratings var damageResistRatingMod = GetNegativeRatingMod(creature.EnchantmentManager.GetDamageResistRating()); //Console.WriteLine("Damage resistance rating: " + NegativeModToRating(damageResistRatingMod)); // scale damage for armor and shield var armorMod = SkillFormula.CalcArmorMod(resistance); var shieldMod = creature.GetShieldMod(this, damageType); var slayerMod = GetWeaponCreatureSlayerModifier(this, target as Creature); var elementalDamageMod = GetMissileElementalDamageModifier(this, target as Creature, damageType); return((damage + elementalDamageMod) * armorMod * shieldMod * slayerMod * damageResistRatingMod); }