Example #1
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = source.getSourceObject(game);
   if (sourceObject != null && controller != null) {
     TargetCardInYourGraveyard target =
         new TargetCardInYourGraveyard(
             new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"));
     if (controller.chooseTarget(outcome, target, source, game)) {
       UUID exileId =
           CardUtil.getExileZoneId(
               game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
       Card card = controller.getGraveyard().get(target.getFirstTarget(), game);
       if (card != null) {
         controller.moveCardToExileWithInfo(
             card,
             exileId,
             sourceObject.getIdName(),
             source.getSourceId(),
             game,
             Zone.GRAVEYARD,
             true);
       }
     }
     return true;
   }
   return false;
 }
Example #2
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller != null) {
      Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source));
      if (damagedPlayer == null) {
        return false;
      }
      FilterCard filter =
          new FilterCard(
              "target instant or sorcery card from " + damagedPlayer.getName() + "'s graveyard");
      filter.add(new OwnerIdPredicate(damagedPlayer.getId()));
      filter.add(
          Predicates.or(
              new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));

      Target target = new TargetCardInGraveyard(filter);
      if (controller.chooseTarget(Outcome.PlayForFree, target, source, game)) {
        Card card = game.getCard(target.getFirstTarget());
        if (card != null) {
          controller.cast(card.getSpellAbility(), game, true);
          game.addEffect(new WrexialReplacementEffect(card.getId()), source);
        }
      }
      return true;
    }
    return false;
  }
Example #3
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player player = game.getPlayer(targetPointer.getFirst(game, source));
   if (player == null) {
     return false;
   }
   if (player.getLife() > 2
       && player.chooseUse(
           Outcome.Neutral,
           "Pay 2 life? If you don't, return a permanent you control to its owner's hand.",
           game)) {
     player.loseLife(2, game);
     game.informPlayers(
         player.getName() + " pays 2 life. He will not return a permanent he or she controls.");
     return true;
   } else {
     Target target = new TargetControlledPermanent();
     if (target.canChoose(source.getSourceId(), player.getId(), game)
         && player.chooseTarget(outcome, target, source, game)) {
       Permanent permanent = game.getPermanent(target.getFirstTarget());
       if (permanent != null) {
         game.informPlayers(player.getName() + " returns " + permanent.getName() + " to hand.");
         return permanent.moveToZone(Zone.HAND, source.getSourceId(), game, false);
       }
     }
   }
   return false;
 }
Example #4
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   Permanent permanent = (Permanent) game.getLastKnownInformation(target, Zone.BATTLEFIELD);
   if (permanent != null && controller != null) {
     Player player = game.getPlayer(permanent.getOwnerId());
     if (player != null) {
       FilterCreatureCard filter =
           new FilterCreatureCard(
               new StringBuilder("a creature card from ")
                   .append(player.getLogName())
                   .append("'s graveyard")
                   .toString());
       filter.add(new OwnerIdPredicate(player.getId()));
       Target targetCreature = new TargetCardInGraveyard(filter);
       if (targetCreature.canChoose(source.getSourceId(), controller.getId(), game)
           && controller.chooseTarget(outcome, targetCreature, source, game)) {
         Card card = game.getCard(targetCreature.getFirstTarget());
         if (card != null && game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) {
           return card.putOntoBattlefield(
               game, Zone.GRAVEYARD, source.getSourceId(), player.getId());
         }
       }
       return true;
     }
   }
   return false;
 }
