Esempio n. 1
0
        public void Update(decimal timer, Keyboard keyboard, LogData log)
        {
            foreach (SkillControlComponent skillControlComp in skillControlComponents)
            {
                // User
                Entity entity = skillControlComp.Parent;

                AnimationLockComponent animLockComp = animationLockComponents.Find(x => x.Parent == entity);

                if (timer - animLockComp.Start >= Constants.AnimationLock)
                {
                    foreach (SkillName s in skillControlComp.SkillControlList)
                    {
                        if (skillControlComp.SkillControlDictionary[s] == true)
                        {
                            // Skill components
                            SkillBaseComponent skillBaseComp = skillBaseComponents.Find(x => x.Name == s);

                            if (skillBaseComp != null)
                            {
                                // Skill
                                Entity            skill  = skillBaseComp.Parent;
                                CooldownComponent cdComp = cooldownComponents.Find(x => x.Parent == skill);

                                // Checking if skill is on cooldown
                                if (cdComp.UsableAt <= timer)
                                {
                                    ModifierStateComponent modStateComp = modifierStateComponents.Find(x => x.Parent == entity);
                                    BardComponent          brdComp      = bardComponents.Find(x => x.Parent == entity);

                                    // Determining conditional use
                                    bool isUsable = true;

                                    foreach (UseConditionComponent useCondComp in useConditionComponents.FindAll(x => x.Parent == skill))
                                    {
                                        if (!useCondComp.Function(modStateComp, brdComp))
                                        {
                                            isUsable = false;
                                            break;
                                        }
                                    }

                                    if (isUsable)
                                    {
                                        // User Components
                                        AttributesComponent attComp = attributesComponents.Find(x => x.Parent == entity);

                                        // Skill list
                                        List <Entity> skillList = brdComp.SkillList;

                                        // Target components
                                        TargetComponent        targComp         = targetComponents.Find(x => x.Parent == entity);
                                        HealthComponent        targHealthComp   = healthComponents.Find(x => x.Parent == targComp.Target);
                                        ModifierStateComponent targModStateComp = modifierStateComponents.Find(x => x.Parent == targComp.Target);
                                        OverTimeStateComponent targOtComp       = overtimeStateComponents.Find(x => x.Parent == targComp.Target);


                                        // More skill components
                                        PotencyComponent            potComp     = potencyComponents.Find(x => x.Parent == skill);
                                        ConditionalPotencyComponent condPotComp = conditionalPotencyComponents.Find(x => x.Parent == skill);

                                        decimal recast;

                                        if (potComp != null || condPotComp != null)
                                        {
                                            // If the skill is offensive
                                            decimal wdMod    = 1;
                                            decimal apMod    = 1;
                                            decimal detMod   = 1;
                                            decimal tenMod   = 1;
                                            decimal ssMod    = 1;
                                            decimal traitMod = 1;
                                            decimal critMod1 = 1;
                                            decimal dhitMod1 = 1;
                                            decimal critMod2 = 1;
                                            decimal dhitMod2 = 1;
                                            decimal critMod3 = 1;
                                            decimal dhitMod3 = 1;

                                            decimal critChance;
                                            decimal dhitChance;


                                            Dictionary <DamageModifierType, decimal> modifiersDictionary;
                                            Dictionary <AttributeType, decimal>      chancesDictionary;

                                            // Calculates weapon damage modifier
                                            wdMod = CombatFormulas.WeaponDamageMod(attComp.AttributesDictionary[AttributeType.WeaponDamage]);

                                            // Calculates attack power modifier
                                            if (brdComp.Job == Job.Paladin || brdComp.Job == Job.Warrior || brdComp.Job == Job.DarkKnight || brdComp.Job == Job.Monk || brdComp.Job == Job.Dragoon || brdComp.Job == Job.Samurai)
                                            {
                                                apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Strenght] + modStateComp.BuffDictionary[AttributeType.Strenght]);
                                            }
                                            else if (brdComp.Job == Job.Ninja || brdComp.Job == Job.Bard || brdComp.Job == Job.Machinist)
                                            {
                                                apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Dexterity] + modStateComp.BuffDictionary[AttributeType.Dexterity]);
                                            }
                                            else if (brdComp.Job == Job.BlackMage || brdComp.Job == Job.Summoner || brdComp.Job == Job.RedMage)
                                            {
                                                apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Intelligence] + modStateComp.BuffDictionary[AttributeType.Intelligence]);
                                            }
                                            else if (brdComp.Job == Job.WhiteMage || brdComp.Job == Job.Scholar || brdComp.Job == Job.Astrologian)
                                            {
                                                apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Mind] + modStateComp.BuffDictionary[AttributeType.Mind]);
                                            }

                                            // Calculates determination modifier
                                            detMod = CombatFormulas.DeterminationDamageMod(attComp.AttributesDictionary[AttributeType.Determination] + modStateComp.BuffDictionary[AttributeType.Determination]);

                                            // Calculates tenacity modifier
                                            tenMod = CombatFormulas.TenacityDamageMod(attComp.AttributesDictionary[AttributeType.Tenacity] + modStateComp.BuffDictionary[AttributeType.Tenacity]);

                                            // Calculates speed modifier
                                            if (brdComp.Job == Job.BlackMage || brdComp.Job == Job.Summoner || brdComp.Job == Job.RedMage || brdComp.Job == Job.WhiteMage || brdComp.Job == Job.Scholar || brdComp.Job == Job.Astrologian)
                                            {
                                                ssMod = CombatFormulas.SpeedDamageMod(attComp.AttributesDictionary[AttributeType.SpellSpeed] + modStateComp.BuffDictionary[AttributeType.SpellSpeed]);
                                            }
                                            else
                                            {
                                                ssMod = CombatFormulas.SpeedDamageMod(attComp.AttributesDictionary[AttributeType.SkillSpeed] + modStateComp.BuffDictionary[AttributeType.SkillSpeed]);
                                            }

                                            // Calculates trait modifier
                                            if (brdComp.Job == Job.Ninja || brdComp.Job == Job.Bard || brdComp.Job == Job.Machinist)
                                            {
                                                traitMod = 1.2m;
                                            }
                                            else if (brdComp.Job == Job.BlackMage || brdComp.Job == Job.Summoner || brdComp.Job == Job.RedMage || brdComp.Job == Job.WhiteMage || brdComp.Job == Job.Scholar || brdComp.Job == Job.Astrologian)
                                            {
                                                traitMod = 1.3m;
                                            }

                                            // Checks for straighter shot guaranteed crit
                                            Enabler straighterShot = modStateComp.EnablerList.Find(x => x.Name == StatusName.StraighterShot);
                                            if (skillBaseComp.Name == SkillName.StraightShot && straighterShot != null)
                                            {
                                                critChance = 100;
                                                modStateComp.EnablerList.Remove(straighterShot);
                                            }
                                            else
                                            {
                                                critChance = CombatFormulas.CriticalHitRate(attComp.AttributesDictionary[AttributeType.CriticalHit]) + modStateComp.BuffDictionary[AttributeType.CriticalHitRate];
                                            }

                                            dhitChance = CombatFormulas.DirectHitRate(attComp.AttributesDictionary[AttributeType.DirectHit]) + modStateComp.BuffDictionary[AttributeType.DirectHitRate];

                                            // Calculates crit modifier
                                            critMod1 = CombatFormulas.CriticalHitDamageMod(attComp.AttributesDictionary[AttributeType.CriticalHit] + modStateComp.BuffDictionary[AttributeType.CriticalHit]);
                                            critMod2 = critMod1;
                                            critMod3 = critMod1;

                                            // Calculates dhit modifier
                                            dhitMod1 = CombatFormulas.DirectHitDamageMod(attComp.AttributesDictionary[AttributeType.DirectHit] + modStateComp.BuffDictionary[AttributeType.DirectHit]);
                                            dhitMod2 = dhitMod1;
                                            dhitMod3 = dhitMod1;

                                            // Compilates the chances into a dictionary:
                                            chancesDictionary = new Dictionary <AttributeType, decimal>
                                            {
                                                { AttributeType.CriticalHitRate, critChance },
                                                { AttributeType.DirectHitRate, dhitChance }
                                            };

                                            // Compilates all the modifiers into a dictionary:
                                            modifiersDictionary = new Dictionary <DamageModifierType, decimal>
                                            {
                                                { DamageModifierType.WeaponDamageModifier, wdMod },
                                                { DamageModifierType.AttackPowerModifier, apMod },
                                                { DamageModifierType.DeterminationModifier, detMod },
                                                { DamageModifierType.TenacityModifier, tenMod },
                                                { DamageModifierType.TraitModifier, traitMod },
                                                { DamageModifierType.SpeedModifier, ssMod },
                                                { DamageModifierType.CriticalModifier, critMod1 },
                                                { DamageModifierType.DirectModifier, dhitMod1 }
                                            };
                                            decimal totalDamage1 = 0;
                                            decimal totalDamage2 = 0;
                                            decimal totalDamage3 = 0;

                                            decimal potMod  = 1;
                                            int     potency = 0;

                                            // Determining potency:
                                            if (potComp != null)
                                            {
                                                potency = potComp.Amount;
                                            }
                                            else if (condPotComp != null)
                                            {
                                                potency = condPotComp.Function(entity, targOtComp, brdComp);
                                            }

                                            // Starts calculating potency modifier from base potency
                                            potMod = CombatFormulas.PotencyMod(potency);

                                            // If not critical hit, modifier is 1
                                            if ((int)(critChance * 10) < rng.Next(1, 1000))
                                            {
                                                critMod1 = 1;
                                            }

                                            // If not direct hit, modifier is 1
                                            if ((int)(dhitChance * 10) < rng.Next(1, 1000))
                                            {
                                                dhitMod1 = 1;
                                            }

                                            totalDamage1 = CombatFormulas.DirectDamage(potMod, wdMod, apMod, detMod, tenMod, traitMod, critMod1, dhitMod1, modStateComp.BuffList);


                                            // Checks for barrage
                                            Enabler barrage = modStateComp.EnablerList.Find(x => x.Name == StatusName.Barrage);
                                            if (skillBaseComp.Type == SkillType.Weaponskill && barrage != null)
                                            {
                                                // Rolls crit and dhit for two more hits

                                                // If not critical hit, modifier is 1
                                                if ((int)(critChance * 10) < rng.Next(1, 1000))
                                                {
                                                    critMod2 = 1;
                                                }

                                                // If not direct hit, modifier is 1
                                                if ((int)(dhitChance * 10) < rng.Next(1, 1000))
                                                {
                                                    dhitMod2 = 1;
                                                }

                                                // If not critical hit, modifier is 1
                                                if ((int)(critChance * 10) < rng.Next(1, 1000))
                                                {
                                                    critMod3 = 1;
                                                }

                                                // If not direct hit, modifier is 1
                                                if ((int)(dhitChance * 10) < rng.Next(1, 1000))
                                                {
                                                    dhitMod3 = 1;
                                                }

                                                // Calculates two more hits
                                                totalDamage2 = CombatFormulas.DirectDamage(potMod, wdMod, apMod, detMod, tenMod, traitMod, critMod2, dhitMod2, modStateComp.BuffList);
                                                totalDamage3 = CombatFormulas.DirectDamage(potMod, wdMod, apMod, detMod, tenMod, traitMod, critMod3, dhitMod3, modStateComp.BuffList);

                                                // Inflicts damage on target's health component
                                                targHealthComp.Amount      -= totalDamage2;
                                                targHealthComp.Amount      -= totalDamage3;
                                                targHealthComp.DamageTaken += totalDamage2;
                                                targHealthComp.DamageTaken += totalDamage3;

                                                // Removes the effect of barrage
                                                modStateComp.EnablerList.Remove(barrage);
                                            }

                                            // Inflicts damage on target's health component
                                            targHealthComp.Amount      -= totalDamage1;
                                            targHealthComp.DamageTaken += totalDamage1;

                                            // Adds the damage to the log, if it exists
                                            if (log != null)
                                            {
                                                // If skill is a GCD
                                                if (skillBaseComp.Name == SkillName.HeavyShot || skillBaseComp.Name == SkillName.StraightShot || skillBaseComp.Name == SkillName.CausticBite || skillBaseComp.Name == SkillName.Stormbite || skillBaseComp.Name == SkillName.IronJaws || skillBaseComp.Name == SkillName.RefulgentArrow || skillBaseComp.Name == SkillName.VenomousBite || skillBaseComp.Name == SkillName.Windbite)
                                                {
                                                    log.Log.Rows.Add(LogActionType.GCD, timer, skillBaseComp.Name.ToString(), totalDamage1, critMod1 > 1, dhitMod1 > 1, false);

                                                    if (skillBaseComp.Type == SkillType.Weaponskill && barrage != null)
                                                    {
                                                        log.Log.Rows.Add(LogActionType.GCD, timer, skillBaseComp.Name.ToString(), totalDamage2, critMod2 > 1, dhitMod2 > 1, true);
                                                        log.Log.Rows.Add(LogActionType.GCD, timer, skillBaseComp.Name.ToString(), totalDamage3, critMod3 > 1, dhitMod3 > 1, true);
                                                    }
                                                }
                                                // Otherwise, it's an oGCD
                                                else
                                                {
                                                    log.Log.Rows.Add(LogActionType.oGCD, timer, skillBaseComp.Name.ToString(), totalDamage1, critMod1 > 1, dhitMod1 > 1, false);

                                                    if (skillBaseComp.Type == SkillType.Weaponskill && barrage != null)
                                                    {
                                                        log.Log.Rows.Add(LogActionType.oGCD, timer, skillBaseComp.Name.ToString(), totalDamage2, critMod2 > 1, dhitMod2 > 1, true);
                                                        log.Log.Rows.Add(LogActionType.oGCD, timer, skillBaseComp.Name.ToString(), totalDamage3, critMod3 > 1, dhitMod3 > 1, true);
                                                    }
                                                }
                                            }

                                            // Logic for over time effects
                                            foreach (DotEffectComponent dotEffectComp in dotEffectComponents.FindAll(x => x.Parent == skill))
                                            {
                                                DoT d = targOtComp.DotList.Find(x => x.UserSource == entity && x.Name == dotEffectComp.Name);

                                                // If there's already the same DoT applied, reapplies it
                                                if (d != null)
                                                {
                                                    d = new DoT(targComp.Target, entity, modifiersDictionary, chancesDictionary, modStateComp.BuffList, dotEffectComp.Name, dotEffectComp.Potency, dotEffectComp.Duration, timer, true);
                                                }
                                                //Otherwise, adds the dot
                                                else
                                                {
                                                    targOtComp.DotList.Add(new DoT(targComp.Target, entity, modifiersDictionary, chancesDictionary, modStateComp.BuffList, dotEffectComp.Name, dotEffectComp.Potency, dotEffectComp.Duration, timer, false));
                                                }
                                            }

                                            // Logic for straighter shot effects
                                            foreach (StraighterShotEffectComponent ssEffectComp in straighterShotEffectComponents.FindAll(x => x.Parent == skill))
                                            {
                                                // Effect is granted with a chance
                                                if ((int)(ssEffectComp.Probability * 10) > rng.Next(0, 1000))
                                                {
                                                    Enabler e = modStateComp.EnablerList.Find(x => x.User == entity && x.Name == ssEffectComp.Name);

                                                    // If there's already the same enabler applied, refresh the timer
                                                    if (e != null)
                                                    {
                                                        e.Start = timer;
                                                    }
                                                    // Otherwise, adds the enabler
                                                    else
                                                    {
                                                        modStateComp.EnablerList.Add(new Enabler(entity, ssEffectComp.Name, ssEffectComp.Duration, timer));
                                                    }
                                                }
                                            }

                                            // Logic for iron jaws effects
                                            foreach (IronJawsEffectComponent ijEffectComp in ironJawsEffectComponents.FindAll(x => x.Parent == skill))
                                            {
                                                for (int i = 0; i < targOtComp.DotList.Count; i++)
                                                {
                                                    DotEffectComponent ijDotEffectComp = ijEffectComp.DotList.Find(x => x.Name == targOtComp.DotList[i].Name);

                                                    // If the dot is present, reapplies it
                                                    if (ijDotEffectComp != null)
                                                    {
                                                        targOtComp.DotList[i] = new DoT(targComp.Target, entity, modifiersDictionary, chancesDictionary, modStateComp.BuffList, ijDotEffectComp.Name, ijDotEffectComp.Potency, ijDotEffectComp.Duration, timer, true);
                                                    }
                                                }
                                            }

                                            // Logic for song effects
                                            foreach (SongComponent songComp in songComponents.FindAll(x => x.Parent == skill))
                                            {
                                                // Logic for ending AP buff
                                                Buff apEffect = null;
                                                ModifierStateComponent brdModComp = modifierStateComponents.Find(x => x.Parent == brdComp.Parent);

                                                if (brdModComp != null)
                                                {
                                                    apEffect = brdModComp.BuffList.Find(x => x.Name == StatusName.ArmysPaeon);
                                                }

                                                if (apEffect != null)
                                                {
                                                    brdModComp.BuffDictionary[apEffect.Type] -= apEffect.Modifier;
                                                    brdModComp.BuffList.Remove(apEffect);
                                                }

                                                // Logic for resetting repertoire
                                                brdComp.Repertoire = 0;

                                                // Applying the song
                                                brdComp.Song         = songComp.Song;
                                                brdComp.SongStart    = timer;
                                                brdComp.SongDuration = songComp.Duration;
                                            }

                                            // Logic for enhanced empyreal arrow effects
                                            foreach (EnhancedEmpyrealArrowComponent eaComp in enhancedEmpyrealArrowComponents.FindAll(x => x.Parent == skill))
                                            {
                                                if (brdComp.Song != SongName.None)
                                                {
                                                    if (brdComp.Song == SongName.TheWanderersMinuet && brdComp.Repertoire < 3)
                                                    {
                                                        brdComp.Repertoire++;
                                                    }
                                                    else if (brdComp.Song == SongName.MagesBallad)
                                                    {
                                                        brdComp.Repertoire++;
                                                    }
                                                    else if (brdComp.Song == SongName.ArmysPaeon && brdComp.Repertoire < 4)
                                                    {
                                                        brdComp.Repertoire++;
                                                    }
                                                }
                                            }

                                            // Logic for consuming repertoire
                                            foreach (UsesRepertoireComponent repComp in usesRepertoireComponents.FindAll(x => x.Parent == skill))
                                            {
                                                brdComp.Repertoire = 0;
                                            }

                                            // Logic for consuming enabler
                                            foreach (UsesEnablerComponent enComp in usesEnablerComponents.FindAll(x => x.Parent == skill))
                                            {
                                                Enabler e = modStateComp.EnablerList.Find(x => x.Name == enComp.Name);

                                                if (e != null)
                                                {
                                                    modStateComp.EnablerList.Remove(e);
                                                }
                                            }
                                        }

                                        // Activates animation lock
                                        animLockComp.Start = timer;

                                        // Adjusts cooldown
                                        if (skillBaseComp.Type == SkillType.Weaponskill)
                                        {
                                            recast = CombatFormulas.SpeedRecast
                                                     (
                                                attComp.AttributesDictionary[AttributeType.SkillSpeed] + modStateComp.BuffDictionary[AttributeType.SkillSpeed],
                                                cdComp.BaseRecast,
                                                modStateComp.BuffDictionary[AttributeType.Arrow],
                                                modStateComp.BuffDictionary[AttributeType.Haste],
                                                modStateComp.BuffDictionary[AttributeType.FeyWind],
                                                modStateComp.BuffDictionary[AttributeType.SpeedType1],
                                                modStateComp.BuffDictionary[AttributeType.SpeedType2],
                                                modStateComp.BuffDictionary[AttributeType.RiddleOfFire],
                                                modStateComp.BuffDictionary[AttributeType.AstralUmbral]
                                                     );
                                        }
                                        else if (skillBaseComp.Type == SkillType.Spell)
                                        {
                                            recast = CombatFormulas.SpeedRecast
                                                     (
                                                attComp.AttributesDictionary[AttributeType.SpellSpeed] + modStateComp.BuffDictionary[AttributeType.SpellSpeed],
                                                cdComp.BaseRecast,
                                                modStateComp.BuffDictionary[AttributeType.Arrow],
                                                modStateComp.BuffDictionary[AttributeType.Haste],
                                                modStateComp.BuffDictionary[AttributeType.FeyWind],
                                                modStateComp.BuffDictionary[AttributeType.SpeedType1],
                                                modStateComp.BuffDictionary[AttributeType.SpeedType2],
                                                modStateComp.BuffDictionary[AttributeType.RiddleOfFire],
                                                modStateComp.BuffDictionary[AttributeType.AstralUmbral]
                                                     );
                                        }
                                        else
                                        {
                                            recast = cdComp.BaseRecast;
                                        }

                                        // Logic for cooldown
                                        foreach (Entity sharedSkill in cdComp.SharedCooldownList)
                                        {
                                            CooldownComponent c = cooldownComponents.Find(x => x.Parent == sharedSkill);
                                            c.Start    = timer;
                                            c.UsableAt = c.Start + recast;
                                        }

                                        // Logic for buff effects
                                        foreach (StatusEffectComponent statusComp in statusEffectComponents.FindAll(x => x.Parent == skill))
                                        {
                                            Buff b = modStateComp.BuffList.Find(x => x.UserSource == entity && x.Name == statusComp.Name);

                                            // If there's already the same buff applied, refresh the timer
                                            if (b != null)
                                            {
                                                b.Start = timer;
                                            }
                                            // Otherwise, adds the buff
                                            else
                                            {
                                                if (statusComp.Actor == ActorType.Self)
                                                {
                                                    modStateComp.BuffList.Add(new Buff(entity, entity, statusComp.Name, statusComp.Type, statusComp.Duration, timer, statusComp.Modifier, false));
                                                }
                                                else if (statusComp.Actor == ActorType.Target)
                                                {
                                                    modStateComp.BuffList.Add(new Buff(targComp.Target, entity, statusComp.Name, statusComp.Type, statusComp.Duration, timer, statusComp.Modifier, false));
                                                }
                                            }
                                        }

                                        // Logic for generic buff effects
                                        foreach (GenericStatusEffectComponent genStatusComp in genericStatusEffectComponents.FindAll(x => x.Parent == skill))
                                        {
                                            Enabler e = modStateComp.EnablerList.Find(x => x.User == entity && x.Name == genStatusComp.Name);

                                            // If there's already the same enabler applied, refresh the timer
                                            if (e != null)
                                            {
                                                e.Start = timer;
                                            }
                                            // Otherwise, adds the enabler
                                            else
                                            {
                                                modStateComp.EnablerList.Add(new Enabler(entity, genStatusComp.Name, genStatusComp.Duration, timer));
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        public void Update(decimal timer, Keyboard keyboard, LogData log)
        {
            foreach (AutoAttackComponent aaComp in autoAttackComponents)
            {
                AttributesComponent    attComp        = attributesComponents.Find(x => x.Parent == aaComp.Parent);
                ModifierStateComponent modStateComp   = modifiterStateComponents.Find(x => x.Parent == aaComp.Parent);
                BardComponent          brdComp        = bardComponents.Find(x => x.Parent == aaComp.Parent);
                TargetComponent        targComp       = targetComponents.Find(x => x.Parent == aaComp.Parent);
                HealthComponent        targHealthComp = healthComponents.Find(x => x.Parent == targComp.Target);

                // To assure autos start right away
                if (aaComp.NextAuto == 0)
                {
                    aaComp.NextAuto = timer;
                }

                // Inflict auto attack damage every X seconds, where X is the weapon delay
                if (timer == aaComp.NextAuto)
                {
                    decimal potMod  = 1;
                    decimal aaMod   = 1;
                    decimal apMod   = 1;
                    decimal detMod  = 1;
                    decimal tenMod  = 1;
                    decimal ssMod   = 1;
                    decimal critMod = 1;
                    decimal dhitMod = 1;

                    decimal critChance;
                    decimal dhitChance;

                    decimal totalDamage;

                    // Starts calculating potency modifier from base potency
                    potMod = CombatFormulas.PotencyMod(aaComp.Potency);

                    // Calculates auto attack modifier
                    aaMod = CombatFormulas.AutoAttackMod(attComp.AttributesDictionary[AttributeType.WeaponDamage], attComp.AttributesDictionary[AttributeType.WeaponDelay]);

                    // Calculates attack power modifier (every job uses str, except dex-based jobs)
                    if (brdComp.Job == Job.Ninja || brdComp.Job == Job.Bard || brdComp.Job == Job.Machinist)
                    {
                        apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Dexterity] + modStateComp.BuffDictionary[AttributeType.Dexterity]);
                    }
                    else
                    {
                        apMod = CombatFormulas.AttackPowerDamageMod(attComp.AttributesDictionary[AttributeType.Strenght] + modStateComp.BuffDictionary[AttributeType.Strenght]);
                    }

                    // Calculates determination modifier
                    detMod = CombatFormulas.DeterminationDamageMod(attComp.AttributesDictionary[AttributeType.Determination] + modStateComp.BuffDictionary[AttributeType.Determination]);

                    // Calculates tenacity modifier
                    tenMod = CombatFormulas.TenacityDamageMod(attComp.AttributesDictionary[AttributeType.Tenacity] + modStateComp.BuffDictionary[AttributeType.Tenacity]);

                    // Calculates speed modifier (even casters use sks for this)

                    ssMod = CombatFormulas.SpeedDamageMod(attComp.AttributesDictionary[AttributeType.SkillSpeed] + modStateComp.BuffDictionary[AttributeType.SkillSpeed]);

                    critChance = CombatFormulas.CriticalHitRate(attComp.AttributesDictionary[AttributeType.CriticalHit]) + modStateComp.BuffDictionary[AttributeType.CriticalHitRate];

                    dhitChance = CombatFormulas.DirectHitRate(attComp.AttributesDictionary[AttributeType.DirectHit]) + modStateComp.BuffDictionary[AttributeType.DirectHitRate];

                    // Calculates crit modifier
                    // If not critical hit, modifier is 1
                    if ((int)(critChance * 10) < rng.Next(1, 1000))
                    {
                        critMod = 1;
                    }
                    else
                    {
                        critMod = CombatFormulas.CriticalHitDamageMod(attComp.AttributesDictionary[AttributeType.CriticalHit] + modStateComp.BuffDictionary[AttributeType.CriticalHit]);
                    }

                    // Calculates dhit modifier
                    // If not direct hit, modifier is 1
                    if ((int)(dhitChance * 10) < rng.Next(1, 1000))
                    {
                        dhitMod = 1;
                    }
                    else
                    {
                        dhitMod = CombatFormulas.DirectHitDamageMod(attComp.AttributesDictionary[AttributeType.DirectHit] + modStateComp.BuffDictionary[AttributeType.DirectHit]);
                    }

                    totalDamage = CombatFormulas.AutoAttackDamage(potMod, aaMod, apMod, detMod, tenMod, 1, ssMod, critMod, dhitMod, modStateComp.BuffList);

                    // Inflicts damage on target's health component
                    targHealthComp.Amount      -= totalDamage;
                    targHealthComp.DamageTaken += totalDamage;

                    // Adds the damage to the log, if it exists
                    if (log != null)
                    {
                        log.Log.Rows.Add(LogActionType.AutoAttack, timer, "Auto attack", totalDamage, critMod > 1, dhitMod > 1, false);
                    }

                    // Sets next auto
                    aaComp.NextAuto += attComp.AttributesDictionary[AttributeType.WeaponDelay];
                }
            }
        }