Exemple #1
0
        public void Update(decimal timer, Keyboard keyboard, LogData log)
        {
            if (timer == 0)
            {
                gcdCounter = 0;
            }

            if (timer == NextGCD(heavyShotCdComp))
            {
                gcdCounter++;
            }

            // Opener:
            if (gcdCounter <= 9)
            {
                if (NextGCD(heavyShotCdComp) <= timer)
                {
                    // GCD: opener
                    switch (gcdCounter)
                    {
                    case 1:
                        UseSkill(skillControlComp, SkillName.Stormbite);
                        break;

                    case 2:
                        UseSkill(skillControlComp, SkillName.CausticBite);
                        break;

                    case 3:
                        UseSkill(skillControlComp, SkillName.StraightShot);
                        break;

                    case 4:
                        UseSkill(skillControlComp, SkillName.IronJaws);
                        break;

                    case 5:
                        UseSkill(skillControlComp, SkillName.HeavyShot);
                        break;

                    case 6:
                    case 7:
                    case 8:
                        if (IsStatusActive(modStateComponent, StatusName.StraighterShot))
                        {
                            UseSkill(skillControlComp, SkillName.RefulgentArrow);
                        }
                        else
                        {
                            UseSkill(skillControlComp, SkillName.HeavyShot);
                        }
                        break;

                    case 9:
                        UseSkill(skillControlComp, SkillName.IronJaws);
                        break;
                    }
                }
                else if (timer < NextGCD(heavyShotCdComp))
                {
                    // oGCD: opener
                    switch (gcdCounter)
                    {
                    case 1:
                        if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        else if (CooldownLeft(rsCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.RagingStrikes);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                        break;

                    case 2:
                        if (CooldownLeft(wmCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.TheWanderersMinuet);
                        }
                        else if (CooldownLeft(eaCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                        break;

                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        if (Repertoire(brdComp) == 3 && CooldownLeft(ppCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.PitchPerfect);
                        }
                        else if (IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(barrageCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Barrage);
                        }
                        else if (CooldownLeft(eaCooldownComp, timer) <= 0 && CooldownLeft(barrageCooldownComp, timer) > 0 && !IsStatusActive(modStateComponent, StatusName.Barrage) && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        else if (CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                        break;

                    case 8:
                        if (Repertoire(brdComp) == 3 && CooldownLeft(ppCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.PitchPerfect);
                        }
                        else if (CooldownLeft(eaCooldownComp, timer) <= 0 && CooldownLeft(barrageCooldownComp, timer) > 0 && !IsStatusActive(modStateComponent, StatusName.Barrage) && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        else if (CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                        break;

                    case 9:
                        if (Repertoire(brdComp) == 3 && CooldownLeft(ppCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.PitchPerfect);
                        }
                        else if (CooldownLeft(barrageCooldownComp, timer) <= 0 && !IsStatusActive(modStateComponent, StatusName.StraighterShot))
                        {
                            UseSkill(skillControlComp, SkillName.Barrage);
                        }
                        else if ((IsStatusActive(modStateComponent, StatusName.Barrage) && !IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(eaCooldownComp, timer) <= 0) || (CooldownLeft(barrageCooldownComp, timer) > 0 && NoClip(timer) && CooldownLeft(eaCooldownComp, timer) <= 0))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                        break;
                    }
                }
            }
            else
            {
                if (TimeLeftOnSong(brdComp, SongName.TheWanderersMinuet, timer) > 0)
                {
                    if (NextGCD(heavyShotCdComp) <= timer)
                    {
                        // GCD: Base structure
                        if (!IsDoTActive(targOtComp, DotName.Stormbite))
                        {
                            UseSkill(skillControlComp, SkillName.CausticBite);
                        }
                        else if (!IsDoTActive(targOtComp, DotName.CausticBite))
                        {
                            UseSkill(skillControlComp, SkillName.Stormbite);
                        }
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && (TimeLeftOnDot(targOtComp, DotName.CausticBite, timer) <= 3m || TimeLeftOnDot(targOtComp, DotName.Stormbite, timer) <= 3m))
                        {
                            UseSkill(skillControlComp, SkillName.IronJaws);
                        }
                        else if (IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(barrageCooldownComp, timer) >= 10m)
                        {
                            UseSkill(skillControlComp, SkillName.RefulgentArrow);
                        }
                        else if (!IsStatusActive(modStateComponent, StatusName.StraightShot) || TimeLeftOnStatus(modStateComponent, StatusName.StraightShot, timer) <= 5m)
                        {
                            UseSkill(skillControlComp, SkillName.StraightShot);
                        }
                        else
                        {
                            UseSkill(skillControlComp, SkillName.HeavyShot);
                        }
                    }
                    else if (timer < NextGCD(heavyShotCdComp))
                    {
                        // oGCD: Base structure

                        // Mage's Ballad
                        if (TimeLeftOnSong(brdComp, SongName.TheWanderersMinuet, timer) <= 2m && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.MagesBallad);
                        }
                        // Raging Strikes
                        else if (CooldownLeft(rsCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.RagingStrikes);
                        }
                        // Pitch Perfect
                        else if ((Repertoire(brdComp) == 3 || (IsSongActive(brdComp, SongName.TheWanderersMinuet) && TimeLeftOnSong(brdComp, SongName.TheWanderersMinuet, timer) <= 2m)) && CooldownLeft(ppCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.PitchPerfect);
                        }
                        // Barrage
                        else if ((IsStatusActive(modStateComponent, StatusName.StraighterShot) || IsStatusActive(modStateComponent, StatusName.RagingStrikes) && TimeLeftOnStatus(modStateComponent, StatusName.RagingStrikes, timer) <= 3m) && CooldownLeft(barrageCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Barrage);
                        }
                        // Bloodletter
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        // Empyreal Arrow
                        else if (IsStatusActive(modStateComponent, StatusName.RagingStrikes) && TimeLeftOnStatus(modStateComponent, StatusName.RagingStrikes, timer) <= 15m && IsStatusActive(modStateComponent, StatusName.Barrage) && CooldownLeft(eaCooldownComp, timer) <= 0 /* CAN CLIP */)
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        // Empyreal Arrow
                        else if ((IsStatusActive(modStateComponent, StatusName.RagingStrikes) && TimeLeftOnStatus(modStateComponent, StatusName.RagingStrikes, timer) > 15m) || !IsStatusActive(modStateComponent, StatusName.RagingStrikes) && CooldownLeft(eaCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        // Sidewinder
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                    }
                    else
                    {
                        ReleaseSkill(skillControlComp);
                    }
                }
                else if (TimeLeftOnSong(brdComp, SongName.MagesBallad, timer) > 0)
                {
                    if (NextGCD(heavyShotCdComp) <= timer)
                    {
                        // GCD: Base structure
                        if (!IsDoTActive(targOtComp, DotName.Stormbite))
                        {
                            UseSkill(skillControlComp, SkillName.CausticBite);
                        }
                        else if (!IsDoTActive(targOtComp, DotName.CausticBite))
                        {
                            UseSkill(skillControlComp, SkillName.Stormbite);
                        }
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && (TimeLeftOnDot(targOtComp, DotName.CausticBite, timer) <= 3m || TimeLeftOnDot(targOtComp, DotName.Stormbite, timer) <= 3m))
                        {
                            UseSkill(skillControlComp, SkillName.IronJaws);
                        }
                        else if (IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(barrageCooldownComp, timer) >= 10m)
                        {
                            UseSkill(skillControlComp, SkillName.RefulgentArrow);
                        }
                        else if (!IsStatusActive(modStateComponent, StatusName.StraightShot) || TimeLeftOnStatus(modStateComponent, StatusName.StraightShot, timer) <= 5m)
                        {
                            UseSkill(skillControlComp, SkillName.StraightShot);
                        }
                        else
                        {
                            UseSkill(skillControlComp, SkillName.HeavyShot);
                        }
                    }
                    else if (timer < NextGCD(heavyShotCdComp))
                    {
                        // oGCD: Base structure

                        // Army's Paeon
                        if (CooldownLeft(apCooldownComp, timer) <= 0 && CooldownLeft(wmCooldownComp, timer) <= 20 && CooldownLeft(mbCooldownComp, timer) <= 50 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.ArmysPaeon);
                        }
                        // Bloodletter
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        // Empyreal Arrow
                        else if (CooldownLeft(blCooldownComp, timer) > 3m && CooldownLeft(eaCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        // Sidewinder
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                    }
                    else
                    {
                        ReleaseSkill(skillControlComp);
                    }
                }
                else if (TimeLeftOnSong(brdComp, SongName.ArmysPaeon, timer) > 0)
                {
                    if (NextGCD(heavyShotCdComp) <= timer)
                    {
                        // GCD: Base structure
                        if (!IsDoTActive(targOtComp, DotName.Stormbite))
                        {
                            UseSkill(skillControlComp, SkillName.CausticBite);
                        }
                        else if (!IsDoTActive(targOtComp, DotName.CausticBite))
                        {
                            UseSkill(skillControlComp, SkillName.Stormbite);
                        }
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && (TimeLeftOnDot(targOtComp, DotName.CausticBite, timer) <= 3m || TimeLeftOnDot(targOtComp, DotName.Stormbite, timer) <= 3m))
                        {
                            UseSkill(skillControlComp, SkillName.IronJaws);
                        }
                        else if (IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(barrageCooldownComp, timer) >= 10m)
                        {
                            UseSkill(skillControlComp, SkillName.RefulgentArrow);
                        }
                        else if (!IsStatusActive(modStateComponent, StatusName.StraightShot) || TimeLeftOnStatus(modStateComponent, StatusName.StraightShot, timer) <= 5m || ((TimeLeftOnStatus(modStateComponent, StatusName.StraightShot, timer) - CooldownLeft(rsCooldownComp, timer) - 20m) <= ((NextGCD(heavyShotCdComp) - timer + Constants.AnimationLock)) && CooldownLeft(rsCooldownComp, timer) <= ((NextGCD(heavyShotCdComp) - timer + Constants.AnimationLock)) && (CooldownLeft(wmCooldownComp, timer) <= ((NextGCD(heavyShotCdComp) - timer + Constants.AnimationLock)) && CooldownLeft(mbCooldownComp, timer) <= 30 + ((NextGCD(heavyShotCdComp) - timer + Constants.AnimationLock)) && CooldownLeft(apCooldownComp, timer) <= 60 + ((NextGCD(heavyShotCdComp) - timer + Constants.AnimationLock)))))
                        {
                            UseSkill(skillControlComp, SkillName.StraightShot);
                        }
                        else
                        {
                            UseSkill(skillControlComp, SkillName.HeavyShot);
                        }
                    }
                    else if (timer < NextGCD(heavyShotCdComp))
                    {
                        // oGCD: Base structure

                        // Wanderer's Minuet
                        if (CooldownLeft(wmCooldownComp, timer) <= 0m && CooldownLeft(mbCooldownComp, timer) <= 30 && CooldownLeft(apCooldownComp, timer) <= 60 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.TheWanderersMinuet);
                        }
                        // Bloodletter
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        // Empyreal Arrow
                        else if (CooldownLeft(blCooldownComp, timer) > 3m && CooldownLeft(eaCooldownComp, timer) <= 0 && NoClip(timer) && TimeLeftOnSong(brdComp, SongName.ArmysPaeon, timer) > 15)
                        {
                            UseSkill(skillControlComp, SkillName.EmpyrealArrow);
                        }
                        // Sidewinder
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                    }
                    else
                    {
                        ReleaseSkill(skillControlComp);
                    }
                }
                else
                {
                    if (NextGCD(heavyShotCdComp) <= timer)
                    {
                        // GCD: Base structure
                        if (!IsDoTActive(targOtComp, DotName.Stormbite))
                        {
                            UseSkill(skillControlComp, SkillName.CausticBite);
                        }
                        else if (!IsDoTActive(targOtComp, DotName.CausticBite))
                        {
                            UseSkill(skillControlComp, SkillName.Stormbite);
                        }
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && (TimeLeftOnDot(targOtComp, DotName.CausticBite, timer) <= 3m || TimeLeftOnDot(targOtComp, DotName.Stormbite, timer) <= 3m))
                        {
                            UseSkill(skillControlComp, SkillName.IronJaws);
                        }
                        else if (IsStatusActive(modStateComponent, StatusName.StraighterShot) && CooldownLeft(barrageCooldownComp, timer) >= 10m)
                        {
                            UseSkill(skillControlComp, SkillName.RefulgentArrow);
                        }
                        else if (!IsStatusActive(modStateComponent, StatusName.StraightShot) || TimeLeftOnStatus(modStateComponent, StatusName.StraightShot, timer) <= 5m)
                        {
                            UseSkill(skillControlComp, SkillName.StraightShot);
                        }
                        else
                        {
                            UseSkill(skillControlComp, SkillName.HeavyShot);
                        }
                    }
                    else if (timer < NextGCD(heavyShotCdComp))
                    {
                        // oGCD: Base structure
                        // The Wanderer's Minuet
                        if (IsSongActive(brdComp, SongName.None) && CooldownLeft(wmCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.TheWanderersMinuet);
                        }
                        // Mage's Ballad
                        else if (IsSongActive(brdComp, SongName.None) && CooldownLeft(mbCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.MagesBallad);
                        }
                        // Army's Paeon
                        else if (IsSongActive(brdComp, SongName.None) && CooldownLeft(apCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.ArmysPaeon);
                        }
                        // Bloodletter
                        else if (CooldownLeft(blCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Bloodletter);
                        }
                        // Sidewinder
                        else if (IsDoTActive(targOtComp, DotName.CausticBite) && IsDoTActive(targOtComp, DotName.Stormbite) && CooldownLeft(swCooldownComp, timer) <= 0 && NoClip(timer))
                        {
                            UseSkill(skillControlComp, SkillName.Sidewinder);
                        }
                        else
                        {
                            ReleaseSkill(skillControlComp);
                        }
                    }
                    else
                    {
                        ReleaseSkill(skillControlComp);
                    }
                }
            }
        }
Exemple #2
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;
                        }
                    }
                }
            }
        }
