@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;
  }
  public boolean applySearchAndExile(
      Game game, Ability source, String cardName, UUID targetPlayerId) {
    Player player = game.getPlayer(source.getControllerId());
    if (cardName != null && player != null) {
      Player targetPlayer = game.getPlayer(targetPlayerId);
      if (targetPlayer != null) {
        FilterCard filter = new FilterCard("card named " + cardName);
        filter.add(new NamePredicate(cardName));

        // cards in Graveyard
        int cardsCount = (cardName.isEmpty() ? 0 : targetPlayer.getGraveyard().count(filter, game));
        if (cardsCount > 0) {
          filter.setMessage(
              "card named " + cardName + " in the graveyard of " + targetPlayer.getName());
          TargetCardInGraveyard target =
              new TargetCardInGraveyard(
                  (graveyardExileOptional ? 0 : cardsCount), cardsCount, filter);
          if (player.choose(Outcome.Exile, targetPlayer.getGraveyard(), target, game)) {
            List<UUID> targets = target.getTargets();
            for (UUID targetId : targets) {
              Card targetCard = targetPlayer.getGraveyard().get(targetId, game);
              if (targetCard != null) {
                targetPlayer.getGraveyard().remove(targetCard);
                targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
              }
            }
          }
        }

        // cards in Hand
        cardsCount = (cardName.isEmpty() ? 0 : targetPlayer.getHand().count(filter, game));
        if (cardsCount > 0) {
          filter.setMessage("card named " + cardName + " in the hand of " + targetPlayer.getName());
          TargetCardInHand target = new TargetCardInHand(0, cardsCount, filter);
          if (player.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) {
            List<UUID> targets = target.getTargets();
            for (UUID targetId : targets) {
              Card targetCard = targetPlayer.getHand().get(targetId, game);
              if (targetCard != null) {
                targetPlayer.getHand().remove(targetCard);
                targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
              }
            }
          }
        } else {
          if (targetPlayer.getHand().size() > 0) {
            player.lookAtCards(targetPlayer.getName() + " hand", targetPlayer.getHand(), game);
          }
        }

        // cards in Library
        Cards cardsInLibrary = new CardsImpl(Zone.LIBRARY);
        cardsInLibrary.addAll(targetPlayer.getLibrary().getCards(game));
        cardsCount = (cardName.isEmpty() ? 0 : cardsInLibrary.count(filter, game));
        if (cardsCount > 0) {
          filter.setMessage(
              "card named " + cardName + " in the library of " + targetPlayer.getName());
          TargetCardInLibrary target = new TargetCardInLibrary(0, cardsCount, filter);
          if (player.choose(Outcome.Exile, cardsInLibrary, target, game)) {
            List<UUID> targets = target.getTargets();
            for (UUID targetId : targets) {
              Card targetCard = targetPlayer.getLibrary().remove(targetId, game);
              if (targetCard != null) {
                targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
              }
            }
          }
        } else {
          player.lookAtCards(targetPlayer.getName() + " library", cardsInLibrary, game);
        }
      }

      targetPlayer.shuffleLibrary(game);

      return true;
    }

    return false;
  }
Esempio n. 3
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    Permanent enchantment = game.getPermanent(source.getSourceId());

    if (player == null || enchantment.getAttachedTo() == null) {
      return false;
    }

    Permanent creature = game.getPermanent(enchantment.getAttachedTo());
    if (creature == null) {
      return false;
    }

    Cards cards = new CardsImpl(Zone.PICK);
    int count = Math.min(player.getLibrary().size(), 5);
    for (int i = 0; i < count; i++) {
      Card card = player.getLibrary().removeFromTop(game);
      if (card != null) {
        cards.add(card);
        game.setZone(card.getId(), Zone.PICK);
      }
    }
    player.lookAtCards("Call to the Kindred", cards, game);

    FilterCreatureCard filter = new FilterCreatureCard();
    StringBuilder sb = new StringBuilder("creature card with at least one subtype from: ");
    ArrayList<Predicate<MageObject>> subtypes = new ArrayList<Predicate<MageObject>>();
    for (String subtype : creature.getSubtype()) {
      subtypes.add(new SubtypePredicate(subtype));
      sb.append(subtype).append(", ");
    }
    filter.add(Predicates.or(subtypes));
    sb.delete(sb.length() - 2, sb.length());
    filter.setMessage(sb.toString());

    if (cards.count(filter, game) > 0
        && player.chooseUse(
            Outcome.DrawCard,
            "Do you wish to put a creature card onto the battlefield?",
            source,
            game)) {
      TargetCard target = new TargetCard(Zone.PICK, filter);

      if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
        Card card = cards.get(target.getFirstTarget(), game);
        if (card != null) {
          cards.remove(card);
          card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), source.getControllerId());
        }
      }
    }

    TargetCard target =
        new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
    while (player.isInGame() && cards.size() > 1) {
      player.choose(Outcome.Neutral, cards, target, game);
      Card card = cards.get(target.getFirstTarget(), game);
      if (card != null) {
        cards.remove(card);
        card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
      }
      target.clearChosen();
    }
    if (cards.size() == 1) {
      Card card = cards.get(cards.iterator().next(), game);
      card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
    }

    return true;
  }