@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; }
@Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { FilterCard filter = new FilterCard("red instant or sorcery card from your graveyard to play"); filter.add(new ColorPredicate(ObjectColor.RED)); filter.add( Predicates.or( new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); String message = "Play red instant or sorcery card from your graveyard without paying its mana cost?"; Set<Card> cards = player.getGraveyard().getCards(filter, game); TargetCardInGraveyard target = new TargetCardInGraveyard(filter); while (!cards.isEmpty() && player.chooseUse(outcome, message, source, game)) { target.clearChosen(); if (player.choose(outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { player.cast(card.getSpellAbility(), game, true); player.getGraveyard().remove(card); cards.remove(card); } } } return true; } return false; }
@Override public boolean apply(Game game, Ability source) { FilterCard protectionFilter = (FilterCard) ((ProtectionAbility) ability).getFilter(); protectionFilter.add(new ColorPredicate(choice.getColor())); protectionFilter.setMessage(choice.getChoice()); ((ProtectionAbility) ability).setFilter(protectionFilter); return super.apply(game, source); }
Cards ProteanHulkSearch(Game game, Ability source) { Cards cardsPicked = new CardsImpl(Zone.PICK); Player player = game.getPlayer(source.getControllerId()); if (player != null) { GameEvent event = GameEvent.getEvent( GameEvent.EventType.SEARCH_LIBRARY, source.getControllerId(), source.getControllerId(), source.getControllerId(), Integer.MAX_VALUE); if (!game.replaceEvent(event)) { int manaCostLeftToFetch = 6; int librarySearchLimit = event.getAmount(); FilterCard filter = new FilterCreatureCard( "number of creature cards with total converted mana cost 6 or less (6 CMC left)"); filter.add( new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); target.setCardLimit(librarySearchLimit); while (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { target.choose( Outcome.PutCreatureInPlay, source.getControllerId(), source.getControllerId(), game); Card card = player.getLibrary().remove(target.getFirstTarget(), game); if (card == null) { break; } cardsPicked.add(card); game.setZone(card.getId(), Zone.PICK); game.getState().getLookedAt(source.getControllerId()).add("Protean Hulk", cardsPicked); librarySearchLimit--; if (librarySearchLimit == 0) { break; } manaCostLeftToFetch -= card.getManaCost().convertedManaCost(); filter = new FilterCreatureCard( "number of creature cards with total converted mana cost 6 or less (" + manaCostLeftToFetch + " CMC left)"); filter.add( new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); target = new TargetCardInLibrary(0, 1, filter); target.setCardLimit(librarySearchLimit); } game.fireEvent( GameEvent.getEvent( GameEvent.EventType.LIBRARY_SEARCHED, source.getControllerId(), source.getControllerId())); } } return cardsPicked; }
/** * 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); } } }
@Override public boolean apply(Game game, Ability source) { Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (creature != null) { FilterCard protectionFilter = (FilterCard) ((ProtectionAbility) ability).getFilter(); protectionFilter.add(new ColorPredicate(choice.getColor())); protectionFilter.setMessage(choice.getChoice()); ((ProtectionAbility) ability).setFilter(protectionFilter); creature.addAbility(ability, source.getSourceId(), game); return true; } return false; }
public TargetCardInExile( int minNumTargets, int maxNumTargets, FilterCard filter, UUID zoneId, boolean allExileZones) { super(minNumTargets, maxNumTargets, Zone.EXILED, filter); this.zoneId = zoneId; this.allExileZones = allExileZones; this.targetName = filter.getMessage(); }
static { filter.add(new ControllerPredicate(TargetController.YOU)); filterCard.add( Predicates.or( new SubtypePredicate("Aura"), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.PLANESWALKER))); }
public boolean apply(Game game, Ability source) { Permanent target = game.getPermanent(source.getFirstTarget()); if (target != null) { for (ObjectColor color : target.getColor(game).getColors()) { FilterCard filter = new FilterCard(color.getDescription()); filter.add(new ColorPredicate(color)); game.addEffect( new GainAbilityControlledEffect( new ProtectionAbility(filter), Duration.EndOfTurn, new FilterControlledCreaturePermanent()), source); } return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { FilterCard filter = new FilterCard("instant card"); filter.add(new CardTypePredicate(CardType.INSTANT)); Card[] cards = player.getGraveyard().getCards(filter, game).toArray(new Card[0]); if (cards.length > 0) { Random rnd = new Random(); Card card = cards[rnd.nextInt(cards.length)]; card.moveToZone(Zone.HAND, source.getSourceId(), game, true); game.informPlayers(card.getName() + "returned to the hand of" + player.getName()); return true; } } return false; }
static { filter.add( Predicates.or( new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ENCHANTMENT), new CardTypePredicate(CardType.LAND))); }
private String setText() { StringBuilder sb = new StringBuilder("Target "); switch (targetController) { case OPPONENT: sb.append("opponent"); break; case ANY: sb.append("player"); break; default: throw new UnsupportedOperationException("target controller not supported"); } if (revealAllCards) { sb.append(" reveals his or her hand"); } else { if (numberCardsToReveal instanceof StaticValue) { sb.append(" reveales "); sb.append(numberCardsToReveal.getMessage()); sb.append(" from his or her hand"); } else { sb.append(" reveals a number of cards from his or her hand equal to "); sb.append(numberCardsToReveal.getMessage()); } } sb.append(". You choose "); boolean discardMultipleCards = !numberCardsToDiscard.toString().equals("1"); if (discardMultipleCards) { sb.append(numberCardsToDiscard).append(" "); } else { if (!filter.getMessage().startsWith("a ") && !filter.getMessage().startsWith("an ")) { sb.append("a "); } } sb.append(filter.getMessage()); if (revealAllCards) { sb.append(" from it."); } else { sb.append(" of them."); } sb.append(" That player discards ") .append(discardMultipleCards ? "those cards" : "that card") .toString(); return sb.toString(); }
@Override public boolean apply(Game game, Ability source) { Cards cardsToCast = new CardsImpl(); Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = source.getSourceObject(game); if (targetOpponent != null && sourceObject != null) { List<Card> allCards = targetOpponent.getLibrary().getTopCards(game, 7); Cards cards = new CardsImpl(Zone.LIBRARY, allCards); targetOpponent.revealCards( sourceObject.getIdName() + " - " + targetOpponent.getName() + "'s top library cards", cards, game); for (Card card : allCards) { if (filter.match(card, game)) { cardsToCast.add(card); } } // cast an instant or sorcery for free if (cardsToCast.size() > 0) { int numberOfSpells = 1; if (SpellMasteryCondition.getInstance().apply(game, source)) { numberOfSpells++; } Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { TargetCard target = new TargetCard(Zone.LIBRARY, filter); // zone should be ignored here target.setNotTarget(true); while (numberOfSpells > 0 && cardsToCast.size() > 0 && controller.chooseUse( outcome, "Cast an instant or sorcery card from among them for free?", source, game) && controller.choose(outcome, cardsToCast, target, game)) { Card card = cardsToCast.get(target.getFirstTarget(), game); if (card != null) { controller.cast(card.getSpellAbility(), game, true); numberOfSpells--; cardsToCast.remove(card); allCards.remove(card); } if (!controller.isInGame()) { return false; } target.clearChosen(); } } targetOpponent.moveCards(allCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); } return true; } return false; }
public SpellsCostReductionAllEffect(FilterCard filter, int amount) { super(Duration.WhileOnBattlefield, Outcome.Benefit); this.filter = filter; this.amount = amount; this.staticText = new StringBuilder(filter.getMessage()) .append(" cost {") .append(amount) .append("} less to cast") .toString(); }
@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; }
@Override public boolean applies(GameEvent event, Ability source, Game game) { BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get("ManaPaidFromBoseijuWhoSheltersAllWatcher"); Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && watcher.spells.contains(spell.getId())) { if (filter.match(spell.getCard(), game)) { return true; } } return false; }
public SpellsCostReductionControllerEffect(FilterCard filter, int amount, boolean upTo) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.filter = filter; this.amount = amount; this.upTo = upTo; this.staticText = filter.getMessage() + " you cast cost " + (upTo ? "up to " : "") + "{" + amount + "} less to cast"; }
@Override public boolean apply(Game game, Ability source) { Player you = game.getPlayer(source.getControllerId()); Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (you != null && attackingCreature != null) { FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature"); filter.add(new SubtypePredicate("Aura")); filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId())); if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(filter); target.setNotTarget(true); if (you.searchLibrary(target, game)) { if (target.getFirstTarget() != null) { Card aura = game.getCard(target.getFirstTarget()); game.getState().setValue("attachTo:" + aura.getId(), attackingCreature); aura.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), you.getId()); return attackingCreature.addAttachment(aura.getId(), game); } } } you.shuffleLibrary(game); } return false; }
public SpellsCostReductionControllerEffect( FilterCard filter, ManaCosts<ManaCost> manaCostsToReduce) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.filter = filter; this.amount = 0; this.manaCostsToReduce = manaCostsToReduce; this.upTo = false; StringBuilder sb = new StringBuilder(); sb.append(filter.getMessage()).append(" you cast cost "); for (String manaSymbol : manaCostsToReduce.getSymbols()) { sb.append(manaSymbol); } sb.append(" less to cast. This effect reduces only the amount of colored mana you pay."); this.staticText = sb.toString(); }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { if (controller.chooseUse(Outcome.Benefit, choiceText, source, game)) { Set<Card> sideboard = controller.getSideboard().getCards(filter, game); List<Card> exile = game.getExile().getAllCards(game); Cards filteredCards = new CardsImpl(); Card card = null; for (Card sideboardCard : sideboard) { filteredCards.add(sideboardCard.getId()); } for (Card exileCard : exile) { if (exileCard.getOwnerId().equals(source.getControllerId()) && exileCard.hasSubtype("Eldrazi")) { filteredCards.add(exileCard); } } if (filteredCards.isEmpty()) { game.informPlayer( controller, "You have no " + filter.getMessage() + " outside the game (your sideboard) or in exile."); } else { TargetCard target = new TargetCard(Zone.OUTSIDE, filter); target.setNotTarget(true); if (controller.choose(outcome, filteredCards, target, game)) { card = controller.getSideboard().get(target.getFirstTarget(), game); if (card == null) { card = game.getCard(target.getFirstTarget()); } } } if (card != null) { card.moveToZone(Zone.HAND, source.getSourceId(), game, false); controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); } } 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; }
static { filterCost.add(new SubtypePredicate("Plains")); }
static { filter.add(Predicates.or(new SubtypePredicate("Forest"), new SubtypePredicate("Plains"))); }
static { filter.add(new ColorPredicate(ObjectColor.BLUE)); }
static { filter.add(Predicates.not(new FaceDownPredicate())); }
static { filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, 2)); }
static { filterBlack.add(new ColorPredicate(ObjectColor.BLACK)); filterRed.add(new ColorPredicate(ObjectColor.RED)); }
static { myrCardFilter.add(new SubtypePredicate("Myr")); }
static { filter.add(new NamePredicate("Demigod of Revenge")); }
static { filterCost.add(new SubtypePredicate("Plains")); filter.add( Predicates.or( new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ENCHANTMENT))); }