Exemple #3
0
 public void Update(decimal timer, Keyboard keyboard, LogData log)
 {
     if (!(timer <= NextGCD(heavyShotCdComp) - Constants.AnimationLock) || NextGCD(heavyShotCdComp) <= 0m)
     {
         if (targOtComp.DotList.Find(x => x.Name == DotName.Stormbite && x.UserSource == player && x.Duration - timer + x.Start < 4m) != null || targOtComp.DotList.Find(x => x.Name == DotName.CausticBite && x.UserSource == player && x.Duration - timer + x.Start < 4m) != null)
         {
             UseKey(keyboard, Keys.Num5);
         }
         else if (modStateComponent.EnablerList.Find(x => x.Name == StatusName.StraighterShot) != null)
         {
             UseKey(keyboard, Keys.F3);
         }
         else if (modStateComponent.BuffList.Find(x => x.IsActive && x.Name == StatusName.StraightShot) == null)
         {
             UseKey(keyboard, Keys.Num2);
         }
         else if (targOtComp.DotList.Find(x => x.IsActive == true && x.Name == DotName.Stormbite && x.UserSource == player) == null)
         {
             UseKey(keyboard, Keys.Num3);
         }
         else if (targOtComp.DotList.Find(x => x.IsActive == true && x.Name == DotName.CausticBite && x.UserSource == player) == null)
         {
             UseKey(keyboard, Keys.Num4);
         }
         else
         {
             UseKey(keyboard, Keys.Num1);
         }
     }
     else
     {
         if (brdComp.Song != SongName.TheWanderersMinuet && wmCooldownComp.UsableAt <= timer && apCooldownComp.UsableAt - timer <= 60m && onOpener == false)
         {
             UseKey(keyboard, Keys.M1);
         }
         else if (brdComp.Song != SongName.MagesBallad && mbCooldownComp.UsableAt <= timer && wmCooldownComp.UsableAt - timer <= 50m && onOpener == false)
         {
             UseKey(keyboard, Keys.M2);
         }
         else if (brdComp.Song != SongName.ArmysPaeon && apCooldownComp.UsableAt <= timer && mbCooldownComp.UsableAt - timer <= 50m && wmCooldownComp.UsableAt - timer <= 20m && onOpener == false)
         {
             UseKey(keyboard, Keys.M3);
         }
         else if ((brdComp.Song == SongName.TheWanderersMinuet && brdComp.Repertoire == 3 && ppCooldownComp.UsableAt <= timer) || (brdComp.Song == SongName.TheWanderersMinuet && timer - wmCooldownComp.Start >= 28m && ppCooldownComp.UsableAt <= timer))
         {
             UseKey(keyboard, Keys.T);
         }
         else if (blCooldownComp.UsableAt <= timer)
         {
             UseKey(keyboard, Keys.R);
         }
         else if (rsCooldownComp.UsableAt <= timer)
         {
             UseKey(keyboard, Keys.F1);
         }
         else if (brdComp.Song != SongName.TheWanderersMinuet && wmCooldownComp.UsableAt <= timer && apCooldownComp.UsableAt - timer <= 60m && onOpener == true)
         {
             onOpener = false;
             UseKey(keyboard, Keys.M1);
         }
         else if (modStateComponent.EnablerList.Find(x => x.Name == StatusName.StraighterShot) != null && barrageCooldownComp.UsableAt <= timer && !(targOtComp.DotList.Find(x => x.Name == DotName.Stormbite && x.Duration - timer + x.Start < 4m) != null || targOtComp.DotList.Find(x => x.Name == DotName.CausticBite && x.Duration - timer + x.Start < 4m) != null))
         {
             UseKey(keyboard, Keys.F2);
         }
         else if (!(modStateComponent.EnablerList.Find(x => x.Name == StatusName.StraighterShot) != null && modStateComponent.EnablerList.Find(x => x.Name == StatusName.Barrage) != null) && eaCooldownComp.UsableAt <= timer)
         {
             UseKey(keyboard, Keys.Num6);
         }
         else if ((targOtComp.DotList.Find(x => x.IsActive == true && x.Name == DotName.Stormbite && x.UserSource == player) != null && targOtComp.DotList.Find(x => x.IsActive == true && x.Name == DotName.CausticBite && x.UserSource == player) != null) && swCooldownComp.UsableAt <= timer)
         {
             UseKey(keyboard, Keys.Num7);
         }
     }
 }