Example #5
0
  /**
   * Checks all available splice effects to be applied.
   *
   * @param abilityToModify
   * @param game
   */
  public void applySpliceEffects(Ability abilityToModify, Game game) {
    if (((SpellAbility) abilityToModify).getSpellAbilityType().equals(SpellAbilityType.SPLICE)) {
      // on a spliced ability of a spell can't be spliced again
      return;
    }
    List<SpliceCardEffect> spliceEffects =
        getApplicableSpliceCardEffects(game, abilityToModify.getControllerId());
    // get the applyable splice abilities
    List<SpliceOntoArcaneAbility> spliceAbilities = new ArrayList<>();
    for (SpliceCardEffect effect : spliceEffects) {
      HashSet<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        if (effect.applies(abilityToModify, ability, game)) {
          spliceAbilities.add((SpliceOntoArcaneAbility) ability);
        }
      }
    }
    // check if player wants to use splice

    if (spliceAbilities.size() > 0) {
      Player controller = game.getPlayer(abilityToModify.getControllerId());
      if (controller.chooseUse(Outcome.Benefit, "Splice a card?", game)) {
        Cards cardsToReveal = new CardsImpl();
        do {
          FilterCard filter = new FilterCard("a card to splice");
          ArrayList<Predicate<MageObject>> idPredicates = new ArrayList<>();
          for (SpliceOntoArcaneAbility ability : spliceAbilities) {
            idPredicates.add(new CardIdPredicate((ability.getSourceId())));
          }
          filter.add(Predicates.or(idPredicates));
          TargetCardInHand target = new TargetCardInHand(filter);
          controller.chooseTarget(Outcome.Benefit, target, abilityToModify, game);
          UUID cardId = target.getFirstTarget();
          if (cardId != null) {
            SpliceOntoArcaneAbility selectedAbility = null;
            for (SpliceOntoArcaneAbility ability : spliceAbilities) {
              if (ability.getSourceId().equals(cardId)) {
                selectedAbility = ability;
                break;
              }
            }
            if (selectedAbility != null) {
              SpliceCardEffect spliceEffect =
                  (SpliceCardEffect) selectedAbility.getEffects().get(0);
              spliceEffect.apply(game, selectedAbility, abilityToModify);
              cardsToReveal.add(game.getCard(cardId));
              spliceAbilities.remove(selectedAbility);
            }
          }
        } while (!spliceAbilities.isEmpty()
            && controller.chooseUse(Outcome.Benefit, "Splice another card?", game));
        controller.revealCards("Spliced cards", cardsToReveal, game);
      }
    }
  }
Example #6
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = game.getObject(source.getSourceId());
   if (sourceObject != null && controller != null) {
     Cards cards = new CardsImpl();
     cards.addAll(controller.getLibrary().getTopCards(game, 3));
     if (!cards.isEmpty()) {
       controller.revealCards(staticText, cards, game);
       Card cardToGraveyard;
       if (cards.size() == 1) {
         cardToGraveyard = cards.getRandom(game);
       } else {
         Player opponent;
         Set<UUID> opponents = game.getOpponents(controller.getId());
         if (opponents.size() == 1) {
           opponent = game.getPlayer(opponents.iterator().next());
         } else {
           Target target = new TargetOpponent(true);
           controller.chooseTarget(Outcome.Detriment, target, source, game);
           opponent = game.getPlayer(target.getFirstTarget());
         }
         TargetCard target = new TargetCard(1, Zone.LIBRARY, new FilterCard());
         opponent.chooseTarget(outcome, cards, target, source, game);
         cardToGraveyard = game.getCard(target.getFirstTarget());
       }
       if (cardToGraveyard != null) {
         controller.moveCards(cardToGraveyard, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
         cards.remove(cardToGraveyard);
       }
       controller.moveCards(cards, Zone.LIBRARY, Zone.HAND, source, game);
     }
     return true;
   }
   return false;
 }
Example #7
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   if (controller != null) {
     Target target = new TargetSource();
     target.setRequired(true);
     target.setNotTarget(true);
     if (controller.chooseTarget(outcome, target, source, game)) {
       ContinuousEffect continuousEffect = new InterventionPactPreventDamageEffect();
       continuousEffect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
       game.addEffect(continuousEffect, source);
     }
     return true;
   }
   return false;
 }
