Example #1
0
        public MotionCommand GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, uint minSkillLevel = 0)
        {
            if (!Stances.TryGetValue(stance, out var attackHeights))
            {
                return(MotionCommand.Invalid);
            }

            if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes))
            {
                return(MotionCommand.Invalid);
            }

            if (!attackTypes.Table.TryGetValue(attackType, out var minSkillLevels))
            {
                return(MotionCommand.Invalid);
            }

            foreach (var kvp in minSkillLevels.Table)
            {
                if (kvp.Key > minSkillLevel)
                {
                    continue;
                }

                return(kvp.Value);
            }

            return(MotionCommand.Invalid);
        }
Example #2
0
        public Quadrant GetQuadrant(Creature defender, Creature attacker, AttackHeight attackHeight, WorldObject damageSource)
        {
            var quadrant = attackHeight.ToQuadrant();

            var wo = damageSource.CurrentLandblock != null ? damageSource : attacker;

            quadrant |= wo.GetRelativeDir(defender);

            return(quadrant);
        }
Example #3
0
        /// <summary>
        /// Returns a body part for a creature defender
        /// </summary>
        public void GetBodyPart(AttackHeight attackHeight, Creature defender)
        {
            // select random body part @ current attack height
            BiotaPropertiesBodyPart = BodyParts.GetBodyPart(defender, attackHeight);

            if (BiotaPropertiesBodyPart == null)
            {
                Evaded = true;
                return;
            }
            CreaturePart = new Creature_BodyPart(defender, BiotaPropertiesBodyPart);
        }
Example #4
0
        public static BodyPart GetBodyPart(AttackHeight attackHeight)
        {
            switch (attackHeight)
            {
            case AttackHeight.High: return(GetBodyPart(Upper));

            case AttackHeight.Medium: return(GetBodyPart(Mid));

            case AttackHeight.Low:
            default: return(GetBodyPart(Lower));
            }
        }
Example #5
0
        public static string GetString(this AttackHeight attackHeight)
        {
            switch (attackHeight)
            {
            case AttackHeight.High:   return("High");

            case AttackHeight.Medium: return("Med");

            case AttackHeight.Low:    return("Low");
            }
            return(null);
        }
Example #6
0
        public static Quadrant ToQuadrant(this AttackHeight attackHeight)
        {
            switch (attackHeight)
            {
            case AttackHeight.High:   return(Quadrant.High);

            case AttackHeight.Medium: return(Quadrant.Medium);

            case AttackHeight.Low:    return(Quadrant.Low);

            default:
                return(Quadrant.None);
            }
        }
Example #7
0
        public MotionCommand GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, MotionCommand prevMotion)
        {
            if (!Stances.TryGetValue(stance, out var attackHeights))
            {
                return(MotionCommand.Invalid);
            }

            if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes))
            {
                return(MotionCommand.Invalid);
            }

            if (!attackTypes.Table.TryGetValue(attackType, out var maneuvers))
            {
                return(MotionCommand.Invalid);
            }

            if (maneuvers.Count == 1)
            {
                return(maneuvers[0]);
            }

            /*Console.WriteLine($"CombatManeuverTable({Id:X8}).GetMotion({stance}, {attackHeight}, {attackType}) - found {maneuvers.Count} maneuvers");
             * foreach (var maneuver in maneuvers)
             *  Console.WriteLine(maneuver);*/

            // CombatManeuverTable(30000000).GetMotion(SwordCombat, Medium, Slash) - found 2 maneuvers
            // SlashMed
            // BackhandMed

            // rng, or alternate?
            for (var i = 0; i < maneuvers.Count; i++)
            {
                var maneuver = maneuvers[i];

                if (maneuver == prevMotion)
                {
                    if (i < maneuvers.Count - 1)
                    {
                        return(maneuvers[i + 1]);
                    }
                    else
                    {
                        return(maneuvers[0]);
                    }
                }
            }
            return(maneuvers[0]);
        }
