public override IEnumerator UsePower(int index = 0)
        {
            int numDamage = GetPowerNumeral(0, 3);

            //"Once before your next turn, when a hero target is dealt damage, {Echelon} may deal the source of that damage 3 melee damage"
            var statusEffect = new OnDealDamageStatusEffect(CardWithoutReplacements, nameof(MaybeCounterDamageResponse), $"Once before their next turn, when a hero target is dealt damage {DecisionMaker.Name} may deal the source of that damage {numDamage} melee damage.", new TriggerType[] { TriggerType.DealDamage }, DecisionMaker.TurnTaker, this.Card, new int[] { numDamage });

            statusEffect.TargetCriteria.IsHero            = true;
            statusEffect.DamageAmountCriteria.GreaterThan = 0;
            statusEffect.UntilStartOfNextTurn(DecisionMaker.TurnTaker);
            statusEffect.UntilTargetLeavesPlay(CharacterCard);
            statusEffect.BeforeOrAfter  = BeforeOrAfter.After;
            statusEffect.DoesDealDamage = true;
            statusEffect.CanEffectStack = true;

            IEnumerator coroutine = AddStatusEffect(statusEffect);

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(coroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(coroutine);
            }
            yield break;
        }
        public override IEnumerator UseIncapacitatedAbility(int index)
        {
            switch (index)
            {
            case 0:
            {
                //"Until the start of your next turn, prevent all damage that would be dealt to or by the target with the lowest HP.",
                OnDealDamageStatusEffect lowestTargetImmunity = new OnDealDamageStatusEffect(Card, "LowestTargetImmunity", "The target with the lowest HP is immune to damage and cannot deal damage.", new TriggerType[] { TriggerType.MakeImmuneToDamage }, TurnTaker, Card);
                lowestTargetImmunity.UntilStartOfNextTurn(TurnTaker);
                lowestTargetImmunity.CardSource = Card;
                lowestTargetImmunity.SourceCriteria.IsTarget = true;
                lowestTargetImmunity.BeforeOrAfter           = BeforeOrAfter.Before;
                IEnumerator coroutine = AddStatusEffect(lowestTargetImmunity);
                if (UseUnityCoroutines)
                {
                    yield return(GameController.StartCoroutine(coroutine));
                }
                else
                {
                    GameController.ExhaustCoroutine(coroutine);
                }
                break;
            }

            case 1:
            {
                //"1 player may use a power now.",
                IEnumerator coroutine2 = GameController.SelectHeroToUsePower(HeroTurnTakerController, optionalSelectHero: false, optionalUsePower: true, allowAutoDecide: false, null, null, null, omitHeroesWithNoUsablePowers: true, canBeCancelled: true, GetCardSource());
                if (UseUnityCoroutines)
                {
                    yield return(GameController.StartCoroutine(coroutine2));
                }
                else
                {
                    GameController.ExhaustCoroutine(coroutine2);
                }
                break;
            }

            case 2:
            {
                //"1 hero target regains 2 HP."
                IEnumerator coroutine3 = GameController.SelectAndGainHP(HeroTurnTakerController, 2, optional: false, (Card c) => c.IsInPlay && c.IsHero && c.IsTarget, 1, null, allowAutoDecide: false, null, GetCardSource());
                if (UseUnityCoroutines)
                {
                    yield return(GameController.StartCoroutine(coroutine3));
                }
                else
                {
                    GameController.ExhaustCoroutine(coroutine3);
                }
                break;
            }
            }


            yield break;
        }
Example #3
0
        public IEnumerator AddTackleEffect(DealDamageAction dda)
        {
            // "Until the start of your next turn, whenever that target would deal damage, reduce that damage to 1."
            Card pinned = dda.Target;
            OnDealDamageStatusEffect tackleEffect = new OnDealDamageStatusEffect(base.Card, "ReduceToOne", "Until the start of " + base.CharacterCard.Title + "'s next turn, whenever " + pinned.Title + " would deal damage, reduce that damage to 1.", new TriggerType[] { TriggerType.ReduceDamage }, base.TurnTaker, base.Card);

            tackleEffect.SourceCriteria.IsSpecificCard = pinned;
            tackleEffect.UntilStartOfNextTurn(base.TurnTaker);
            tackleEffect.DamageAmountCriteria.GreaterThan = 1;
            tackleEffect.UntilCardLeavesPlay(pinned);

            IEnumerator statusCoroutine = base.GameController.AddStatusEffect(tackleEffect, true, GetCardSource());

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(statusCoroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(statusCoroutine);
            }
            yield break;
        }