Example #8
0
 @Override
 public boolean resolve(Game game) {
   int manaX = this.getManaCostsToPay().getX();
   FilterPermanent filter =
       new FilterCreaturePermanent("creature with power " + manaX + " or less");
   filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, manaX + 1));
   Target target = new TargetPermanent(filter);
   Player player = game.getPlayer(controllerId);
   if (player != null) {
     if (player.chooseTarget(Outcome.Benefit, target, this, game)) {
       this.getEffects().get(0).setTargetPointer(new FixedTarget(target.getFirstTarget()));
       return super.resolve(game);
     }
   }
   return false;
 }
  @Override
  public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    if (player == null) {
      return false;
    }

    int cmc = 0;
    for (Cost cost : source.getCosts()) {
      if (cost instanceof PayVariableLoyaltyCost) {
        cmc = ((PayVariableLoyaltyCost) cost).getAmount();
      }
    }

    FilterCard filter =
        new FilterCreatureCard(
            new StringBuilder("creature card with converted mana cost {")
                .append(cmc)
                .append("} exiled with Ashiok, Nightmare Weaver")
                .toString());
    filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, cmc));
    Target target = new TargetCardInExile(filter, CardUtil.getCardExileZoneId(game, source));

    if (target.canChoose(source.getSourceId(), player.getId(), game)) {
      if (player.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) {
        Card card = game.getCard(target.getFirstTarget());
        if (card != null
            && player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId())) {
          Permanent permanent = game.getPermanent(card.getId());
          if (permanent != null) {
            permanent.changeControllerId(source.getControllerId(), game);
          }
          ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect();
          effect.setTargetPointer(new FixedTarget(card.getId()));
          game.addEffect(effect, source);
          return true;
        }
      }
    }
    return false;
  }
Example #10
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player targetPlayer = game.getPlayer(source.getFirstTarget());
   Player controller = game.getPlayer(source.getControllerId());
   if (targetPlayer != null && controller != null) {
     TargetCardInYourGraveyard target = new TargetCardInYourGraveyard();
     target.setRequired(true);
     if (targetPlayer.chooseTarget(Outcome.Exile, target, source, game)) {
       Card card = game.getCard(target.getFirstTarget());
       if (card != null) {
         targetPlayer.getGraveyard().remove(card);
         card.moveToExile(null, "", source.getId(), game);
         if (card.getCardType().contains(CardType.CREATURE)) {
           controller.gainLife(2, game);
         }
       }
       return true;
     }
   }
   return false;
 }
Example #11
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
    Player controller = game.getPlayer(source.getControllerId());
    if (player == null || controller == null) {
      return false;
    }

    Cards cards = new CardsImpl();
    cards.addAll(player.getLibrary().getTopCards(game, 7));
    controller.moveCards(cards, Zone.EXILED, source, game);
    if (cards.getCards(new FilterCreatureCard(), game).size() > 0) {
      TargetCard target = new TargetCard(Zone.EXILED, new FilterCreatureCard());
      if (controller.chooseTarget(outcome, cards, target, source, game)) {
        Card card = cards.get(target.getFirstTarget(), game);
        if (card != null) {
          controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null);
        }
      }
    }
    return true;
  }
Example #12
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller != null) {
      boolean targetChosen = false;
      TargetPermanent target = new TargetPermanent(1, 1, filter, true);
      if (target.canChoose(controller.getId(), game)
          && controller.chooseUse(
              outcome, "Return another creature you control to its owner's hand?", source, game)) {
        controller.chooseTarget(Outcome.ReturnToHand, target, source, game);
        Permanent permanent = game.getPermanent(target.getFirstTarget());
        if (permanent != null) {
          targetChosen = true;
          permanent.moveToZone(Zone.HAND, this.getId(), game, false);
        }
      }

      if (!targetChosen) {
        new SacrificeSourceEffect().apply(game, source);
      }
      return true;
    }
    return false;
  }
