@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; }
@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(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; }
@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; }
/** * 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) { 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; }
@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; }
@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; }
@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; }
@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; }
@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; }
/** * @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; }
@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; }
@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); } } }
@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; }