Пример #1
0
        public EngineAction Run(SongConfig Config)
        {
            EngineAction actionResult = new EngineAction()
            {
                Target = Target.Me
            };

            PL_BRDCount = PL.Player.GetPlayerInfo().Buffs.Where(b => b == 195 || b == 196 || b == 197 || b == 198 || b == 199 || b == 200 || b == 201 || b == 214 || b == 215 || b == 216 || b == 218 || b == 219 || b == 222).Count();

            if (Config.SingingEnabled && PL.Player.Status != 33)
            {
                int songs_currently_up = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == 197 || b == 198 || b == 195 || b == 199 || b == 200 || b == 215 || b == 196 || b == 214 || b == 216 || b == 218 || b == 222).Count();

                // TODO: Add support for multiple JAs per cast, or else this will never work.
                // For now we just return the action with only the ability in it.
                // ie. If N + T were up, this would return once with Troub, then next cycle return Night,
                // then finally return the song cast.
                if (Config.TroubadourEnabled && PL.AbilityAvailable(Ability.Troubadour) && songs_currently_up == 0)
                {
                    actionResult.JobAbility = Ability.Troubadour;
                    return(actionResult);
                }
                else if (Config.NightingaleEnabled && PL.AbilityAvailable(Ability.Nightingale) && songs_currently_up == 0)
                {
                    actionResult.JobAbility = Ability.Nightingale;
                    return(actionResult);
                }

                SongData song_1 = SongInfo.Where(c => c.song_position == Config.Song1).FirstOrDefault();
                SongData song_2 = SongInfo.Where(c => c.song_position == Config.Song2).FirstOrDefault();
                SongData song_3 = SongInfo.Where(c => c.song_position == Config.Song3).FirstOrDefault();
                SongData song_4 = SongInfo.Where(c => c.song_position == Config.Song4).FirstOrDefault();

                SongData dummy1_song = SongInfo.Where(c => c.song_position == Config.Dummy1).FirstOrDefault();
                SongData dummy2_song = SongInfo.Where(c => c.song_position == Config.Dummy2).FirstOrDefault();

                // Check the distance of the Monitored player
                int Monitoreddistance = 50;


                XiEntity monitoredTarget = PL.Entity.GetEntity((int)Monitored.Player.TargetID);
                Monitoreddistance = (int)monitoredTarget.Distance;

                int Songs_Possible = 0;

                if (song_1.song_name.ToLower() != "blank")
                {
                    Songs_Possible++;
                }
                if (song_2.song_name.ToLower() != "blank")
                {
                    Songs_Possible++;
                }
                if (dummy1_song != null && dummy1_song.song_name.ToLower() != "blank")
                {
                    Songs_Possible++;
                }
                if (dummy2_song != null && dummy2_song.song_name.ToLower() != "blank")
                {
                    Songs_Possible++;
                }

                // List to make it easy to check how many of each buff is needed.
                List <int> SongDataMax = new List <int> {
                    song_1.buff_id, song_2.buff_id, song_3.buff_id, song_4.buff_id
                };

                // Check Whether e have the songs Currently Up
                int count1_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == song_1.buff_id).Count();
                int count2_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == song_2.buff_id).Count();
                int count3_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == dummy1_song.buff_id).Count();
                int count4_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == song_3.buff_id).Count();
                int count5_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == dummy2_song.buff_id).Count();
                int count6_type = PL.Player.GetPlayerInfo().Buffs.Where(b => b == song_4.buff_id).Count();

                int MON_count1_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == song_1.buff_id).Count();
                int MON_count2_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == song_2.buff_id).Count();
                int MON_count3_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == dummy1_song.buff_id).Count();
                int MON_count4_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == song_3.buff_id).Count();
                int MON_count5_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == dummy2_song.buff_id).Count();
                int MON_count6_type = Monitored.Player.GetPlayerInfo().Buffs.Where(b => b == song_4.buff_id).Count();


                if (ForceSongRecast == true)
                {
                    song_casting = 0; ForceSongRecast = false;
                }


                // SONG NUMBER #4
                if (song_casting == 3 && PL_BRDCount >= 3 && song_4.song_name.ToLower() != "blank" && count6_type < SongDataMax.Where(c => c == song_4.buff_id).Count() && Last_Song_Cast != song_4.song_name)
                {
                    if (PL_BRDCount == 3)
                    {
                        if (PL.SpellAvailable(dummy2_song.song_name))
                        {
                            actionResult.Spell = dummy2_song.song_name;
                        }
                    }
                    else
                    {
                        if (PL.SpellAvailable(song_4.song_name))
                        {
                            actionResult.Spell = song_4.song_name;

                            Last_Song_Cast         = song_4.song_name;
                            Last_SongCast_Timer[0] = DateTime.Now;
                            playerSong4[0]         = DateTime.Now;
                            song_casting           = 0;
                        }
                    }
                }
                else if (song_casting == 3 && song_4.song_name.ToLower() != "blank" && count6_type >= SongDataMax.Where(c => c == song_4.buff_id).Count())
                {
                    song_casting = 0;
                }


                // SONG NUMBER #3
                else if (song_casting == 2 && PL_BRDCount >= 2 && song_3.song_name.ToLower() != "blank" && count4_type < SongDataMax.Where(c => c == song_3.buff_id).Count() && Last_Song_Cast != song_3.song_name)
                {
                    if (PL_BRDCount == 2)
                    {
                        if (PL.SpellAvailable(dummy1_song.song_name))
                        {
                            actionResult.Spell = dummy1_song.song_name;
                        }
                    }
                    else
                    {
                        if (PL.SpellAvailable(song_3.song_name))
                        {
                            actionResult.Spell = song_3.song_name;

                            Last_Song_Cast         = song_3.song_name;
                            Last_SongCast_Timer[0] = DateTime.Now;
                            playerSong3[0]         = DateTime.Now;
                            song_casting           = 3;
                        }
                    }
                }
                else if (song_casting == 2 && song_3.song_name.ToLower() != "blank" && count4_type >= SongDataMax.Where(c => c == song_3.buff_id).Count())
                {
                    song_casting = 3;
                }


                // SONG NUMBER #2
                else if (song_casting == 1 && song_2.song_name.ToLower() != "blank" && count2_type < SongDataMax.Where(c => c == song_2.buff_id).Count() && Last_Song_Cast != song_4.song_name)
                {
                    if (PL.SpellAvailable(song_2.song_name))
                    {
                        actionResult.Spell = song_2.song_name;

                        Last_Song_Cast         = song_2.song_name;
                        Last_SongCast_Timer[0] = DateTime.Now;
                        playerSong2[0]         = DateTime.Now;
                        song_casting           = 2;
                    }
                }
                else if (song_casting == 1 && song_2.song_name.ToLower() != "blank" && count2_type >= SongDataMax.Where(c => c == song_2.buff_id).Count())
                {
                    song_casting = 2;
                }

                // SONG NUMBER #1
                else if ((song_casting == 0) && song_1.song_name.ToLower() != "blank" && count1_type < SongDataMax.Where(c => c == song_1.buff_id).Count() && Last_Song_Cast != song_4.song_name)
                {
                    if (PL.SpellAvailable(song_1.song_name))
                    {
                        actionResult.Spell = song_1.song_name;

                        Last_Song_Cast         = song_1.song_name;
                        Last_SongCast_Timer[0] = DateTime.Now;
                        playerSong1[0]         = DateTime.Now;
                        song_casting           = 1;
                    }
                }
                else if (song_casting == 0 && song_2.song_name.ToLower() != "blank" && count1_type >= SongDataMax.Where(c => c == song_1.buff_id).Count())
                {
                    song_casting = 1;
                }


                // ONCE ALL SONGS HAVE BEEN CAST ONLY RECAST THEM WHEN THEY MEET THE THRESHOLD SET ON SONG RECAST AND BLOCK IF IT'S SET AT LAUNCH DEFAULTS
                if (playerSong1[0] != DefaultTime && playerSong1_Span[0].Minutes >= Config.SongRecastMinutes)
                {
                    if ((Config.SingOnlyWhenNear && Monitoreddistance < 10) || Config.SingOnlyWhenNear == false)
                    {
                        if (PL.SpellAvailable(song_1.song_name))
                        {
                            actionResult.Spell = song_1.song_name;

                            playerSong1[0] = DateTime.Now;
                            song_casting   = 0;
                        }
                    }
                }
                else if (playerSong2[0] != DefaultTime && playerSong2_Span[0].Minutes >= Config.SongRecastMinutes)
                {
                    if ((Config.SingOnlyWhenNear && Monitoreddistance < 10) || Config.SingOnlyWhenNear == false)
                    {
                        if (PL.SpellAvailable(song_2.song_name))
                        {
                            actionResult.Spell = song_2.song_name;

                            playerSong2[0] = DateTime.Now;
                            song_casting   = 0;
                        }
                    }
                }
                else if (playerSong3[0] != DefaultTime && playerSong3_Span[0].Minutes >= Config.SongRecastMinutes)
                {
                    if ((Config.SingOnlyWhenNear && Monitoreddistance < 10) || Config.SingOnlyWhenNear == false)
                    {
                        if (PL.SpellAvailable(song_3.song_name))
                        {
                            actionResult.Spell = song_3.song_name;
                            playerSong3[0]     = DateTime.Now;
                            song_casting       = 0;
                        }
                    }
                }
                else if (playerSong4[0] != DefaultTime && playerSong4_Span[0].Minutes >= Config.SongRecastMinutes)
                {
                    if ((Config.SingOnlyWhenNear && Monitoreddistance < 10) || Config.SingOnlyWhenNear == false)
                    {
                        if (PL.SpellAvailable(song_4.song_name))
                        {
                            actionResult.Spell = song_4.song_name;
                            playerSong4[0]     = DateTime.Now;
                            song_casting       = 0;
                        }
                    }
                }
            }

            return(actionResult);
        }