Example #13
0
  /**
   * @param game
   * @param playerId
   * @param forceChange - does only work for targets with maximal one targetId
   * @param onlyOneTarget - 114.6b one target must be changed to another target
   * @return
   */
  public boolean chooseNewTargets(
      Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget) {
    Player player = game.getPlayer(playerId);
    if (player != null) {
      for (SpellAbility spellAbility : spellAbilities) {
        for (Target target : spellAbility.getTargets()) {
          Target newTarget = target.copy();
          newTarget.clearChosen();
          for (UUID targetId : target.getTargets()) {
            MageObject object = game.getObject(targetId);
            String name = null;
            if (object == null) {
              Player targetPlayer = game.getPlayer(targetId);
              if (targetPlayer != null) {
                name = targetPlayer.getName();
              }
            } else {
              name = object.getName();
            }
            if (name != null
                && (forceChange
                    || player.chooseUse(
                        spellAbility.getEffects().get(0).getOutcome(),
                        "Change target from " + name + "?",
                        game))) {
              if (forceChange
                  && target.possibleTargets(this.getSourceId(), playerId, game).size() > 1) {
                int iteration = 0;
                do {
                  if (iteration > 0) {
                    game.informPlayer(
                        player,
                        "You may only select exactly one target that must be different from the origin target!");
                  }
                  iteration++;
                  newTarget.clearChosen();
                  player.chooseTarget(
                      spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game);
                } while (targetId.equals(newTarget.getFirstTarget())
                    || newTarget.getTargets().size() != 1);

              } else {
                if (!player.chooseTarget(
                    spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game)) {
                  newTarget.addTarget(targetId, spellAbility, game, false);
                }
              }
            } else {
              newTarget.addTarget(targetId, spellAbility, game, false);
            }
          }
          target.clearChosen();
          for (UUID newTargetId : newTarget.getTargets()) {
            target.addTarget(newTargetId, spellAbility, game, false);
          }
        }
      }
      return true;
    }
    return false;
  }
