public IEnumerator DamageUnshellResponse(GameAction ga)
        {
            // "... the hero with the second highest HP may have the environment deal them {H + 1} projectile damage."
            List <Card>      secondHighestChoice = new List <Card>();
            DealDamageAction sample = new DealDamageAction(GetCardSource(), new DamageSource(base.GameController, FindEnvironment().TurnTaker), null, H + 1, DamageType.Projectile);
            IEnumerator      findSecondHighestCoroutine = base.GameController.FindTargetWithHighestHitPoints(2, (Card c) => c.IsHeroCharacterCard, secondHighestChoice, gameAction: sample, dealDamageInfo: sample.ToEnumerable(), evenIfCannotDealDamage: true, cardSource: GetCardSource());

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(findSecondHighestCoroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(findSecondHighestCoroutine);
            }
            Card secondHighest = secondHighestChoice.FirstOrDefault();

            if (secondHighest != null)
            {
                List <DealDamageAction> damageResult        = new List <DealDamageAction>();
                IEnumerator             heroDamageCoroutine = base.GameController.DealDamageToTarget(new DamageSource(base.GameController, FindEnvironment().TurnTaker), secondHighest, H + 1, DamageType.Projectile, optional: true, storedResults: damageResult, cardSource: GetCardSource());
                if (base.UseUnityCoroutines)
                {
                    yield return(base.GameController.StartCoroutine(heroDamageCoroutine));
                }
                else
                {
                    base.GameController.ExhaustCoroutine(heroDamageCoroutine);
                }
                DealDamageAction heroDamage = damageResult.FirstOrDefault();
                if (heroDamage != null && heroDamage.DidDealDamage && heroDamage.Target == secondHighest)
                {
                    Card shell = base.TurnTaker.FindCard("GiantPeanutShell");
                    // "If that hero takes damage this way, destroy a villain Ongoing card..."
                    IEnumerator destroyCoroutine = base.GameController.SelectAndDestroyCards(DecisionMaker, new LinqCardCriteria((Card c) => c.IsVillain && c.DoKeywordsContain("ongoing"), "villain Ongoing"), 1, requiredDecisions: 1, responsibleCard: base.Card, cardSource: GetCardSource());
                    if (base.UseUnityCoroutines)
                    {
                        yield return(base.GameController.StartCoroutine(destroyCoroutine));
                    }
                    else
                    {
                        base.GameController.ExhaustCoroutine(destroyCoroutine);
                    }
                    // "... and the environment deals {TheShelledOne} 4 projectile damage."
                    IEnumerator damageCoroutine = null;
                    if (base.CharacterCard.IsTarget)
                    {
                        damageCoroutine = base.GameController.DealDamageToTarget(new DamageSource(base.GameController, FindEnvironment().TurnTaker), base.CharacterCard, 4, DamageType.Projectile, cardSource: GetCardSource());
                    }
                    else
                    {
                        damageCoroutine = base.GameController.SendMessageAction(base.CharacterCard.Title + " is not a target.", Priority.Medium, GetCardSource(), showCardSource: true);
                    }
                    if (damageCoroutine != null)
                    {
                        if (base.UseUnityCoroutines)
                        {
                            yield return(base.GameController.StartCoroutine(damageCoroutine));
                        }
                        else
                        {
                            base.GameController.ExhaustCoroutine(damageCoroutine);
                        }
                    }
                }
            }
            yield break;
        }
        public override IEnumerator Play()
        {
            //Deal one Non-Hero Target 1 Melee Damage.
            List <DealDamageAction> storedResults = new List <DealDamageAction>();
            IEnumerator             coroutine     = GameController.SelectTargetsAndDealDamage(HeroTurnTakerController, new DamageSource(GameController, CharacterCard), 1, DamageType.Melee, 1, false, 1, additionalCriteria: (Card c) => !c.IsHero && c.IsTarget, storedResultsDamage: storedResults, cardSource: GetCardSource());

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(coroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(coroutine);
            }
            //If a Target takes Damage this way, another Hero deals that same Target 3 Irreducible Melee Damage.
            if (DidDealDamage(storedResults))
            {
                Card target = storedResults.First().Target;
                if (target.IsInPlayAndHasGameText)
                {
                    DealDamageAction fakeDamage = new DealDamageAction(GameController, new DamageSource(GameController, CharacterCard), target, 3, DamageType.Melee, isIrreducible: true);
                    List <SelectTurnTakerDecision> storedHero = new List <SelectTurnTakerDecision>();
                    coroutine = GameController.SelectHeroTurnTaker(HeroTurnTakerController, SelectionType.DealDamage, optional: false, allowAutoDecide: false, storedResults: storedHero, heroCriteria: new LinqTurnTakerCriteria(tt => tt != TurnTaker), gameAction: fakeDamage, cardSource: GetCardSource());
                    if (base.UseUnityCoroutines)
                    {
                        yield return(base.GameController.StartCoroutine(coroutine));
                    }
                    else
                    {
                        base.GameController.ExhaustCoroutine(coroutine);
                    }
                    if (DidSelectTurnTaker(storedHero))
                    {
                        TurnTaker selectedTurnTaker = GetSelectedTurnTaker(storedHero);
                        Card      source            = selectedTurnTaker.CharacterCard;
                        if (selectedTurnTaker.HasMultipleCharacterCards)
                        {
                            List <Card> storedSource = new List <Card>();
                            coroutine = FindCharacterCard(selectedTurnTaker, SelectionType.HeroToDealDamage, storedSource, additionalCriteria: c => c.IsInPlayAndHasGameText, damageInfo: fakeDamage.ToEnumerable());
                            if (base.UseUnityCoroutines)
                            {
                                yield return(base.GameController.StartCoroutine(coroutine));
                            }
                            else
                            {
                                base.GameController.ExhaustCoroutine(coroutine);
                            }
                            source = storedSource.First();
                        }

                        coroutine = DealDamage(source, target, 3, DamageType.Melee, isIrreducible: true, cardSource: GetCardSource());
                        if (base.UseUnityCoroutines)
                        {
                            yield return(base.GameController.StartCoroutine(coroutine));
                        }
                        else
                        {
                            base.GameController.ExhaustCoroutine(coroutine);
                        }
                    }
                }
            }

            //One Hero may Draw a Card.
            coroutine = GameController.SelectHeroToDrawCard(HeroTurnTakerController, cardSource: GetCardSource());
            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(coroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(coroutine);
            }
            yield break;
        }
        public IEnumerator ExplosionResponse(CardEntersPlayAction cepa)
        {
            // "... this card deals the non-environment target with the highest HP in each other play area 1 energy damage, ..."
            DealDamageAction previewDamage = new DealDamageAction(GetCardSource(), new DamageSource(base.GameController, base.Card), null, 1, DamageType.Energy);
            List <Location>  playAreas     = new List <Location>();

            // Get each other play area
            foreach (TurnTaker tt in base.GameController.AllTurnTakers)
            {
                Location ttPlayArea = tt.PlayArea;
                if (ttPlayArea.HighestRecursiveLocation != base.Card.Location.HighestRecursiveLocation)
                {
                    playAreas.Add(ttPlayArea);
                }
            }
            // For each other play area, find its non-environment target with the highest HP
            List <Card> highestTargets = new List <Card>();

            foreach (Location playArea in playAreas)
            {
                if (playArea.Cards.Any((Card c) => c.IsTarget && !c.IsEnvironment))
                {
                    List <Card> localHighest  = new List <Card>();
                    IEnumerator findCoroutine = base.GameController.FindTargetWithHighestHitPoints(1, (Card c) => c.Location.HighestRecursiveLocation == playArea && !c.IsEnvironment, localHighest, dealDamageInfo: previewDamage.ToEnumerable(), cardSource: GetCardSource());
                    if (base.UseUnityCoroutines)
                    {
                        yield return(base.GameController.StartCoroutine(findCoroutine));
                    }
                    else
                    {
                        base.GameController.ExhaustCoroutine(findCoroutine);
                    }
                    if (localHighest != null && localHighest.Count() > 0)
                    {
                        highestTargets.Add(localHighest.FirstOrDefault());
                    }
                }
            }
            IEnumerator explodeCoroutine = base.DealDamage(base.Card, (Card c) => highestTargets.Contains(c), 1, DamageType.Energy);

            if (base.UseUnityCoroutines)
            {
                yield return(base.GameController.StartCoroutine(explodeCoroutine));
            }
            else
            {
                base.GameController.ExhaustCoroutine(explodeCoroutine);
            }
            // "then deals itself 1 energy damage."
            IEnumerator selfDamageCoroutine = base.DealDamage(base.Card, base.Card, 1, DamageType.Energy, cardSource: GetCardSource());

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