Пример #2
0
        public EngineAction Run(PLConfig Config)
        {
            // FIRST IF YOU ARE SILENCED OR DOOMED ATTEMPT REMOVAL NOW
            if (PL.HasStatus(StatusEffect.Silence) && Config.PLSilenceItemEnabled)
            {
                var plSilenceItem = Items.SilenceRemoval[Config.PLSilenceItem];

                // Check to make sure we have echo drops
                if (PL.GetInventoryItemCount(PL.GetItemId(plSilenceItem)) > 0 || PL.GetTempItemCount(PL.GetItemId(plSilenceItem)) > 0)
                {
                    return(new EngineAction
                    {
                        Item = plSilenceItem
                    });
                }
            }
            else if (PL.HasStatus(StatusEffect.Doom) && Config.PLDoomItemEnabled)
            {
                var plDoomItem = Items.DoomRemoval[Config.PLDoomItem];

                // Check to make sure we have holy water
                if (PL.GetInventoryItemCount(PL.GetItemId(plDoomItem)) > 0 || PL.GetTempItemCount(PL.GetItemId(plDoomItem)) > 0)
                {
                    return(new EngineAction
                    {
                        Item = plDoomItem
                    });
                }
            }

            else if (Config.DivineSeal && PL.Player.MPP <= 11 && PL.AbilityAvailable(Ability.DivineSeal) && !PL.Player.Buffs.Contains((short)StatusEffect.Weakness))
            {
                return(new EngineAction
                {
                    Target = Target.Me,
                    JobAbility = Ability.DivineSeal
                });
            }
            else if (Config.Convert && (PL.Player.MP <= Config.ConvertMP) && PL.AbilityAvailable(Ability.Convert) && !PL.Player.Buffs.Contains((short)StatusEffect.Weakness))
            {
                return(new EngineAction
                {
                    Target = Target.Me,
                    JobAbility = Ability.Convert
                });
            }

            if (PL.Player.MP <= Config.MinCastingMP && PL.Player.MP != 0)
            {
                if (Config.LowMPEnabled && !LowMP && !Config.HealLowMPEnabled)
                {
                    PL.ThirdParty.SendString("/tell " + Monitored.Player.Name + " MP is low!");
                }

                LowMP = true;
            }
            if (PL.Player.MP > Config.MinCastingMP && PL.Player.MP != 0)
            {
                if (Config.LowMPEnabled && LowMP && !Config.HealLowMPEnabled)
                {
                    PL.ThirdParty.SendString("/tell " + Monitored.Player.Name + " MP OK!");
                }

                LowMP = false;
            }

            if (Config.HealLowMPEnabled && PL.Player.MP <= Config.HealMPThreshold && PL.Player.Status == 0)
            {
                if (Config.LowMPEnabled && !LowMP)
                {
                    PL.ThirdParty.SendString("/tell " + Monitored.Player.Name + " MP is seriously low, /healing.");
                }

                LowMP = true;

                return(new EngineAction
                {
                    CustomAction = "/heal"
                });
            }
            else if (Config.StandMPEnabled && PL.Player.MPP >= Config.StandMPThreshold && PL.Player.Status == 33)
            {
                if (Config.LowMPEnabled && !LowMP)
                {
                    PL.ThirdParty.SendString("/tell " + Monitored.Player.Name + " MP has recovered.");
                }

                LowMP = false;

                return(new EngineAction
                {
                    CustomAction = "/heal"
                });
            }

            if (Config.AfflatusSolaceEnabled && (!PL.HasStatus(StatusEffect.Afflatus_Solace)) && PL.AbilityAvailable(Ability.AfflatusSolace))
            {
                return(new EngineAction {
                    JobAbility = Ability.AfflatusSolace
                });
            }

            if (Config.AfflatusMiseryEnabled && (!PL.HasStatus(StatusEffect.Afflatus_Misery)) && PL.AbilityAvailable(Ability.AfflatusMisery))
            {
                return(new EngineAction {
                    JobAbility = Ability.AfflatusMisery
                });
            }

            if (Config.Composure && (!PL.HasStatus(StatusEffect.Composure)) && PL.AbilityAvailable(Ability.Composure))
            {
                return(new EngineAction
                {
                    JobAbility = Ability.Composure
                });
            }

            if (Config.LightArts && (!PL.HasStatus(StatusEffect.Light_Arts)) && (!PL.HasStatus(StatusEffect.Addendum_White)) && PL.AbilityAvailable(Ability.LightArts))
            {
                return(new EngineAction
                {
                    JobAbility = Ability.LightArts
                });
            }

            if (Config.AddendumWhite && (!PL.HasStatus(StatusEffect.Addendum_White)) && PL.HasStatus(StatusEffect.Light_Arts) && PL.CurrentSCHCharges() > 0)
            {
                return(new EngineAction
                {
                    JobAbility = Ability.AddendumWhite
                });
            }

            if (Config.DarkArts && (!PL.HasStatus(StatusEffect.Dark_Arts)) && (!PL.HasStatus(StatusEffect.Addendum_Black)) && PL.AbilityAvailable(Ability.DarkArts))
            {
                return(new EngineAction
                {
                    JobAbility = Ability.DarkArts
                });
            }

            if (Config.AddendumBlack && PL.HasStatus(StatusEffect.Dark_Arts) && (!PL.HasStatus(StatusEffect.Addendum_Black)) && PL.CurrentSCHCharges() > 0)
            {
                return(new EngineAction
                {
                    JobAbility = Ability.AddendumBlack
                });
            }
            if (Config.SublimationEnabled && (!PL.HasStatus(StatusEffect.Sublimation_Activated)) && (!PL.HasStatus(StatusEffect.Sublimation_Complete)) && (!PL.HasStatus(StatusEffect.Refresh)) && PL.AbilityAvailable(Ability.Sublimation))
            {
                return(new EngineAction {
                    JobAbility = Ability.Sublimation
                });
            }

            if (Config.SublimationEnabled && ((PL.Player.MPMax - PL.Player.MP) > Config.SublimationMPLossThreshold) && PL.HasStatus(StatusEffect.Sublimation_Complete) && PL.AbilityAvailable(Ability.Sublimation))
            {
                return(new EngineAction {
                    JobAbility = Ability.Sublimation
                });
            }

            if (Config.DivineCaressEnabled && Config.DebuffsEnabled && PL.AbilityAvailable(Ability.DivineCaress))
            {
                return(new EngineAction {
                    JobAbility = Ability.DivineCaress
                });
            }

            if (Config.DevotionEnabled && PL.AbilityAvailable(Ability.Devotion) && PL.Player.HPP > 80 && (!Config.DevotionWhenEngaged || (Monitored.Player.Status == 1)))
            {
                int plParty = PL.GetPartyRelativeTo(Monitored);

                // Get all active members who are in the PLs party.
                IEnumerable <PartyMember> cParty = Monitored.GetActivePartyMembers().Where(member => member.InParty(plParty) && member.Name != PL.Player.Name);

                // If we're set to only devotion a specific target, filter the list for that target.
                if (Config.DevotionSpecifiedTarget)
                {
                    cParty = cParty.Where(member => member.Name == Config.DevotionTargetName);
                }

                // Get the first member who's within range, and has enough missing MP to meet our config criteria.
                var devotionTarget = cParty.FirstOrDefault(member => member.CurrentMP <= Config.DevotionMPThreshold && PL.EntityWithin(10, member.TargetIndex));

                if (devotionTarget != default)
                {
                    return(new EngineAction
                    {
                        Target = devotionTarget.Name,
                        JobAbility = Ability.Devotion
                    });
                }
            }

            if (Config.ShellraEnabled && (!PL.HasStatus(StatusEffect.Shell)))
            {
                var shellraSpell = Data.ShellraTiers[Config.ShellraLevel - 1];
                if (PL.SpellAvailable(shellraSpell))
                {
                    return(new EngineAction
                    {
                        Spell = shellraSpell
                    });
                }
            }

            if (Config.ProtectraEnabled && (!PL.HasStatus(StatusEffect.Protect)))
            {
                var protectraSpell = Data.ProtectraTiers[Config.ProtectraLevel - 1];
                if (PL.SpellAvailable(protectraSpell))
                {
                    return(new EngineAction {
                        Spell = protectraSpell
                    });
                }
            }

            if (Config.BarElementEnabled && !PL.HasStatus(Data.SpellEffects[Config.BarElementSpell]) && PL.SpellAvailable(Config.BarElementSpell))
            {
                // TODO: Make this work properly, so it can figure out if there's 2 charges and return
                // an action that says: Do Accession + Perpetuance + Barspell.
                var result = new EngineAction
                {
                    Spell = Config.BarElementSpell
                };

                if (Config.AccessionEnabled && Config.BarElementAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !Config.AOEBarElementEnabled && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.BarElemenetPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.BarStatusEnabled && !PL.HasStatus(Data.SpellEffects[Config.BarStatusSpell]) && PL.SpellAvailable(Config.BarStatusSpell))
            {
                var result = new EngineAction
                {
                    Spell = Config.BarStatusSpell
                };

                if (Config.AccessionEnabled && Config.BarStatusAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !Config.AOEBarStatusEnabled && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.BarStatusPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.GainBoostSpellEnabled && !PL.HasStatus(Data.SpellEffects[Config.GainBoostSpell]) && PL.SpellAvailable(Config.GainBoostSpell))
            {
                return(new EngineAction {
                    Spell = Config.GainBoostSpell
                });
            }

            if (Config.StormSpellEnabled && !PL.HasStatus(Data.SpellEffects[Config.StormSpell]) && PL.SpellAvailable(Config.StormSpell))
            {
                var result = new EngineAction {
                    Spell = Config.StormSpell
                };
                if (Config.AccessionEnabled && Config.StormspellAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.StormspellPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.ProtectEnabled && (!PL.HasStatus(StatusEffect.Protect)))
            {
                var result = new EngineAction {
                    Spell = Config.ProtectSpell
                };

                if (Config.AccessionEnabled && Config.AccessionProtectShell && PL.Party.GetPartyMembers().Count() > 2 && PL.AbilityAvailable(Ability.Accession) && PL.CurrentSCHCharges() > 0)
                {
                    if (!PL.HasStatus(StatusEffect.Accession))
                    {
                        result.JobAbility = Ability.Accession;
                    }
                }

                return(result);
            }

            if (Config.ShellEnabled && (!PL.HasStatus(StatusEffect.Shell)))
            {
                var result = new EngineAction {
                    Spell = Config.ShellSpell
                };

                if (Config.AccessionEnabled && Config.AccessionProtectShell && PL.Party.GetPartyMembers().Count() > 2 && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession))
                {
                    if (!PL.HasStatus(StatusEffect.Accession))
                    {
                        result.JobAbility = Ability.Accession;
                    }
                }

                return(result);
            }

            if (Config.ReraiseEnabled && (!PL.HasStatus(StatusEffect.Reraise)))
            {
                var result = new EngineAction {
                    Spell = Config.ReraiseSpell
                };

                if (Config.EnlightenmentReraise && !PL.HasStatus(StatusEffect.Addendum_White) && PL.AbilityAvailable(Ability.Enlightenment))
                {
                    result.JobAbility = Ability.Enlightenment;
                }

                return(result);
            }

            if (Config.UtsusemiEnabled && PL.ShadowsRemaining() < 2)
            {
                if (PL.GetInventoryItemCount(PL.GetItemId(Items.Shihei)) > 0)
                {
                    if (PL.SpellAvailable(Spells.Utsusemi_Ni))
                    {
                        return(new EngineAction {
                            Spell = Spells.Utsusemi_Ni
                        });
                    }
                    else if (PL.SpellAvailable(Spells.Utsusemi_Ichi) && (PL.ShadowsRemaining() == 0))
                    {
                        return(new EngineAction {
                            Spell = Spells.Utsusemi_Ichi
                        });
                    }
                }
            }

            if (Config.BlinkEnabled && (!PL.HasStatus(StatusEffect.Blink)) && PL.SpellAvailable(Spells.Blink))
            {
                var result = new EngineAction {
                    Spell = Spells.Blink
                };

                if (Config.AccessionEnabled && Config.BlinkAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.BlinkPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.PhalanxEnabled && (!PL.HasStatus(StatusEffect.Phalanx)) && PL.SpellAvailable(Spells.Phalanx))
            {
                var result = new EngineAction {
                    Spell = Spells.Phalanx
                };

                if (Config.AccessionEnabled && Config.PhalanxAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.PhalanxPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.RefreshEnabled && (!PL.HasStatus(StatusEffect.Refresh)))
            {
                var result = new EngineAction {
                    Spell = Config.RefreshSpell
                };

                if (Config.AccessionEnabled && Config.RefreshAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.RefreshPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.RegenEnabled && (!PL.HasStatus(StatusEffect.Regen)))
            {
                var result = new EngineAction {
                    Spell = Config.RegenSpell
                };

                if (Config.AccessionEnabled && Config.RegenAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.RegenPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.AdloquiumEnabled && (!PL.HasStatus(StatusEffect.Regain)) && PL.SpellAvailable(Spells.Adloquium))
            {
                var result = new EngineAction {
                    Spell = Spells.Adloquium
                };

                if (Config.AccessionEnabled && Config.AdloquiumAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.AdloquiumPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.StoneskinEnabled && (!PL.HasStatus(StatusEffect.Stoneskin)) && PL.SpellAvailable(Spells.Stoneskin))
            {
                var result = new EngineAction {
                    Spell = Spells.Stoneskin
                };

                if (Config.AccessionEnabled && Config.StoneskinAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.StoneskinPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.AquaveilEnabled && (!PL.HasStatus(StatusEffect.Aquaveil)) && PL.SpellAvailable(Spells.Aquaveil))
            {
                var result = new EngineAction {
                    Spell = Spells.Aquaveil
                };

                if (Config.AccessionEnabled && Config.AquaveilAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                {
                    result.JobAbility = Ability.Accession;
                }
                else if (Config.PerpetuanceEnabled && Config.AquaveilPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                {
                    result.JobAbility = Ability.Perpetuance;
                }

                return(result);
            }

            if (Config.KlimaformEnabled && !PL.HasStatus(StatusEffect.Klimaform))
            {
                return(new EngineAction {
                    Spell = Spells.Klimaform
                });
            }

            if (Config.TemperEnabled && (!PL.HasStatus(StatusEffect.Multi_Strikes)))
            {
                return(new EngineAction {
                    Spell = Config.TemperSpell
                });
            }

            if (Config.HasteEnabled && (!PL.HasStatus(StatusEffect.Haste)))
            {
                return(new EngineAction {
                    Spell = Config.HasteSpell
                });
            }

            if (Config.SpikesEnabled && !PL.HasStatus(Data.SpellEffects[Config.SpikesSpell]))
            {
                return(new EngineAction {
                    Spell = Config.SpikesSpell
                });
            }

            if (Config.EnSpellEnabled && !PL.HasStatus(Data.SpellEffects[Config.EnSpell]) && PL.SpellAvailable(Config.EnSpell))
            {
                var result = new EngineAction {
                    Spell = Config.EnSpell
                };

                // Don't want to try and accession/perpetuance tier II.
                if (!Config.EnSpell.Contains("II"))
                {
                    if (Config.AccessionEnabled && Config.EnspellAccession && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Accession) && !PL.HasStatus(StatusEffect.Accession))
                    {
                        result.JobAbility = Ability.Accession;
                    }
                    else if (Config.PerpetuanceEnabled && Config.EnspellPerpetuance && PL.CurrentSCHCharges() > 0 && PL.AbilityAvailable(Ability.Perpetuance) && !PL.HasStatus(StatusEffect.Perpetuance))
                    {
                        result.JobAbility = Ability.Perpetuance;
                    }
                }

                return(result);
            }

            if (Config.AuspiceEnabled && (!PL.HasStatus(StatusEffect.Auspice)) && PL.SpellAvailable(Spells.Auspice))
            {
                return(new EngineAction {
                    Spell = Spells.Auspice
                });
            }

            // TODO: Rethink this whole logic.
            // Probably doesn't work at all right now, and need to figure out a better way
            // to find entities than iterating 2048 things...
            if (Config.AutoTargetEnabled && PL.SpellAvailable(Config.AutoTargetSpell))
            {
                if (Config.PartyBasedHateSpell)
                {
                    // PARTY BASED HATE SPELL
                    int enemyID = CheckEngagedStatus_Hate(Config);

                    if (enemyID != 0 && enemyID != lastKnownEstablisherTarget)
                    {
                        lastKnownEstablisherTarget = enemyID;

                        return(new EngineAction
                        {
                            Target = Config.AutoTargetTarget,
                            Spell = Config.AutoTargetSpell
                        });
                    }
                }
                else
                {
                    // ENEMY BASED TARGET
                    int enemyID = CheckEngagedStatus_Hate(Config);

                    if (enemyID != 0 && enemyID != lastKnownEstablisherTarget)
                    {
                        PL.Target.SetTarget(enemyID);

                        lastKnownEstablisherTarget = enemyID;

                        return(new EngineAction
                        {
                            Target = "<t>",
                            Spell = Config.AutoTargetSpell
                        });

                        //if (ConfigForm.config.DisableTargettingCancel == false)
                        //{
                        //    await Task.Delay(TimeSpan.FromSeconds((double)ConfigForm.config.TargetRemoval_Delay));
                        //    PL.Target.SetTarget(0);
                        //}
                    }
                }
            }

            return(null);
        }
Пример #3
0
        public EngineAction Run(CureConfig Config, bool[] enabledMembers, bool[] highPriorityMembers)
        {
            _config = Config;

            IEnumerable <PartyMember> partyByHP = Monitored.GetActivePartyMembers().OrderBy(member => member.CurrentHPP);

            /////////////////////////// PL CURE //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // TODO: Test this! Pretty sure your own character is always party member index 0.
            if (PL.Player.HP > 0 && (PL.Player.HPP <= Config.MonitoredCurePercentage) && Config.EnableOutOfPartyHealing && !PL.SamePartyAs(Monitored))
            {
                var plAsPartyMember = PL.Party.GetPartyMember(0);
                return(CureCalculator(plAsPartyMember));
            }

            /////////////////////////// CURAGA //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (Config.EnabledCuragaTiers.Any())
            {
                int plParty = PL.GetPartyRelativeTo(Monitored);

                // Order parties that qualify for AOE cures by average missing HP.
                var partyNeedsAoe = Monitored.PartyNeedsAoeCure(Config.CuragaMinPlayers, Config.CuragaHealthPercent).OrderBy(partyNumber => Monitored.AverageHpLossForParty(partyNumber));

                // If PL is in same alliance, and there's at least 1 party that needs an AOE cure.
                // Parties are ordered by most average missing HP.
                if (plParty > 0 && partyNeedsAoe.Any())
                {
                    int targetParty = 0;

                    // We can accession if we have light arts/addendum white, and either we already have the status or we have the ability available,
                    // and have the charges to use it.
                    bool plCanAccession = (PL.HasStatus(StatusEffect.Light_Arts) || PL.HasStatus(StatusEffect.Addendum_White)) &&
                                          (PL.HasStatus(StatusEffect.Accession) || (PL.AbilityAvailable(Ability.Accession) && PL.CurrentSCHCharges() > 0));

                    foreach (int party in partyNeedsAoe)
                    {
                        // We check whether we can accession here, so that if we can't accession we don't skip a chance to curaga our own party.
                        if (party != plParty && !plCanAccession)
                        {
                            continue;
                        }

                        // We get the first party with at least 1 person who's in it and checked.
                        // As well as 1 person who's both under the cure threshold AND in casting range.
                        // This way we won't AOE parties we haven't got anyone checked in, and we won't attempt
                        // to AOE a party where we can't reach any of the injured members.
                        if (partyByHP.Count(pm => pm.InParty(party) && enabledMembers[pm.MemberNumber]) > 0)
                        {
                            if (partyByHP.Count(pm => pm.InParty(party) && pm.CurrentHPP < Config.CuragaHealthPercent && PL.CanCastOn(pm)) > 0)
                            {
                                targetParty = party;
                            }
                        }
                    }

                    if (targetParty > 0)
                    {
                        // The target is the first person we can cast on, since they're already ordered by HPP.
                        var target = partyByHP.FirstOrDefault(pm => pm.InParty(targetParty) && PL.CanCastOn(pm));

                        if (target != default)
                        {
                            // If same party as PL, curaga. Otherwise we try to accession cure.
                            if (targetParty == plParty)
                            {
                                // TODO: Don't do this if we have no curagas enabled, prevents curing!
                                return(CuragaCalculator(target));
                            }
                            else
                            {
                                var actionResult = CureCalculator(target);

                                // We've already determined we can accession, or already have the status.
                                if (actionResult != null && !PL.HasStatus(StatusEffect.Accession))
                                {
                                    actionResult.JobAbility = Ability.Accession;
                                }

                                return(actionResult);
                            }
                        }
                    }
                }
            }

            /////////////////////////// CURE //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // First run a check on the monitored target
            if (Config.MonitoredPriorityEnabled && Monitored.Player.HP > 0 && (Monitored.Player.HPP <= Config.MonitoredCurePercentage))
            {
                // Need to get monitored player as a PartyMember
                PartyMember monitoredPlayer = partyByHP.FirstOrDefault(p => p.Name == Monitored.Player.Name);
                if (monitoredPlayer != default)
                {
                    return(CureCalculator(monitoredPlayer));
                }
            }

            // Calculate who needs a cure, and is a valid target.
            // Anyone who's: Enabled + Active + Alive + Under cure threshold
            var validCures = partyByHP.Where(pm => enabledMembers[pm.MemberNumber] && (pm.CurrentHPP <= Config.CureHealthPercent) && PL.CanCastOn(pm));

            // Now run a scan to check all targets in the High Priority Threshold
            if (validCures != null && validCures.Any())
            {
                var highPriorityCures = validCures.Where(pm => highPriorityMembers[pm.MemberNumber]);

                if (highPriorityCures != null && highPriorityCures.Any())
                {
                    return(CureCalculator(highPriorityCures.First()));
                }
                else
                {
                    return(CureCalculator(validCures.First()));
                }
            }


            return(null);
        }