Example #14
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    if (player == null) {
      return false;
    }

    Cards cards = new CardsImpl();
    int count = Math.min(player.getLibrary().size(), 3);
    for (int i = 0; i < count; i++) {
      Card card = player.getLibrary().removeFromTop(game);
      if (card != null) {
        cards.add(card);
      }
    }
    player.revealCards("Jace, Architect of Thought", cards, game);

    Set<UUID> opponents = game.getOpponents(source.getControllerId());
    if (!opponents.isEmpty()) {
      Player opponent = null;
      if (opponents.size() > 1) {
        TargetOpponent targetOpponent = new TargetOpponent();
        if (player.chooseTarget(Outcome.Neutral, targetOpponent, source, game)) {
          opponent = game.getPlayer(targetOpponent.getFirstTarget());
        }
      }
      if (opponent == null) {
        opponent = game.getPlayer(opponents.iterator().next());
      }

      TargetCard target =
          new TargetCard(
              0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
      target.setRequired(false);
      Cards pile1 = new CardsImpl();
      if (opponent.choose(Outcome.Neutral, cards, target, game)) {
        for (UUID targetId : (List<UUID>) target.getTargets()) {
          Card card = cards.get(targetId, game);
          if (card != null) {
            pile1.add(card);
            cards.remove(card);
          }
        }
      }
      player.revealCards("Pile 1 (Jace, Architect of Thought)", pile1, game);
      player.revealCards("Pile 2 (Jace, Architect of Thought)", cards, game);

      postPileToLog("Pile 1", pile1.getCards(game), game);
      postPileToLog("Pile 2", cards.getCards(game), game);

      Cards cardsToHand = cards;
      Cards cardsToLibrary = pile1;
      List<Card> cardPile1 = new ArrayList<>();
      List<Card> cardPile2 = new ArrayList<>();
      for (UUID cardId : pile1) {
        cardPile1.add(game.getCard(cardId));
      }
      for (UUID cardId : cards) {
        cardPile2.add(game.getCard(cardId));
      }

      boolean pileChoice =
          player.choosePile(
              Outcome.Neutral,
              "Choose a pile to to put into your hand.",
              cardPile1,
              cardPile2,
              game);
      if (pileChoice) {
        cardsToHand = pile1;
        cardsToLibrary = cards;
      }
      game.informPlayers(player.getLogName() + " chose pile" + (pileChoice ? "1" : "2"));

      for (UUID cardUuid : cardsToHand) {
        Card card = cardsToHand.get(cardUuid, game);
        if (card != null) {
          player.moveCards(card, null, Zone.HAND, source, game);
        }
      }

      player.putCardsOnBottomOfLibrary(cardsToLibrary, game, source, true);
      return true;
    }
    return false;
  }
  @Override
  public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(targetPointer.getFirst(game, source));
    Player controller = game.getPlayer(source.getControllerId());
    Card sourceCard = game.getCard(source.getSourceId());
    if (player != null && controller != null) {
      if (revealAllCards) {
        this.numberCardsToReveal = new StaticValue(player.getHand().size());
      }
      int numberToReveal = this.numberCardsToReveal.calculate(game, source, this);
      if (numberToReveal > 0) {
        Cards revealedCards = new CardsImpl(Zone.HAND);
        numberToReveal = Math.min(player.getHand().size(), numberToReveal);
        if (player.getHand().size() > numberToReveal) {
          TargetCardInHand chosenCards =
              new TargetCardInHand(
                  numberToReveal,
                  numberToReveal,
                  new FilterCard("card in " + player.getLogName() + "'s hand"));
          chosenCards.setNotTarget(true);
          if (chosenCards.canChoose(player.getId(), game)
              && player.chooseTarget(
                  Outcome.Discard, player.getHand(), chosenCards, source, game)) {
            if (!chosenCards.getTargets().isEmpty()) {
              List<UUID> targets = chosenCards.getTargets();
              for (UUID targetid : targets) {
                Card card = game.getCard(targetid);
                if (card != null) {
                  revealedCards.add(card);
                }
              }
            }
          }
        } else {
          revealedCards.addAll(player.getHand());
        }

        player.revealCards(
            sourceCard != null ? sourceCard.getName() : "Discard", revealedCards, game);

        boolean result = true;
        int filteredCardsCount =
            revealedCards.count(filter, source.getSourceId(), source.getControllerId(), game);
        int numberToDiscard =
            Math.min(this.numberCardsToDiscard.calculate(game, source, this), filteredCardsCount);
        if (numberToDiscard > 0) {
          TargetCard target = new TargetCard(numberToDiscard, Zone.HAND, filter);
          if (controller.choose(Outcome.Benefit, revealedCards, target, game)) {
            for (Object targetId : target.getTargets()) {
              Card card = revealedCards.get((UUID) targetId, game);
              if (card != null) {
                if (!player.discard(card, source, game)) {
                  result = false;
                }
              }
            }
          }
        }
        return result;
      }
      return true;
    }
    return false;
  }