Example #8
0
        public List <MotionCommand> GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, MotionCommand prevMotion)
        {
            if (!Stances.TryGetValue(stance, out var attackHeights))
            {
                return(Invalid);
            }

            if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes))
            {
                return(Invalid);
            }

            if (!attackTypes.Table.TryGetValue(attackType, out var maneuvers))
            {
                return(Invalid);
            }

            //if (maneuvers.Count == 1)
            //return maneuvers[0];

            /*Console.WriteLine($"CombatManeuverTable({Id:X8}).GetMotion({stance}, {attackHeight}, {attackType}) - found {maneuvers.Count} maneuvers");
             * foreach (var maneuver in maneuvers)
             *  Console.WriteLine(maneuver);*/

            // CombatManeuverTable(30000000).GetMotion(SwordCombat, Medium, Slash) - found 2 maneuvers
            // SlashMed
            // BackhandMed

            // rng, or alternate?

            /*for (var i = 0; i < maneuvers.Count; i++)
             * {
             *  var maneuver = maneuvers[i];
             *
             *  if (maneuver == prevMotion)
             *  {
             *      if (i < maneuvers.Count - 1)
             *          return maneuvers[i + 1];
             *      else
             *          return maneuvers[0];
             *  }
             * }
             * return maneuvers[0];*/

            // if the CMT contains > 1 entries for this lookup, return both
            // the code determines which motion to use based on the power bar
            return(maneuvers);
        }
Example #9
0
        public void HandleActionTargetedMeleeAttack(ObjectGuid guid, uint attackHeight, float powerLevel)
        {
            /*Console.WriteLine("HandleActionTargetedMeleeAttack");
             * Console.WriteLine("Target ID: " + guid.Full.ToString("X8"));
             * Console.WriteLine("Attack height: " + attackHeight);
             * Console.WriteLine("Power level: " + powerLevel);*/

            // sanity check
            powerLevel = Math.Clamp(powerLevel, 0.0f, 1.0f);

            AttackHeight = (AttackHeight)attackHeight;
            PowerLevel   = powerLevel;

            // get world object of target guid
            var target = CurrentLandblock.GetObject(guid);

            if (target == null)
            {
                log.Warn("Unknown target guid " + guid.Full.ToString("X8"));
                return;
            }
            if (MeleeTarget == null)
            {
                MeleeTarget = target;
            }
            else
            {
                return;
            }

            // get distance from target
            var dist = GetDistance(target);

            // get angle to target
            var angle = GetAngle(target);

            //Console.WriteLine("Dist: " + dist);
            //Console.WriteLine("Angle: " + angle);

            // turn / moveto if required
            Rotate(target);
            MoveTo(target);

            // do melee attack
            Attack(target);
        }
Example #10
0
        public static BiotaPropertiesBodyPart GetBodyPart(WorldObject target, AttackHeight height)
        {
            var creature = target as Creature;

            if (creature == null)
            {
                return(null);
            }

            // get all of the body parts for this creature
            // at this attack height
            var heightParts = creature.Biota.BiotaPropertiesBodyPart.Where(b => b.BH == (int)height).ToList();

            if (heightParts.Count == 0)
            {
                return(null);
            }

            // get random body part
            var rng  = Physics.Common.Random.RollDice(0, heightParts.Count - 1);
            var part = heightParts[rng];

            return(part);
        }
Example #11
0
 /// <summary>
 /// Returns a body part for a player defender
 /// </summary>
 public void GetBodyPart(AttackHeight attackHeight)
 {
     // select random body part @ current attack height
     BodyPart = BodyParts.GetBodyPart(attackHeight);
 }
