Ejemplo n.º 1
0
        /// <summary>
        /// Selects a random body part at current attack height
        /// </summary>
        public BodyPart GetBodyPart()
        {
            if (AttackHeight == null)
            {
                GetAttackHeight();
            }

            return(BodyParts.GetBodyPart(AttackHeight.Value));
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Performs a melee attack for the monster
        /// </summary>
        /// <returns>The length in seconds for the attack animation</returns>
        public float MeleeAttack()
        {
            var player = AttackTarget as Player;

            if (player.Health.Current <= 0)
            {
                return(0.0f);
            }

            // choose a random combat maneuver
            var maneuver = GetCombatManeuver();

            if (maneuver == null)
            {
                return(0.0f);
            }

            AttackHeight = maneuver.AttackHeight;

            // select random body part @ current attack height
            var bodyPart = BodyParts.GetBodyPart(AttackHeight.Value);

            DoSwingMotion(AttackTarget, maneuver, out float animLength);
            PhysicsObj.stick_to_object(AttackTarget.PhysicsObj.ID);

            var actionChain = new ActionChain();

            actionChain.AddDelaySeconds(animLength / 2.0f);
            actionChain.AddAction(this, () =>
            {
                if (AttackTarget == null)
                {
                    return;
                }

                var critical   = false;
                var damageType = DamageType.Undef;
                var damage     = CalculateDamage(ref damageType, maneuver, bodyPart, ref critical);

                if (damage > 0.0f)
                {
                    player.TakeDamage(this, damageType, damage, bodyPart, critical);
                }
                else
                {
                    player.OnEvade(this, AttackType.Melee);
                }
            });
            actionChain.EnqueueChain();

            // TODO: figure out exact speed / delay formula
            NextAttackTime = Timer.CurrentTime + animLength + MeleeDelay;
            return(animLength);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Performs a melee attack for the monster
        /// </summary>
        /// <returns>The length in seconds for the attack animation</returns>
        public float MeleeAttack()
        {
            var target       = AttackTarget as Creature;
            var targetPlayer = AttackTarget as Player;
            var targetPet    = AttackTarget as CombatPet;
            var combatPet    = this as CombatPet;

            if (target == null || !target.IsAlive)
            {
                Sleep();
                return(0.0f);
            }

            // choose a random combat maneuver
            var maneuver = GetCombatManeuver();

            if (maneuver == null)
            {
                Console.WriteLine($"Combat maneuver null! Stance {CurrentMotionState.Stance}, MotionTable {MotionTableId:X8}");
                return(0.0f);
            }

            AttackHeight = maneuver.AttackHeight;

            // select random body part @ current attack height
            var bodyPart = BodyParts.GetBodyPart(AttackHeight.Value);

            DoSwingMotion(AttackTarget, maneuver, out float animLength, out var attackFrames);
            PhysicsObj.stick_to_object(AttackTarget.PhysicsObj.ID);

            var numStrikes = attackFrames.Count;

            var actionChain = new ActionChain();

            var prevTime = 0.0f;

            for (var i = 0; i < numStrikes; i++)
            {
                actionChain.AddDelaySeconds(attackFrames[i] * animLength - prevTime);
                prevTime = attackFrames[i] * animLength;

                actionChain.AddAction(this, () =>
                {
                    if (AttackTarget == null)
                    {
                        return;
                    }

                    var critical   = false;
                    var damageType = DamageType.Undef;
                    var shieldMod  = 1.0f;
                    var damage     = CalculateDamage(ref damageType, maneuver, bodyPart, ref critical, ref shieldMod);

                    if (damage != null)
                    {
                        if (combatPet != null || targetPet != null)
                        {
                            // combat pet inflicting or receiving damage
                            //Console.WriteLine($"{target.Name} taking {Math.Round(damage)} {damageType} damage from {Name}");
                            target.TakeDamage(this, damageType, damage.Value);
                            EmitSplatter(target, damage.Value);
                        }
                        else
                        {
                            // this is a player taking damage
                            targetPlayer.TakeDamage(this, damageType, damage.Value, bodyPart, critical);

                            if (shieldMod != 1.0f)
                            {
                                var shieldSkill = targetPlayer.GetCreatureSkill(Skill.Shield);
                                Proficiency.OnSuccessUse(targetPlayer, shieldSkill, shieldSkill.Current); // ?
                            }
                        }
                    }
                    else
                    {
                        target.OnEvade(this, CombatType.Melee);
                    }
                });
            }
            actionChain.EnqueueChain();

            // TODO: figure out exact speed / delay formula
            var meleeDelay = ThreadSafeRandom.Next(MeleeDelayMin, MeleeDelayMax);

            NextAttackTime = Timers.RunningTime + animLength + meleeDelay;
            return(animLength);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Performs a melee attack for the monster
        /// </summary>
        /// <returns>The length in seconds for the attack animation</returns>
        public float MeleeAttack()
        {
            var target = AttackTarget as Creature;

            if (target == null || !target.IsAlive)
            {
                Sleep();
                return(0.0f);
            }

            // choose a random combat maneuver
            var maneuver = GetCombatManeuver();

            if (maneuver == null)
            {
                Console.WriteLine($"Combat maneuver null! Stance {CurrentMotionState.Stance}, MotionTable {MotionTableId:X8}");
                return(0.0f);
            }

            AttackHeight = maneuver.AttackHeight;

            // select random body part @ current attack height
            var bodyPart = BodyParts.GetBodyPart(AttackHeight.Value);

            DoSwingMotion(AttackTarget, maneuver, out float animLength);
            PhysicsObj.stick_to_object(AttackTarget.PhysicsObj.ID);

            var actionChain = new ActionChain();

            actionChain.AddDelaySeconds(animLength / 3.0f);     // TODO: get attack frame?
            actionChain.AddAction(this, () =>
            {
                if (AttackTarget == null)
                {
                    return;
                }

                var critical   = false;
                var damageType = DamageType.Undef;
                var shieldMod  = 1.0f;
                var damage     = CalculateDamage(ref damageType, maneuver, bodyPart, ref critical, ref shieldMod);

                var player = AttackTarget as Player;

                if (damage > 0.0f)
                {
                    player.TakeDamage(this, damageType, damage, bodyPart, critical);

                    if (shieldMod != 1.0f)
                    {
                        var shieldSkill = player.GetCreatureSkill(Skill.Shield);
                        Proficiency.OnSuccessUse(player, shieldSkill, shieldSkill.Current); // ?
                    }
                }
                else
                {
                    player.OnEvade(this, AttackType.Melee);
                }
            });
            actionChain.EnqueueChain();

            // TODO: figure out exact speed / delay formula
            var meleeDelay = Physics.Common.Random.RollDice(MeleeDelayMin, MeleeDelayMax);

            NextAttackTime = Timers.RunningTime + animLength + meleeDelay;;
            return(animLength);
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Calculates the creature damage for a physical monster attack
        /// </summary>
        public float?CalculateDamagePVP(WorldObject target, WorldObject damageSource, DamageType damageType, ref bool criticalHit, ref bool sneakAttack, ref BodyPart bodyPart)
        {
            // verify target player killer
            var targetPlayer = target as Player;

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

            // check lifestone protection
            if (targetPlayer.UnderLifestoneProtection)
            {
                targetPlayer.HandleLifestoneProtection();
                return(null);
            }

            // evasion chance
            var evadeChance = GetEvadeChance(target);

            if (ThreadSafeRandom.Next(0.0f, 1.0f) < evadeChance)
            {
                return(null);
            }

            // get base damage
            var baseDamageRange = GetBaseDamage();
            var baseDamage      = ThreadSafeRandom.Next(baseDamageRange.Min, baseDamageRange.Max);

            // get damage mods
            var attackType       = GetAttackType();
            var attributeMod     = GetAttributeMod(attackType);
            var powerAccuracyMod = GetPowerAccuracyMod();
            var recklessnessMod  = GetRecklessnessMod(this, targetPlayer);
            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 attackSkill = GetCreatureSkill(GetCurrentWeaponSkill());
            var critical    = GetWeaponPhysicalCritFrequencyModifier(this, attackSkill);

            if (ThreadSafeRandom.Next(0.0f, 1.0f) < critical)
            {
                damage      = baseDamageRange.Max * attributeMod * powerAccuracyMod * sneakAttackMod * (1.0f + GetWeaponCritMultiplierModifier(this, attackSkill));
                criticalHit = true;
            }

            // select random body part @ current attack height
            bodyPart = BodyParts.GetBodyPart(AttackHeight.Value);

            // get armor piece
            var armor = GetArmor(bodyPart);

            // get armor modifiers
            var armorMod = GetArmorMod(armor, damageSource, damageType, attackSkill);

            // get resistance modifiers (protect/vuln)
            var resistanceMod = damageSource != null && damageSource.IgnoreMagicResist ? 1.0f : AttackTarget.EnchantmentManager.GetResistanceMod(damageType);

            // weapon resistance mod?
            var damageResistRatingMod = GetNegativeRatingMod(AttackTarget.EnchantmentManager.GetDamageResistRating());

            // get shield modifier
            var attackTarget = AttackTarget as Creature;
            var shieldMod    = attackTarget.GetShieldMod(this, damageType);

            var slayerMod          = GetWeaponCreatureSlayerModifier(this, target as Creature);
            var elementalDamageMod = GetMissileElementalDamageModifier(this, target as Creature, damageType);

            // scale damage by modifiers
            var outDamage = (damage + elementalDamageMod) * armorMod * shieldMod * slayerMod * resistanceMod * damageResistRatingMod;

            return(outDamage);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Calculates the creature damage for a physical monster attack
        /// </summary>
        public float?CalculateDamagePVP(WorldObject target, WorldObject damageSource, DamageType damageType, ref bool criticalHit, ref bool sneakAttack, ref BodyPart bodyPart)
        {
            // verify target player killer
            var targetPlayer = target as Player;

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

            // check lifestone protection
            if (targetPlayer.UnderLifestoneProtection)
            {
                targetPlayer.HandleLifestoneProtection();
                return(null);
            }

            // evasion chance
            var evadeChance = GetEvadeChance(target);

            if (ThreadSafeRandom.Next(0.0f, 1.0f) < evadeChance)
            {
                return(null);
            }

            // get 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 powerMod        = GetPowerMod(weapon);
            var recklessnessMod = GetRecklessnessMod(this, targetPlayer);
            var sneakAttackMod  = GetSneakAttackMod(target);

            sneakAttack = sneakAttackMod > 1.0f;

            // heritage damge mod
            var heritageMod = GetHeritageBonus(weapon) ? 1.05f : 1.0f;

            var damageRatingMod = AdditiveCombine(heritageMod, recklessnessMod, sneakAttackMod, GetRatingMod(EnchantmentManager.GetDamageRating()), GetNegativeRatingMod(target.EnchantmentManager.GetDamageResistRating()));
            //Console.WriteLine("Damage rating: " + ModToRating(damageRatingMod));

            var damage = baseDamage * attributeMod * powerMod * damageRatingMod;

            // critical hit
            var attackSkill = GetCreatureSkill(GetCurrentWeaponSkill());
            var critical    = GetWeaponCritChanceModifier(this, attackSkill);

            if (ThreadSafeRandom.Next(0.0f, 1.0f) < critical)
            {
                if (targetPlayer != null && targetPlayer.AugmentationCriticalDefense > 0)
                {
                    var protChance = targetPlayer.AugmentationCriticalDefense * 0.05f;
                    if (ThreadSafeRandom.Next(0.0f, 1.0f) > protChance)
                    {
                        criticalHit = true;
                    }
                }
                else
                {
                    criticalHit = true;
                }
            }

            if (criticalHit)
            {
                // not effective for criticals: recklessness
                damageRatingMod = AdditiveCombine(heritageMod, sneakAttackMod, GetRatingMod(EnchantmentManager.GetDamageRating()), GetNegativeRatingMod(target.EnchantmentManager.GetDamageResistRating()));
                damage          = baseDamageRange.Max * attributeMod * powerMod * damageRatingMod * (1.0f + GetWeaponCritDamageMod(this, attackSkill));
            }

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

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

            // select random body part @ current attack height
            bodyPart = BodyParts.GetBodyPart(AttackHeight.Value);

            // get armor piece
            var armor = GetArmorLayers(bodyPart);

            // get armor modifiers
            var armorMod = GetArmorMod(damageType, armor, damageSource, armorRendingMod);

            // get resistance modifiers (protect/vuln)
            var resistanceMod = damageSource != null && damageSource.IgnoreMagicResist ? 1.0f : AttackTarget.EnchantmentManager.GetResistanceMod(damageType);

            // weapon resistance mod?
            var damageResistRatingMod = GetNegativeRatingMod(AttackTarget.EnchantmentManager.GetDamageResistRating());

            // get shield modifier
            var attackTarget = AttackTarget as Creature;
            var shieldMod    = attackTarget.GetShieldMod(this, damageType);

            var slayerMod          = GetWeaponCreatureSlayerModifier(this, target as Creature);
            var elementalDamageMod = GetMissileElementalDamageModifier(this, target as Creature, damageType);

            // scale damage by modifiers
            var outDamage = (damage + elementalDamageMod) * armorMod * shieldMod * slayerMod * resistanceMod * damageResistRatingMod;

            return(outDamage);
        }