예제 #1
0
        private static async Task <bool> ProcessCardLogic(CardLogicType logictype, CardPlayType playtype, AstrologianCard card)
        {
            if (AstrologianSettings.Instance.CardRules == null)
            {
                return(false);
            }

            //if (TimeSinceTheLastCardAction < LastCardThreshold) return false;

            if (!LastCardAction.CanCastNewAction)
            {
                return(false);
            }

            var ruleincombat       = Core.Me.InCombat;
            var cardRulesToProcess = AstrologianSettings.Instance.CardRules.Where(r => r.Card == card && r.LogicType == logictype && r.PlayType == playtype).OrderBy(r => r.CardPriority);

            return(await ProcessCardRule(cardRulesToProcess, ruleincombat, playtype, logictype));
        }
예제 #2
0
        private static async Task <bool> ProcessCardRule(IEnumerable <CardRule> cardRulesToProcess, bool ruleincombat, CardPlayType playtype, CardLogicType logictype)
        {
            if (cardRulesToProcess == null)
            {
                return(false);
            }

            var rulesToProcess = cardRulesToProcess as IList <CardRule> ?? cardRulesToProcess.ToList();
            var heldcard       = HeldCard();

            var processed = false;

            //Logger.WriteInfo($@"Processing up to {rulesToProcess.Count} {logictype} rules");

            foreach (var cardRule in rulesToProcess)
            {
                //Logger.WriteInfo($"Processing rule: {cardRule.CardPriority}"); //For testing that the card rule processing is going by priority
                await Coroutine.Yield();

                if (processed)
                {
                    Logger.WriteInfo($"Detected that we've already processed a rule for {cardRule.Card}");
                    return(true);
                }

                if (playtype == CardPlayType.Drawn && cardRule.Card != DrawnCard())
                {
                    return(false);
                }
                if (playtype == CardPlayType.Held && cardRule.Card != HeldCard())
                {
                    return(false);
                }

                var action = cardRule.Action;
                // ReSharper disable once SuggestVarOrType_SimpleTypes
                Conditions conditions = cardRule.Conditions;
                var        targetrule = cardRule.Target;
                CardTargets.Clear();

                GameObject target = Core.Me;
                // ReSharper disable once SuggestVarOrType_SimpleTypes
                TargetConditions targetconditions = cardRule.TargetConditions;

                if (conditions != null)
                {
                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"InCombat Check");
                    if (conditions.InCombat != null && conditions.InCombat != ruleincombat)
                    {
                        continue;
                    }

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"HasHeldCard Check");
                    if (conditions.HasHeldCard?.Count > 0)
                    {
                        if (conditions.HasHeldCard.All(r => r != heldcard))
                        {
                            continue;
                        }
                    }

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"DoesntHaveHeldCard Check");
                    if (conditions.DoesntHaveHeldCard?.Count > 0)
                    {
                        if (conditions.DoesntHaveHeldCard.Any(r => r == heldcard))
                        {
                            continue;
                        }
                    }

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"JobsInParty Check");
                    if (conditions.JobsNotInParty?.Count > 0 && Globals.InParty)
                    {
                        if (PartyManager.AllMembers.Any(r => conditions.JobsNotInParty.Contains(r.Class)))
                        {
                            continue;
                        }
                    }

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"RolesNotInParty Check");
                    if (conditions.RolesNotInParty?.Count > 0 && Globals.InParty)
                    {
                        if (PartyManager.AllMembers.Any(r =>
                                                        (conditions.RolesNotInParty.Contains(CardRole.Tank) && r.GameObject.IsTank()) ||
                                                        (conditions.RolesNotInParty.Contains(CardRole.Healer) && r.GameObject.IsHealer()) ||
                                                        (conditions.RolesNotInParty.Contains(CardRole.Dps) && r.GameObject.IsDps())))
                        {
                            continue;
                        }
                    }
                }

                //if (cardRule.CardPriority == 33) Logger.WriteInfo($"Building Target List");
                if (targetrule == CardTarget.Me)
                {
                    CardTargets.Add(Core.Me);
                }
                if (targetrule == CardTarget.PartyMember)
                {
                    CardTargets = PartyManager.VisibleMembers.Select(r => r.BattleCharacter).Where(r =>
                                                                                                   r.IsTargetable && r.InLineOfSight() && r.Icon != PlayerIcon.Viewing_Cutscene).ToList();
                }

                //if (cardRule.CardPriority == 33) Logger.WriteInfo($@"Processing Card Action: {action} on: {target}");
                switch (action)
                {
                case CardAction.Redraw:
                    if (!CanRedraw)
                    {
                        continue;
                    }
                    if (!await Spells.Redraw.Cast(Core.Me))
                    {
                        return(false);
                    }
                    LogRuleProcessed(cardRule, ruleincombat, heldcard);
                    processed = true;
                    return(true);

                case CardAction.MinorArcana:
                    if (!CanMinorArcana)
                    {
                        continue;
                    }
                    if (!await Spells.MinorArcana.Cast(Core.Me))
                    {
                        return(false);
                    }
                    LogRuleProcessed(cardRule, ruleincombat, heldcard);
                    processed = true;
                    return(true);

                case CardAction.Play:
                {
                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets Starting Count: {CardTargets.Count()}");
                    CardTargets.RemoveAll(r => r.HasCardAura() || r.CurrentHealth < 1 || r.IsDead || !r.IsValid);

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After Death Clean: {CardTargets.Count()}");

                    if (targetconditions != null)
                    {
                        var statLessThanFlag = false;

                        if (targetconditions.MpLessThan != null && targetconditions.MpLessThan > 0 && targetconditions.MpLessThan < 100)
                        {
                            CardTargets.RemoveAll(r => r.CurrentManaPercent > targetconditions.MpLessThan);
                            CardTargets = CardTargets.OrderBy(r => r.CurrentManaPercent).ToList();
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After MP Clean: {CardTargets.Count()}");
                            statLessThanFlag = true;
                        }

                        if (targetconditions.HpLessThan != null && targetconditions.HpLessThan > 0 && targetconditions.HpLessThan < 100)
                        {
                            CardTargets.RemoveAll(r => r.CurrentHealthPercent > targetconditions.HpLessThan);
                            CardTargets = CardTargets.OrderBy(r => r.CurrentHealthPercent).ToList();
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After HP Clean: {CardTargets.Count()}");
                            statLessThanFlag = true;
                        }

                        if (targetconditions.HasTarget != null)
                        {
                            CardTargets.RemoveAll(r => r.HasTarget != targetconditions.HasTarget);
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After Has Target Clean: {CardTargets.Count()}");
                        }

                        if (targetconditions.IsRole?.Count > 0)
                        {
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"Comparing IsRole Clean: {targetconditions.IsRole.Select(r => r.ToString())}");
                            if (targetconditions.IsRole.All(r => r != CardRole.Dps))
                            {
                                CardTargets.RemoveAll(r => r.IsDps());
                            }
                            if (targetconditions.IsRole.All(r => r != CardRole.Tank))
                            {
                                CardTargets.RemoveAll(r => r.IsTank());
                            }
                            if (targetconditions.IsRole.All(r => r != CardRole.Healer))
                            {
                                CardTargets.RemoveAll(r => r.IsHealer());
                            }
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After IsRole Clean: {CardTargets.Count()}");
                        }

                        if (targetconditions.IsJob?.Count > 0)
                        {
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"Comparing IsJob Clean: {targetconditions.IsJob.Select(r => r.ToString())}");
                            CardTargets.RemoveAll(r => !targetconditions.IsJob.Contains(r.CurrentJob));
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After IsJob Clean: {CardTargets.Count()}");
                        }

                        if (targetconditions.JobOrder != null)
                        {
                            CardTargets = CardTargets.OrderBy(x =>
                                {
                                    var index = targetconditions.JobOrder.IndexOf(x.CurrentJob);

                                    if (index == -1)
                                    {
                                        index = int.MaxValue;
                                    }

                                    return(index);
                                }).ToList();

                            statLessThanFlag = true;
                        }

                        if (targetconditions.WithAlliesNearbyMoreThan != null && targetconditions.WithAlliesNearbyMoreThan > 0)
                        {
                            CardTargets.RemoveAll(r => r.PartyMembersNearby(15).Count() <= targetconditions.WithAlliesNearbyMoreThan);
                            //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets After WithAlliesNearbyMoreThan Clean: {CardTargets.Count()}");
                        }

                        if (targetrule == CardTarget.PartyMember)
                        {
                            if (targetconditions.PlayerName != null)
                            {
                                target = CardTargets.FirstOrDefault(r => r.Name == targetconditions.PlayerName);
                            }
                            else if ((targetconditions.Choice == CardChoiceType.Random || targetconditions.Choice == null) && !statLessThanFlag)
                            {
                                var random = new Random();
                                target = CardTargets.ElementAtOrDefault(random.Next(0, CardTargets.Count));
                            }
                            else
                            {
                                target = CardTargets.FirstOrDefault();
                            }

                            if (target == null)
                            {
                                //if (cardRule.CardPriority == 33) Logger.WriteInfo($"No Viable Target based on Conditions");
                                continue;
                            }
                        }
                    }

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets Ending Count: {CardTargets.Count()}");

                    //if (cardRule.CardPriority == 33) Logger.WriteInfo($"CardTargets Attempting to use {cardRule.Card} on {target}");

                    switch (playtype)
                    {
                    case CardPlayType.Drawn:
                        if (logictype == CardLogicType.Pvp)
                        {
                            //Logger.WriteInfo($@"Trying to Pvp Play Drawn {cardRule.Card} on {target.Name} (CanAttack: {target.CanAttack})");
                            if (!await Spells.PvpPlayDrawn.Cast(target))
                            {
                                return(false);
                            }
                            LogRuleProcessed(cardRule, ruleincombat, heldcard);
                            processed = true;
                            return(true);
                        }
                        //if (cardRule.CardPriority == 33) Logger.WriteInfo($@"Trying to Normal Play Drawn {cardRule.Card} on {target.Name} (CanAttack: {target.CanAttack})");
                        if (!await Spells.PlayDrawn.Cast(target))
                        {
                            return(false);
                        }
                        LogRuleProcessed(cardRule, ruleincombat, heldcard);
                        processed = true;
                        return(true);

                    case CardPlayType.Held:
                        if (!await Spells.PlaySpread.Cast(target))
                        {
                            return(false);
                        }
                        LogRuleProcessed(cardRule, ruleincombat, heldcard);
                        processed = true;
                        return(true);

                    default:
                        processed = true;
                        return(false);
                    }
                }

                case CardAction.StopLogic:
                    processed = true;
                    return(false);

                case CardAction.Undraw:
                    if (!CanUndraw)
                    {
                        continue;
                    }
                    if (!await Spells.Undraw.Cast(Core.Me))
                    {
                        return(false);
                    }
                    LogRuleProcessed(cardRule, ruleincombat, heldcard);
                    processed = true;
                    return(true);

                default:
                    continue;
                }
            }

            if (playtype != CardPlayType.Drawn || logictype == CardLogicType.Pvp)
            {
                return(false);
            }
            var drawncard = DrawnCard();

            if (AstrologianSettings.Instance.CardRuleDefaultToMinorArcana && CanMinorArcana)
            {
                if (!await Spells.MinorArcana.Cast(Core.Me))
                {
                    return(false);
                }
                if (BaseSettings.Instance.DebugPlayerCasting)
                {
                    Logger.WriteInfo($"No appropriate Card Rule to process. Using Minor Arcana on {drawncard} for Lord Of Crowns.");
                }
                processed = true;
                return(true);
            }

            if (!AstrologianSettings.Instance.CardRuleDefaultToUndraw)
            {
                return(false);
            }
            if (!CanUndraw)
            {
                return(false);
            }
            if (!await Spells.Undraw.Cast(Core.Me))
            {
                return(false);
            }
            if (BaseSettings.Instance.DebugPlayerCasting)
            {
                Logger.WriteInfo($"No appropriate Card Rule to process. Undrawing {drawncard}.");
            }
            processed = true;
            return(true);
        }