Example #12
0
        private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource)
        {
            var playerAttacker = attacker as Player;
            var playerDefender = defender as Player;

            Attacker = attacker;
            Defender = defender;

            CombatType = damageSource.ProjectileSource == null?attacker.GetCombatType() : CombatType.Missile;

            DamageSource = damageSource;

            Weapon = damageSource.ProjectileSource == null?attacker.GetEquippedWeapon() : damageSource.ProjectileLauncher;

            AttackType   = attacker.GetAttackType(Weapon, CombatManeuver);
            AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium;

            // check lifestone protection
            if (playerDefender != null && playerDefender.UnderLifestoneProtection)
            {
                LifestoneProtection = true;
                playerDefender.HandleLifestoneProtection();
                return(0.0f);
            }

            if (defender.Invincible)
            {
                return(0.0f);
            }

            // evasion chance
            EvasionChance = GetEvadeChance(attacker, defender);
            if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                Evaded = true;
                return(0.0f);
            }

            // get base damage
            if (playerAttacker != null)
            {
                GetBaseDamage(playerAttacker, CombatManeuver);
            }
            else
            {
                GetBaseDamage(attacker, CombatManeuver);
            }

            if (DamageType == DamageType.Undef)
            {
                log.Error($"DamageEvent.DoCalculateDamage({attacker?.Name} ({attacker?.Guid}), {defender?.Name} ({defender?.Guid}), {damageSource?.Name} ({damageSource?.Guid})) - DamageType == DamageType.Undef");
                GeneralFailure = true;
            }

            if (GeneralFailure)
            {
                return(0.0f);
            }

            // get damage modifiers
            PowerMod     = attacker.GetPowerMod(Weapon);
            AttributeMod = attacker.GetAttributeMod(Weapon);
            SlayerMod    = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender);

            // ratings
            DamageRatingBaseMod = Creature.GetPositiveRatingMod(attacker.GetDamageRating());
            RecklessnessMod     = Creature.GetRecklessnessMod(attacker, defender);
            SneakAttackMod      = attacker.GetSneakAttackMod(defender);
            HeritageMod         = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f;

            DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod);

            // damage before mitigation
            DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod;

            // critical hit?
            var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill());

            CriticalChance = WorldObject.GetWeaponCritChanceModifier(attacker, attackSkill, defender);
            if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                if (playerDefender != null && playerDefender.AugmentationCriticalDefense > 0)
                {
                    var criticalDefenseMod    = playerAttacker != null ? 0.05f : 0.25f;
                    var criticalDefenseChance = playerDefender.AugmentationCriticalDefense * criticalDefenseMod;

                    if (criticalDefenseChance > ThreadSafeRandom.Next(0.0f, 1.0f))
                    {
                        CriticalDefended = true;
                    }
                }

                if (!CriticalDefended)
                {
                    IsCritical = true;

                    CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill, defender);

                    // recklessness excluded from crits
                    RecklessnessMod        = 1.0f;
                    DamageRatingMod        = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod);
                    DamageBeforeMitigation = BaseDamageMod.MaxDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod;
                }
            }

            // Armor Rending reduces physical armor too?
            var armorRendingMod = 1.0f;

            if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending))
            {
                armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill);
            }

            // get body part / armor pieces / armor modifier
            if (playerDefender != null)
            {
                // select random body part @ current attack height
                GetBodyPart(AttackHeight);

                // get player armor pieces
                Armor = attacker.GetArmorLayers(playerDefender, BodyPart);

                // get armor modifiers
                ArmorMod = attacker.GetArmorMod(DamageType, Armor, Weapon, armorRendingMod);
            }
            else
            {
                // select random body part @ current attack height
                GetBodyPart(AttackHeight, defender);
                if (Evaded)
                {
                    return(0.0f);
                }

                Armor = CreaturePart.GetArmorLayers((CombatBodyPart)BiotaPropertiesBodyPart.Key);

                // get target armor
                ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, Weapon, armorRendingMod);
            }

            if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor))
            {
                ArmorMod = 1.0f;
            }

            // get resistance modifiers
            WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType);

            if (playerDefender != null)
            {
                ResistanceMod = playerDefender.GetResistanceMod(DamageType, Weapon, WeaponResistanceMod);
            }
            else
            {
                var resistanceType = Creature.GetResistanceType(DamageType);
                ResistanceMod = (float)defender.GetResistanceMod(resistanceType, Weapon, WeaponResistanceMod);
            }

            // damage resistance rating
            DamageResistanceRatingMod = Creature.GetNegativeRatingMod(defender.GetDamageResistRating(CombatType));

            // get shield modifier
            ShieldMod = defender.GetShieldMod(attacker, DamageType, Weapon);

            // calculate final output damage
            Damage          = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod;
            DamageMitigated = DamageBeforeMitigation - Damage;

            return(Damage);
        }
