Example #1
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);
        }