Exemple #4
0
        public void Update(decimal timer, Keyboard keyboard, LogData log)
        {
            foreach (OverTimeStateComponent otStateComp in overtimeStateComponents)
            {
                // Gets the HealthComponent of the entity inflicted by the over time effect
                HealthComponent healthComp = healthComponents.Find(x => x.Parent == otStateComp.Parent);

                foreach (DoT dot in otStateComp.DotList)
                {
                    // Remove the DoT if it's expired
                    if (timer - dot.Start > dot.Duration)
                    {
                        toBeRemoved.Add(dot);
                    }
                    else
                    {
                        // Activates if not active
                        if (!dot.IsActive)
                        {
                            dot.IsActive = true;
                            dot.LastTick = timer;
                        }
                        else
                        {
                            // Executes the damage
                            if (((timer - otStateComp.Offset) % (3m) == 0) && (timer - dot.LastTick >= 3m))
                            {
                                decimal critMod = 1;
                                decimal dhitMod = 1;

                                bool hasCrit = false;

                                if ((int)(dot.UsersChancesDictionary[AttributeType.CriticalHitRate] * 10) > rng.Next(0, 1000))
                                {
                                    critMod = dot.UsersModifiersDictionary[DamageModifierType.CriticalModifier];

                                    // For repertoire
                                    hasCrit = true;
                                }

                                if ((int)(dot.UsersChancesDictionary[AttributeType.DirectHitRate] * 10) > rng.Next(0, 1000))
                                {
                                    dhitMod = dot.UsersModifiersDictionary[DamageModifierType.DirectModifier];
                                }

                                decimal dotTick = CombatFormulas.DoTDamage
                                                  (
                                    CombatFormulas.PotencyMod(dot.Potency),
                                    dot.UsersModifiersDictionary[DamageModifierType.WeaponDamageModifier],
                                    dot.UsersModifiersDictionary[DamageModifierType.AttackPowerModifier],
                                    dot.UsersModifiersDictionary[DamageModifierType.DeterminationModifier],
                                    dot.UsersModifiersDictionary[DamageModifierType.TenacityModifier],
                                    dot.UsersModifiersDictionary[DamageModifierType.TraitModifier],
                                    dot.UsersModifiersDictionary[DamageModifierType.SpeedModifier],
                                    critMod,
                                    dhitMod,
                                    dot.UsersBuffList
                                                  );
                                healthComp.Amount      -= dotTick;
                                healthComp.DamageTaken += dotTick;

                                // Adds the damage to the log, if it exists
                                if (log != null)
                                {
                                    log.Log.Rows.Add(LogActionType.DoT, timer, dot.Name.ToString(), dotTick, critMod > 1, dhitMod > 1, false);
                                }

                                dot.LastTick = timer;

                                // Handles repertoire
                                if ((dot.Name == DotName.CausticBite || dot.Name == DotName.Stormbite) && hasCrit)
                                {
                                    // Gets the BardComponent of the entity that applied the over time effect
                                    foreach (BardComponent brdComp in bardComponents.FindAll(x => x.Parent == dot.UserSource))
                                    {
                                        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++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                foreach (DoT dot in toBeRemoved)
                {
                    otStateComp.DotList.Remove(dot);
                }
                toBeRemoved = new List <DoT>();
            }
        }
        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];
                }
            }
        }
Exemple #6
0
        static void Main(string[] args)
        {
            while (true)
            {
                LogData       logData     = new LogData();
                DataTable     dpsTable    = new DataTable("DPS");
                List <string> ariyalaSets = new List <string>();

                int     numberOfSets     = 0;
                int     numberOfRuns     = 0;
                decimal simulationTarget = 0;
                List <AttributesDictionary> listOfAttDicts = new List <AttributesDictionary>();
                AttributesDictionary        singleAttDict  = new AttributesDictionary();

                bool validSetNumber        = true;
                bool validCode             = true;
                bool validRunsNumber       = true;
                bool validSimulationTarget = true;
                SimulationParameters simulationParameter = SimulationParameters.Invalid;
                SimulationType       simulationType      = SimulationType.Invalid;

                // Asks for type of simulation
                do
                {
                    Console.WriteLine("\nEnter 'V' for a single verbose run, or 'M' for multiple runs:");

                    try
                    {
                        char typeChar = Console.ReadLine()[0];

                        if (typeChar == 'V')
                        {
                            simulationType = SimulationType.Verbose;
                        }
                        else if (typeChar == 'M')
                        {
                            simulationType = SimulationType.Multiple;
                        }
                        else
                        {
                            throw new InvalidDataException("Invalid type of simulation.");
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        simulationType = SimulationType.Invalid;
                    }
                }while (simulationType == SimulationType.Invalid);

                // Multiple simulation
                if (simulationType == SimulationType.Multiple)
                {
                    // Asks for number of gearsets
                    do
                    {
                        Console.WriteLine("\nInput the number of gearsets:");

                        try
                        {
                            int.TryParse(Console.ReadLine(), out numberOfSets);
                            if (numberOfSets <= 0)
                            {
                                throw new InvalidDataException("Number must be greater than zero.");
                            }
                            validSetNumber = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            validSetNumber = false;
                        }
                    }while (!validSetNumber);

                    // Instantiates the HTML scraper for Ariyala
                    AriyalaScraper scraper = new AriyalaScraper();

                    // Iterates over each gearset
                    for (int i = 0; i < numberOfSets; i++)
                    {
                        do
                        {
                            Console.WriteLine("\nEnter the Ariyala link or code #{0}:", i + 1);

                            try
                            {
                                string ariyalaCode = Console.ReadLine();
                                listOfAttDicts.Add(scraper.GetAriyalaSet(ariyalaCode));
                                validCode = true;
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                validCode = false;
                            }
                        }while (!validCode);
                    }

                    // Closes the browser
                    scraper.Dispose();

                    // Asks for number of simulations
                    do
                    {
                        Console.WriteLine("\nInput the number of simulations:");

                        try
                        {
                            int.TryParse(Console.ReadLine(), out numberOfRuns);
                            if (numberOfRuns <= 0)
                            {
                                throw new InvalidDataException("Number must be greater than zero.");
                            }
                            validRunsNumber = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            validRunsNumber = false;
                        }
                    }while (!validRunsNumber);

                    // Asks for type of simulation
                    do
                    {
                        Console.WriteLine("\nEnter 'D' for damage target, or 'T' for time target:");

                        try
                        {
                            char targetChar = Console.ReadLine()[0];

                            if (targetChar == 'D')
                            {
                                simulationParameter = SimulationParameters.DamageTarget;
                            }
                            else if (targetChar == 'T')
                            {
                                simulationParameter = SimulationParameters.TimeTarget;
                            }
                            else
                            {
                                throw new InvalidDataException("Invalid type of simulation.");
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            simulationParameter = SimulationParameters.Invalid;
                        }
                    }while (simulationParameter == SimulationParameters.Invalid);

                    // Asks for target of simulation (seconds or total damage)
                    do
                    {
                        try
                        {
                            if (simulationParameter == SimulationParameters.DamageTarget)
                            {
                                Console.WriteLine("\nInput the  total damage target:");
                                decimal.TryParse(Console.ReadLine(), out simulationTarget);
                            }
                            else if (simulationParameter == SimulationParameters.TimeTarget)
                            {
                                Console.WriteLine("\nInput the time target (in seconds):");
                                decimal.TryParse(Console.ReadLine(), out simulationTarget);
                            }

                            if (simulationTarget <= 0)
                            {
                                throw new InvalidDataException("Value must be greater than zero.");
                            }
                            validSimulationTarget = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            validSimulationTarget = false;
                        }
                    }while (!validSimulationTarget);

                    // Main loop
                    for (int k = 0; k < numberOfSets; k++)
                    {
                        List <decimal> results = new List <decimal>();
                        Engine         engine  = new Engine(listOfAttDicts[k]);
                        Stopwatch      timer   = new Stopwatch();

                        // Simulates each gearset
                        timer.Start();
                        for (int i = 0; i < numberOfRuns; i++)
                        {
                            results.Add(engine.Simulate(simulationParameter, simulationTarget));
                            engine.Reinitialize();
                        }
                        timer.Stop();


                        Console.WriteLine("\nAverage DPS: {0:0.00}\nMax: {1:0.00}\nMin: {2:0.00}", results.Average(), results.Max(), results.Min());

                        Console.WriteLine("\nSimulation time: {0}", timer.ElapsedMilliseconds.MilliToSeconds());

                        // Writes to CSV
                        Console.WriteLine("\nWriting to CSV.");
                        StreamWriter stream    = new StreamWriter(Environment.CurrentDirectory + k.ToString() + @".csv");
                        CsvWriter    csvWriter = new CsvWriter(stream);

                        timer.Restart();
                        foreach (decimal d in results)
                        {
                            csvWriter.WriteRecord((double)d);
                            csvWriter.NextRecord();
                        }
                        timer.Stop();

                        Console.WriteLine("\nWrite time: {0}", timer.ElapsedMilliseconds.MilliToSeconds());

                        stream.Dispose();
                    }
                }

                // Single verbose simulation
                else
                {
                    // Instantiates the HTML scraper for Ariyala
                    AriyalaScraper scraper = new AriyalaScraper();

                    // Asks for an Ariyala code
                    do
                    {
                        Console.WriteLine("\nEnter the Ariyala link or code:");

                        try
                        {
                            string ariyalaCode = Console.ReadLine();
                            singleAttDict = scraper.GetAriyalaSet(ariyalaCode);
                            validCode     = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            validCode = false;
                        }
                    }while (!validCode);

                    // Closes the browser
                    scraper.Dispose();

                    // Asks for type of simulation
                    do
                    {
                        Console.WriteLine("\nEnter 'D' for damage target, or 'T' for time target:");

                        try
                        {
                            char targetChar = Console.ReadLine()[0];

                            if (targetChar == 'D')
                            {
                                simulationParameter = SimulationParameters.DamageTarget;
                            }
                            else if (targetChar == 'T')
                            {
                                simulationParameter = SimulationParameters.TimeTarget;
                            }
                            else
                            {
                                throw new InvalidDataException("Invalid type of simulation.");
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            simulationParameter = SimulationParameters.Invalid;
                        }
                    }while (simulationParameter == SimulationParameters.Invalid);

                    // Asks for target of simulation (seconds or total damage)
                    do
                    {
                        try
                        {
                            if (simulationParameter == SimulationParameters.DamageTarget)
                            {
                                Console.WriteLine("\nInput the  total damage target:");
                                decimal.TryParse(Console.ReadLine(), out simulationTarget);
                            }
                            else if (simulationParameter == SimulationParameters.TimeTarget)
                            {
                                Console.WriteLine("\nInput the time target (in seconds):");
                                decimal.TryParse(Console.ReadLine(), out simulationTarget);
                            }

                            if (simulationTarget <= 0)
                            {
                                throw new InvalidDataException("Value must be greater than zero.");
                            }
                            validSimulationTarget = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            validSimulationTarget = false;
                        }
                    }while (!validSimulationTarget);

                    // Main loop

                    decimal   result = 0;
                    Engine    engine = new Engine(singleAttDict);
                    Stopwatch timer  = new Stopwatch();


                    timer.Start();

                    result = engine.Simulate(simulationParameter, simulationTarget, logData);
                    engine.Reinitialize();

                    timer.Stop();

                    List <string> logStrings = logData.GetLog();

                    foreach (string s in logStrings)
                    {
                        Console.Write(s);
                    }

                    Console.WriteLine("\nDPS: {0:0.00}", result);

                    Console.WriteLine("\nSimulation time: {0}", timer.ElapsedMilliseconds.MilliToSeconds());
                }
            }
        }