Example #13
0
        private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource)
        {
            var playerAttacker = attacker as Player;
            var playerDefender = defender as Player;

            Attacker = attacker;
            Defender = defender;

            CombatType = damageSource.ProjectileSource == null ? CombatType.Melee : CombatType.Missile;

            DamageSource = damageSource;

            Weapon = damageSource.ProjectileSource == null?attacker.GetEquippedMeleeWeapon() : damageSource.ProjectileLauncher;

            AttackType   = attacker.AttackType;
            AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium;

            // check lifestone protection
            if (playerDefender != null && playerDefender.UnderLifestoneProtection)
            {
                LifestoneProtection = true;
                playerDefender.HandleLifestoneProtection();
                return(0.0f);
            }

            if (defender.Invincible)
            {
                return(0.0f);
            }

            // overpower
            if (attacker.Overpower != null)
            {
                Overpower = Creature.GetOverpower(attacker, defender);
            }

            // evasion chance
            if (!Overpower)
            {
                EvasionChance = GetEvadeChance(attacker, defender);
                if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f))
                {
                    Evaded = true;
                    return(0.0f);
                }
            }

            // get base damage
            if (playerAttacker != null)
            {
                GetBaseDamage(playerAttacker);
            }
            else
            {
                GetBaseDamage(attacker, AttackMotion ?? MotionCommand.Invalid);
            }

            if (DamageType == DamageType.Undef && !AllowDamageTypeUndef.Contains(damageSource.WeenieClassId))
            {
                log.Error($"DamageEvent.DoCalculateDamage({attacker?.Name} ({attacker?.Guid}), {defender?.Name} ({defender?.Guid}), {damageSource?.Name} ({damageSource?.Guid})) - DamageType == DamageType.Undef");
                GeneralFailure = true;
            }

            if (GeneralFailure)
            {
                return(0.0f);
            }

            // get damage modifiers
            PowerMod     = attacker.GetPowerMod(Weapon);
            AttributeMod = attacker.GetAttributeMod(Weapon);
            SlayerMod    = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender);

            // ratings
            DamageRatingBaseMod = Creature.GetPositiveRatingMod(attacker.GetDamageRating());
            RecklessnessMod     = Creature.GetRecklessnessMod(attacker, defender);
            SneakAttackMod      = attacker.GetSneakAttackMod(defender);
            HeritageMod         = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f;

            DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod);

            // damage before mitigation
            DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod;

            // critical hit?
            var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill());

            CriticalChance = WorldObject.GetWeaponCriticalChance(attacker, attackSkill, defender);

            // https://asheron.fandom.com/wiki/Announcements_-_2002/08_-_Atonement
            // It should be noted that any time a character is logging off, PK or not, all physical attacks against them become automatically critical.
            // (Note that spells do not share this behavior.) We hope this will stress the need to log off in a safe place.

            if (playerDefender != null && (playerDefender.IsLoggingOut || playerDefender.PKLogout))
            {
                CriticalChance = 1.0f;
            }

            if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                if (playerDefender != null && playerDefender.AugmentationCriticalDefense > 0)
                {
                    var criticalDefenseMod    = playerAttacker != null ? 0.05f : 0.25f;
                    var criticalDefenseChance = playerDefender.AugmentationCriticalDefense * criticalDefenseMod;

                    if (criticalDefenseChance > ThreadSafeRandom.Next(0.0f, 1.0f))
                    {
                        CriticalDefended = true;
                    }
                }

                if (!CriticalDefended)
                {
                    IsCritical = true;

                    CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill, defender);

                    // recklessness excluded from crits
                    RecklessnessMod        = 1.0f;
                    DamageRatingMod        = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod);
                    DamageBeforeMitigation = BaseDamageMod.MaxDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod;
                }
            }

            // armor rending and cleaving
            var armorRendingMod = 1.0f;

            if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending))
            {
                armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill);
            }

            var armorCleavingMod = attacker.GetArmorCleavingMod(Weapon);

            var ignoreArmorMod = Math.Min(armorRendingMod, armorCleavingMod);

            // get body part / armor pieces / armor modifier
            if (playerDefender != null)
            {
                // select random body part @ current attack height
                GetBodyPart(AttackHeight);

                // get player armor pieces
                Armor = attacker.GetArmorLayers(playerDefender, BodyPart);

                // get armor modifiers
                ArmorMod = attacker.GetArmorMod(DamageType, Armor, Weapon, ignoreArmorMod);
            }
            else
            {
                // determine height quadrant
                Quadrant = GetQuadrant(Defender, Attacker, AttackHeight, DamageSource);

                // select random body part @ current attack height
                GetBodyPart(Defender, Quadrant);
                if (Evaded)
                {
                    return(0.0f);
                }

                Armor = CreaturePart.GetArmorLayers(PropertiesBodyPart.Key);

                // get target armor
                ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, Attacker, Weapon, ignoreArmorMod);
            }

            if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor))
            {
                ArmorMod = 1.0f;
            }

            // get resistance modifiers
            WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType);

            if (playerDefender != null)
            {
                ResistanceMod = playerDefender.GetResistanceMod(DamageType, Attacker, Weapon, WeaponResistanceMod);
            }
            else
            {
                var resistanceType = Creature.GetResistanceType(DamageType);
                ResistanceMod = (float)Math.Max(0.0f, defender.GetResistanceMod(resistanceType, Attacker, Weapon, WeaponResistanceMod));
            }

            // damage resistance rating
            DamageResistanceRatingMod = defender.GetDamageResistRatingMod(CombatType);

            // get shield modifier
            ShieldMod = defender.GetShieldMod(attacker, DamageType, Weapon);

            // calculate final output damage
            Damage          = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod;
            DamageMitigated = DamageBeforeMitigation - Damage;

            return(Damage);
        }
