예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        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);
        }
예제 #6
0
 /// <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));
     }
 }
예제 #7
0
 /// <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);
     }
 }
예제 #8
0
        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);
        }
예제 #9
0
파일: Monster_Melee.cs 프로젝트: klp2/ACE
        /// <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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        /// <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));
        }
예제 #13
0
        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);
        }
예제 #14
0
        /// <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));
        }
예제 #15
0
        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);
        }