Example #4
0
        private IEnumerator AddFallResponse()
        {
            //Whenever a hero deals lightning damage to a target, reduce damage dealt by that target by 1 until the start of your next turn.
            OnDealDamageStatusEffect effect = new OnDealDamageStatusEffect(CardWithoutReplacements, nameof(FallReduceDamageReponse), "Whenever a hero deals lightning damage to a target, reduce damage dealt by that target by 1 until the start of your next turn.", new TriggerType[]
            {
                TriggerType.ReduceDamage
            }, base.TurnTaker, base.Card);

            effect.SourceCriteria.IsHeroCharacterCard = true;
            effect.DamageTypeCriteria.AddType(DamageType.Lightning);
            effect.UntilStartOfNextTurn(base.TurnTaker);
            effect.BeforeOrAfter  = BeforeOrAfter.After;
            effect.CanEffectStack = true;
            IEnumerator coroutine = AddStatusEffect(effect);

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(coroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(coroutine);
            }
        }
Example #5
0
        private IEnumerator AddWinterResponse()
        {
            //Whenever a hero deals cold damage to a target, they draw a card.
            OnDealDamageStatusEffect effect = new OnDealDamageStatusEffect(CardWithoutReplacements, nameof(WinterDrawCardReponse), "Whenever a hero deals cold damage to a target, they draw a card.", new TriggerType[]
            {
                TriggerType.DrawCard
            }, base.TurnTaker, base.Card);

            effect.SourceCriteria.IsHeroCharacterCard = true;
            effect.UntilStartOfNextTurn(base.TurnTaker);
            effect.DamageTypeCriteria.AddType(DamageType.Cold);
            effect.BeforeOrAfter  = BeforeOrAfter.After;
            effect.CanEffectStack = true;
            IEnumerator coroutine = AddStatusEffect(effect);

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(coroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(coroutine);
            }
        }
        public override IEnumerator UseIncapacitatedAbility(int index)
        {
            switch (index)
            {
            case 0:
            {
                //"Select a hero target. Reduce damage dealt to that target by 1 until the start of your next turn."
                List <SelectCardDecision> storedResult = new List <SelectCardDecision>();
                IEnumerator reduceDamage = base.GameController.SelectCardAndStoreResults(this.DecisionMaker, SelectionType.SelectTargetFriendly, new LinqCardCriteria((Card c) => c.IsInPlayAndHasGameText && c.IsTarget && c.IsHero, "hero target in play", false, false, null, null, false), storedResult, false, false, null, true, GetCardSource());
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(reduceDamage));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(reduceDamage);
                }
                Card selectedCard             = base.GetSelectedCard(storedResult);
                ReduceDamageStatusEffect rdse = new ReduceDamageStatusEffect(1);
                rdse.TargetCriteria.IsSpecificCard = selectedCard;
                rdse.UntilStartOfNextTurn(base.TurnTaker);
                rdse.UntilCardLeavesPlay(selectedCard);
                reduceDamage = base.AddStatusEffect(rdse, true);
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(reduceDamage));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(reduceDamage);
                }
                break;
            }

            case 1:
            {
                //"Until the start of your next turn, whenever a hero is dealt damage, that hero’s player may draw a card."
                OnDealDamageStatusEffect oddse = new OnDealDamageStatusEffect(CardWithoutReplacements, nameof(DrawCardResponse), "Until the start of your next turn, whenever a hero is dealt damage, their player may draw a card.", new TriggerType[] { TriggerType.DrawCard }, base.TurnTaker, this.Card);
                oddse.TargetCriteria.IsHeroCharacterCard = true;
                oddse.BeforeOrAfter = BeforeOrAfter.After;
                oddse.UntilStartOfNextTurn(base.TurnTaker);
                IEnumerator dealtDamage = base.AddStatusEffect(oddse, true);
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(dealtDamage));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(dealtDamage);
                }
                break;
            }

            case 2:
            {
                //"Destroy any number of non-character hero cards.  For each card destroyed this way, a hero regains 2 HP."
                WhenCardIsDestroyedStatusEffect wcidse = new WhenCardIsDestroyedStatusEffect(CardWithoutReplacements, nameof(GainHPResponse), null, new TriggerType[] { TriggerType.GainHP }, base.HeroTurnTaker, this.Card);
                wcidse.CardDestroyedCriteria.IsHero = true;
                wcidse.BeforeOrAfter = BeforeOrAfter.After;
                wcidse.UntilEndOfPhase(base.TurnTaker, Phase.End);
                IEnumerator cardDestroyed = base.AddStatusEffect(wcidse, true);
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(cardDestroyed));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(cardDestroyed);
                }
                int         value        = base.FindCardsWhere((Card c) => c.IsHero && !c.IsHeroCharacterCard && c.IsInPlay, false, null, false).Count <Card>();
                IEnumerator destroyCards = base.GameController.SelectAndDestroyCards(this.DecisionMaker, new LinqCardCriteria((Card c) => c.IsHero && !c.IsHeroCharacterCard, "non-character hero card", true, false, null, null, false), new int?(value), false, new int?(0), null, null, null, false, null, null, null, GetCardSource(null));
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(destroyCards));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(destroyCards);
                }
                break;
            }
            }
        }
        public override IEnumerator UsePower(int index = 0)
        {
            int targetNumeral = base.GetPowerNumeral(0, 2);
            int damageNumeral = base.GetPowerNumeral(1, 2);

            List <SelectCardDecision> storedSelect = new List <SelectCardDecision>();
            //{Titan} deals up to 2 non-hero targets 2 infernal damage each.
            IEnumerator coroutine = base.GameController.SelectTargetsAndDealDamage(base.HeroTurnTakerController, new DamageSource(base.GameController, base.CharacterCard), damageNumeral, DamageType.Infernal, targetNumeral, false, 0, storedResultsDecisions: storedSelect, cardSource: base.GetCardSource());

            if (UseUnityCoroutines)
            {
                yield return(GameController.StartCoroutine(coroutine));
            }
            else
            {
                GameController.ExhaustCoroutine(coroutine);
            }

            //Until the start of your next turn, when those targets would deal damage, you may redirect that damage to {Titan}.
            if (storedSelect.FirstOrDefault() != null)
            {
                List <StatusEffect> redirects = new List <StatusEffect> {
                };

                foreach (SelectCardDecision decision in storedSelect)
                {
                    if (decision.SelectedCard != null && decision.SelectedCard.IsInPlayAndHasGameText)
                    {
                        OnDealDamageStatusEffect onDealDamageStatusEffect = new OnDealDamageStatusEffect(CardWithoutReplacements,
                                                                                                         nameof(MaybeRedirectDamageResponse),
                                                                                                         $"When {decision.SelectedCard.Title} would deal damage, {DecisionMaker.Name} may redirect it to themselves.",
                                                                                                         new TriggerType[] { TriggerType.RedirectDamage, TriggerType.WouldBeDealtDamage },
                                                                                                         this.TurnTaker,
                                                                                                         this.Card);

                        //Until the start of your next turn...
                        onDealDamageStatusEffect.UntilStartOfNextTurn(base.TurnTaker);
                        //...when those targets would deal damage...
                        onDealDamageStatusEffect.SourceCriteria.IsSpecificCard    = decision.SelectedCard;
                        onDealDamageStatusEffect.DamageAmountCriteria.GreaterThan = 0;

                        //prevent it from asking to redirect from Titan to Titan
                        onDealDamageStatusEffect.TargetCriteria.IsNotSpecificCard = this.CharacterCard;

                        onDealDamageStatusEffect.UntilTargetLeavesPlay(decision.SelectedCard);
                        onDealDamageStatusEffect.BeforeOrAfter  = BeforeOrAfter.Before;
                        onDealDamageStatusEffect.CanEffectStack = true;

                        redirects.Add(onDealDamageStatusEffect);
                    }
                }

                foreach (StatusEffect effect in redirects)
                {
                    coroutine = base.AddStatusEffect(effect);
                    if (base.UseUnityCoroutines)
                    {
                        yield return(base.GameController.StartCoroutine(coroutine));
                    }
                    else
                    {
                        base.GameController.ExhaustCoroutine(coroutine);
                    }
                }
            }
            yield break;
        }
        private IEnumerator AssignBlocked(PhaseChangeAction pca)
        {
            // "At the end of the villain turn, each hero except the 2 heroes with the lowest HP become [b]BLOCKED[/b] until the start of the villain turn."
            // Find exactly 2 hero character cards with lowest HP
            List <Card> currentLowestHeroes = new List <Card>();
            IEnumerator findLowestCoroutine = GameController.FindTargetsWithLowestHitPoints(1, 2, (Card c) => c.IsHeroCharacterCard, currentLowestHeroes, cardSource: GetCardSource());

            if (base.UseUnityCoroutines)
            {
                yield return(this.GameController.StartCoroutine(findLowestCoroutine));
            }
            else
            {
                this.GameController.ExhaustCoroutine(findLowestCoroutine);
            }
            string lowestNames = "";

            if (currentLowestHeroes.Any())
            {
                lowestNames += currentLowestHeroes.First().Title;
                if (currentLowestHeroes.Count() > 1)
                {
                    lowestNames += ", " + currentLowestHeroes.ElementAt(1).Title;
                }
            }
            Log.Debug("Found 2 heroes with lowest HP: " + lowestNames);

            // All OTHER active hero characters become BLOCKED
            LinqCardCriteria criteria = new LinqCardCriteria((Card c) => c.IsHeroCharacterCard && c.IsActive && !currentLowestHeroes.Contains(c));
            List <Card>      toBlock  = base.GameController.FindCardsWhere(criteria).ToList();

            foreach (Card hero in toBlock)
            {
                //Log.Debug("Creating status effects for " + hero.Title);
                // BLOCKED comprises 2 status effects, both expiring at the start of the villain turn, when the hero leaves play, or when this card leaves play:
                // The hero cannot deal damage to non-Terrain villain targets
                OnDealDamageStatusEffect cantHitNonTerrain = new OnDealDamageStatusEffect(cardWithMethod: this.Card, methodToExecute: nameof(this.PreventDamage), description: hero.Title + " cannot deal damage to non-Terrain villain targets.", triggerTypes: new TriggerType[] { TriggerType.CancelAction }, decisionMaker: base.TurnTaker, cardSource: this.Card, powerNumerals: null);
                //Log.Debug("Initialized cantHitNonTerrain");
                cantHitNonTerrain.UntilStartOfNextTurn(this.TurnTaker);
                cantHitNonTerrain.UntilTargetLeavesPlay(hero);
                cantHitNonTerrain.UntilCardLeavesPlay(this.Card);
                cantHitNonTerrain.SourceCriteria.IsSpecificCard = hero;
                cantHitNonTerrain.TargetCriteria.IsVillain      = true;
                cantHitNonTerrain.BeforeOrAfter = BeforeOrAfter.Before;
                IEnumerator addCantHitCoroutine = AddStatusEffect(cantHitNonTerrain);
                //Log.Debug("Built cantHitNonTerrain for " + hero.Title);
                // When the hero would be dealt damage by a villain target, redirect it to a non-BLOCKED hero
                OnDealDamageStatusEffect redirectWhenHit = new OnDealDamageStatusEffect(cardWithMethod: this.Card, methodToExecute: nameof(this.RedirectDamage), description: "When " + hero.Title + " would be dealt damage by a villain target, redirect it to a non-BLOCKED hero.", triggerTypes: new TriggerType[] { TriggerType.RedirectDamage }, decisionMaker: base.TurnTaker, cardSource: this.Card, powerNumerals: null);
                redirectWhenHit.UntilStartOfNextTurn(this.TurnTaker);
                redirectWhenHit.UntilTargetLeavesPlay(hero);
                redirectWhenHit.UntilCardLeavesPlay(this.Card);
                redirectWhenHit.SourceCriteria.IsVillain      = true;
                redirectWhenHit.TargetCriteria.IsSpecificCard = hero;
                redirectWhenHit.BeforeOrAfter = BeforeOrAfter.Before;
                IEnumerator addRedirectCoroutine = AddStatusEffect(redirectWhenHit);
                //Log.Debug("Built redirectWhenHit for " + hero.Title);
                if (base.UseUnityCoroutines)
                {
                    yield return(this.GameController.StartCoroutine(addCantHitCoroutine));

                    yield return(this.GameController.StartCoroutine(addRedirectCoroutine));
                }
                else
                {
                    this.GameController.ExhaustCoroutine(addCantHitCoroutine);
                    this.GameController.ExhaustCoroutine(addRedirectCoroutine);
                }
            }

            string escapedNames = "";

            if (currentLowestHeroes.Any())
            {
                escapedNames = currentLowestHeroes.First().Title;
                if (currentLowestHeroes.Count > 1)
                {
                    escapedNames += " and " + currentLowestHeroes.ElementAt(1).Title;
                }
            }
            string blockedAnnouncement = escapedNames + " slip through Narrow Escape!";

            if (blockedHeroes.Any())
            {
                blockedAnnouncement += " All other heroes are BLOCKED!";
            }
            IEnumerator messageCoroutine = base.GameController.SendMessageAction(blockedAnnouncement, Priority.High, cardSource: GetCardSource(), showCardSource: true);

            if (base.UseUnityCoroutines)
            {
                yield return(this.GameController.StartCoroutine(messageCoroutine));
            }
            else
            {
                this.GameController.ExhaustCoroutine(messageCoroutine);
            }
            yield break;
        }