Example #14
0
 /// <summary>
 /// Returns the current attack height as an enumerable string
 /// </summary>
 public string GetAttackHeight()
 {
     return(AttackHeight?.GetString());
 }
Example #15
0
        private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource)
        {
            var playerAttacker = attacker as Player;
            var playerDefender = defender as Player;

            Attacker = attacker;
            Defender = defender;

            CombatType = attacker.GetCombatType();

            DamageSource = damageSource;

            Weapon = attacker.GetEquippedWeapon();

            AttackType   = attacker.GetAttackType(Weapon, CombatManeuver);
            AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium;

            // check lifestone protection
            if (playerDefender != null && playerDefender.UnderLifestoneProtection)
            {
                LifestoneProtection = true;
                playerDefender.HandleLifestoneProtection();
                return(0.0f);
            }

            if (defender.Invincible ?? false)
            {
                return(0.0f);
            }

            // evasion chance
            EvasionChance = GetEvadeChance(attacker, defender);
            if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                Evaded = true;
                return(0.0f);
            }

            // get base damage
            if (playerAttacker != null)
            {
                GetBaseDamage(playerAttacker, CombatManeuver);
            }
            else
            {
                GetBaseDamage(attacker, CombatManeuver);
            }

            if (GeneralFailure)
            {
                return(0.0f);
            }

            // get damage modifiers
            PowerMod     = attacker.GetPowerMod(Weapon);
            AttributeMod = attacker.GetAttributeMod(Weapon);
            SlayerMod    = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender);

            // additive?
            ElementalDamageBonus = WorldObject.GetMissileElementalDamageModifier(attacker, defender, DamageType);

            // ratings
            DamageRatingBaseMod = Creature.GetPositiveRating(attacker.GetProperty(PropertyInt.DamageRating) ?? 0);
            RecklessnessMod     = Creature.GetRecklessnessMod(attacker, defender);
            SneakAttackMod      = attacker.GetSneakAttackMod(defender);
            HeritageMod         = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f;

            DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod, Creature.GetRatingMod(attacker.EnchantmentManager.GetDamageRating()));

            // damage before mitigation
            DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod + ElementalDamageBonus;   // additives on the end?

            // critical hit?
            var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill());

            CriticalChance = WorldObject.GetWeaponCritChanceModifier(attacker, attackSkill);
            if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                IsCritical = true;

                CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill);

                // recklessness excluded from crits
                RecklessnessMod        = 1.0f;
                DamageRatingMod        = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod, Creature.GetRatingMod(attacker.EnchantmentManager.GetDamageRating()));
                DamageBeforeMitigation = BaseDamageRange.Max * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod + ElementalDamageBonus;
            }

            // get armor rending mod here?
            var armorRendingMod = 1.0f;

            if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending))
            {
                armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill);
            }

            // get body part / armor pieces / armor modifier
            if (playerDefender != null)
            {
                // select random body part @ current attack height
                GetBodyPart(AttackHeight);

                // get armor pieces
                Armor = attacker.GetArmorLayers(BodyPart);    // this uses attacker.AttackTarget

                // get armor modifiers
                ArmorMod = attacker.GetArmorMod(DamageType, Armor, DamageSource, armorRendingMod);
            }
            else
            {
                // select random body part @ current attack height
                GetBodyPart(AttackHeight, defender);
                if (Evaded)
                {
                    return(0.0f);
                }

                Armor = CreaturePart.GetArmorLayers((CombatBodyPart)BiotaPropertiesBodyPart.Key);

                // get target armor
                ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, DamageSource, armorRendingMod);
            }

            // get resistance modifiers
            WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType);

            if (playerDefender != null)
            {
                ResistanceMod = playerDefender.GetResistanceMod(DamageType, DamageSource, WeaponResistanceMod);
            }
            else
            {
                // todo: move out of creature part, not part-related?
                ResistanceMod = CreaturePart.GetResistanceMod(DamageType, DamageSource, WeaponResistanceMod);
            }

            // damage resistance rating
            DamageResistanceRatingMod = Creature.GetNegativeRatingMod(defender.EnchantmentManager.GetDamageResistRating());

            // get shield modifier
            ShieldMod = defender.GetShieldMod(attacker, DamageType);

            // calculate final output damage
            Damage          = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod;
            DamageMitigated = DamageBeforeMitigation - Damage;

            HandleLogging(playerAttacker, playerDefender);

            return(Damage);
        }
Example #16
0
 public override string GetAttackHeight()
 {
     return AttackHeight?.GetString();
 }