Example #16
0
  @Override
  public void adjustCosts(Ability ability, Game game) {
    Player player = game.getPlayer(controllerId);
    if (player == null || !(ability instanceof SpellAbility)) {
      return;
    }
    Target target = new TargetControlledCreaturePermanent(1, Integer.MAX_VALUE, filter, true);
    target.setTargetName("creatures to convoke");
    if (!target.canChoose(sourceId, controllerId, game)) {
      return;
    }
    if (player.chooseUse(Outcome.Detriment, "Convoke creatures?", game)) {
      player.chooseTarget(Outcome.Tap, target, ability, game);
      if (target.getTargets().size() > 0) {
        int adjCost = 0;
        for (UUID creatureId : target.getTargets()) {
          Permanent perm = game.getPermanent(creatureId);
          if (perm == null) {
            continue;
          }
          ManaCosts manaCostsCreature = perm.getSpellAbility().getManaCosts();
          if (manaCostsCreature != null
              && manaCostsCreature.convertedManaCost() > 0
              && perm.tap(game)) {
            Choice chooseManaType = buildChoice(manaCostsCreature, ability.getManaCostsToPay());
            if (chooseManaType.getChoices().size() > 0) {
              if (chooseManaType.getChoices().size() > 1) {
                chooseManaType.getChoices().add("Colorless");
                chooseManaType.setMessage("Choose mana color to reduce from " + perm.getName());
                while (!chooseManaType.isChosen()) {
                  player.choose(Outcome.Benefit, chooseManaType, game);
                }
              } else {
                chooseManaType.setChoice(chooseManaType.getChoices().iterator().next());
              }

              ManaCosts manaCostsToReduce = new ManaCostsImpl();
              if (chooseManaType.getChoice().equals("Black")) {
                manaCostsToReduce.load("{B}");
              }
              if (chooseManaType.getChoice().equals("Blue")) {
                manaCostsToReduce.load("{U}");
              }
              if (chooseManaType.getChoice().equals("Green")) {
                manaCostsToReduce.load("{G}");
              }
              if (chooseManaType.getChoice().equals("White")) {
                manaCostsToReduce.load("{W}");
              }
              if (chooseManaType.getChoice().equals("Red")) {
                manaCostsToReduce.load("{R}");
              }
              if (chooseManaType.getChoice().equals("Colorless")) {
                ++adjCost;
              }
              CardUtil.adjustCost((SpellAbility) ability, manaCostsToReduce);
            } else {
              ++adjCost;
            }
          }
        }
        this.getTargets().add(target);
        CardUtil.adjustCost((SpellAbility) ability, adjCost);
      }
    }
  }
Example #17
0
  @Override
  public boolean apply(Game game, Ability source) {
    List<Card> chosen = new ArrayList<>();

    for (UUID playerId : game.getPlayerList()) {
      Player player = game.getPlayer(playerId);

      Target target1 =
          new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent(), true);
      Target target2 =
          new TargetControlledPermanent(1, 1, new FilterControlledCreaturePermanent(), true);
      Target target3 =
          new TargetControlledPermanent(1, 1, new FilterControlledEnchantmentPermanent(), true);
      Target target4 =
          new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent(), true);

      if (target1.canChoose(player.getId(), game)) {
        while (player.canRespond()
            && !target1.isChosen()
            && target1.canChoose(player.getId(), game)) {
          player.chooseTarget(Outcome.Benefit, target1, source, game);
        }
        Permanent artifact = game.getPermanent(target1.getFirstTarget());
        if (artifact != null) {
          chosen.add(artifact);
        }
        target1.clearChosen();
      }

      if (target2.canChoose(player.getId(), game)) {
        while (player.canRespond()
            && !target2.isChosen()
            && target2.canChoose(player.getId(), game)) {
          player.chooseTarget(Outcome.Benefit, target2, source, game);
        }
        Permanent creature = game.getPermanent(target2.getFirstTarget());
        if (creature != null) {
          chosen.add(creature);
        }
        target2.clearChosen();
      }

      if (target3.canChoose(player.getId(), game)) {
        while (player.canRespond()
            && !target3.isChosen()
            && target3.canChoose(player.getId(), game)) {
          player.chooseTarget(Outcome.Benefit, target3, source, game);
        }
        Permanent enchantment = game.getPermanent(target3.getFirstTarget());
        if (enchantment != null) {
          chosen.add(enchantment);
        }
        target3.clearChosen();
      }

      if (target4.canChoose(player.getId(), game)) {
        while (player.canRespond()
            && !target4.isChosen()
            && target4.canChoose(player.getId(), game)) {
          player.chooseTarget(Outcome.Benefit, target4, source, game);
        }
        Permanent land = game.getPermanent(target4.getFirstTarget());
        if (land != null) {
          chosen.add(land);
        }
        target4.clearChosen();
      }
    }

    for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
      if (!chosen.contains(permanent)) {
        permanent.sacrifice(source.getSourceId(), game);
      }
    }
    return true;
  }