@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player opponent = game.getPlayer(source.getFirstTarget()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && opponent != null && sourcePermanent != null) { opponent.revealCards(sourcePermanent.getName(), opponent.getHand(), game); TargetCard target = new TargetCard(Zone.PICK, new FilterNonlandCard("nonland card to exile")); if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) { Card card = opponent.getHand().get(target.getFirstTarget(), game); if (card != null) { controller.moveCardToExileWithInfo( card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game, Zone.HAND); } } return true; } return false; }
@Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { DamageEvent damageEvent = (DamageEvent) event; Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent != null) { // get name of old target Permanent targetPermanent = game.getPermanent(event.getTargetId()); StringBuilder message = new StringBuilder(); message.append(sourcePermanent.getName()).append(": gets "); message.append(damageEvent.getAmount()).append(" damage redirected from "); if (targetPermanent != null) { message.append(targetPermanent.getName()); } else { Player targetPlayer = game.getPlayer(event.getTargetId()); if (targetPlayer != null) { message.append(targetPlayer.getName()); } else { message.append("unknown"); } } game.informPlayers(message.toString()); // redirect damage this.used = true; sourcePermanent.damage( damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isPreventable(), damageEvent.isCombatDamage(), event.getAppliedEffects()); return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); String name = permanent.getName(); permanent.moveToZone(Zone.HAND, source.getSourceId(), game, false); for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { if (perm.getName().equals(name)) permanent.moveToZone(Zone.HAND, source.getSourceId(), game, false); } return true; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && source.getTargets().size() > 0) { Target multiTarget = source.getTargets().get(0); for (UUID target : multiTarget.getTargets()) { Permanent permanent = game.getPermanent(target); if (permanent != null) { permanent.addCounters( CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); game.informPlayers( new StringBuilder(controller.getLogName()) .append(" puts ") .append(multiTarget.getTargetAmount(target)) .append(" ") .append(CounterType.P1P1.getName().toLowerCase()) .append(" counter on ") .append(permanent.getName()) .toString()); } } 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 player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (player != null && permanent != null) { String colors; ChoiceColor colorChoice = new ChoiceColor(); colorChoice.setMessage("Choose the first color"); while (!player.choose(Outcome.GainLife, colorChoice, game)) { if (!player.canRespond()) { return false; } } game.getState().setValue(permanent.getId() + "_color1", colorChoice.getColor().toString()); colors = colorChoice.getChoice().toLowerCase() + " and "; colorChoice.getChoices().remove(colorChoice.getChoice()); colorChoice.setMessage("Choose the second color"); while (!player.choose(Outcome.GainLife, colorChoice, game) && player.canRespond()) { game.debugMessage("player canceled choosing type. retrying."); } game.getState().setValue(permanent.getId() + "_color2", colorChoice.getColor().toString()); colors = colors + colorChoice.getChoice().toLowerCase(); game.informPlayers( permanent.getName() + ": " + player.getLogName() + " has chosen " + colors); } return false; }
@Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { preventDamageAction(event, source, game); Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { boolean removeCounter = true; // check if in the same combat damage step already a counter was removed if (game.getTurn().getPhase().getStep().getType().equals(PhaseStep.COMBAT_DAMAGE)) { if (game.getTurnNum() == turn && game.getTurn().getStep().equals(combatPhaseStep)) { removeCounter = false; } else { turn = game.getTurnNum(); combatPhaseStep = game.getTurn().getStep(); } } if (removeCounter && permanent.getCounters().getCount(CounterType.P1P1) > 0) { StringBuilder sb = new StringBuilder(permanent.getName()).append(": "); permanent.removeCounters(CounterType.P1P1.createInstance(), game); sb.append("Removed a +1/+1 counter "); game.informPlayers(sb.toString()); } } return false; }
@Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { GameEvent preventEvent = new GameEvent( GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false); if (!game.replaceEvent(preventEvent)) { int damage = event.getAmount(); Permanent permanent = game.getPermanent(event.getSourceId()); StringBuilder message = new StringBuilder(); if (permanent != null) { message.append(" from ").append(permanent.getName()); } message.insert(0, "Damage").append(" has been prevented: ").append(damage); event.setAmount(0); game.informPlayers(message.toString()); game.fireEvent( GameEvent.getEvent( GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage)); } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { return permanent.moveToExile( source.getSourceId(), permanent.getName(), source.getSourceId(), game); } return false; }
@Override public boolean apply(Game game, Ability source) { int randomNumber = (int) (Math.random() * 3); Permanent target = game.getPermanent(source.getTargets().get(randomNumber).getFirstTarget()); if (target != null) { game.informPlayers( "Wild Swing: The randomly chosen target to destroy is " + target.getName()); return target.destroy(source.getSourceId(), game, false); } return false; }
@Override public boolean apply(Game game, Ability source) { UUID exileId = source.getSourceId(); Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && exileId != null && targetPermanent != null && controller != null) { if (targetPermanent.getName().isEmpty()) { // face down creature controller.moveCardToExileWithInfo( targetPermanent, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); } else { String name = targetPermanent.getName(); for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { if (permanent != null && permanent.getName().equals(name)) { controller.moveCardToExileWithInfo( permanent, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); } } } return true; } return false; }
@Override public String getTargetedName(Game game) { StringBuilder sb = new StringBuilder(); for (UUID targetId : getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { sb.append(permanent.getName()).append(" "); } else { Player player = game.getPlayer(targetId); if (player != null) { sb.append(player.getName()).append(" "); } } } return sb.toString(); }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent target = game.getPermanent(source.getFirstTarget()); StringBuilder sb = new StringBuilder(); if (controller != null && target != null) { for (int i = 0; i < 5; i++) { if (!controller.chooseUse( Outcome.Neutral, "Do you wish to choose another color?", source, game)) { break; } ChoiceColor choiceColor = new ChoiceColor(); controller.choose(Outcome.Benefit, choiceColor, game); if (!controller.isInGame()) { return false; } if (!game.isSimulation()) game.informPlayers( target.getName() + ": " + controller.getLogName() + " has chosen " + choiceColor.getChoice()); if (choiceColor.getColor().isBlack()) { sb.append("B"); } else if (choiceColor.getColor().isBlue()) { sb.append("U"); } else if (choiceColor.getColor().isRed()) { sb.append("R"); } else if (choiceColor.getColor().isGreen()) { sb.append("G"); } else if (choiceColor.getColor().isWhite()) { sb.append("W"); } } String colors = new String(sb); ObjectColor chosenColors = new ObjectColor(colors); ContinuousEffect effect = new BecomesColorTargetEffect(chosenColors, duration); effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); game.addEffect(effect, source); return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); Permanent sourcePermananent = game.getPermanent(source.getSourceId()); if (permanent != null) { if (sourcePermananent != null) { sourcePermananent.imprint(permanent.getId(), game); sourcePermananent.addInfo( "imprint", new StringBuilder("[Imprinted card - ") .append(permanent.getName()) .append("]") .toString(), game); } return permanent.moveToExile(null, null, source.getSourceId(), game); } return false; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Set<UUID> toSacrifice = new HashSet<UUID>(); if (controller.flipCoin(game)) { // each blocking creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { for (UUID blockerId : combatGroup.getBlockers()) { toSacrifice.add(blockerId); } } } else { // each blocked creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (!combatGroup.getBlockers().isEmpty()) { for (UUID attackerId : combatGroup.getAttackers()) { toSacrifice.add(attackerId); } } } } for (UUID creatureId : toSacrifice) { Permanent creature = game.getPermanent(creatureId); if (creature != null) { creature.sacrifice(source.getSourceId(), game); Player player = game.getPlayer(creature.getControllerId()); if (player != null) { game.informPlayers( new StringBuilder(player.getName()) .append(" sacrifices ") .append(creature.getName()) .toString()); } } } return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { TargetPlayer target = new TargetPlayer(); target.setRequired(true); if (player.choose(this.outcome, target, source.getSourceId(), game)) { Player chosenPlayer = game.getPlayer(target.getFirstTarget()); if (chosenPlayer != null) { game.informPlayers( permanent.getName() + ": " + player.getName() + " has chosen " + chosenPlayer.getName()); game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); return true; } } } return false; }
@Override public boolean apply(Game game, Ability source) { Map<Integer, Set<String>> attackerMap = null; Object object = game.getState().getValue("blockedAttackers" + source.getSourceId()); if (object != null && object instanceof Map) { attackerMap = (Map<Integer, Set<String>>) object; for (Set<String> attackerSet : attackerMap.values()) { List<Permanent> doNotUntapNextUntapStep = new ArrayList<>(); for (Permanent creature : game.getBattlefield() .getActivePermanents( new FilterCreaturePermanent(), source.getControllerId(), game)) { if (attackerSet.contains(CardUtil.getCardZoneString(null, creature.getId(), game))) { // tap creature and add the not untap effect creature.tap(game); doNotUntapNextUntapStep.add(creature); game.informPlayers( new StringBuilder("Triton Tactics: ") .append(creature.getName()) .append(" doesn't untap during its controller's next untap step") .toString()); } } if (!doNotUntapNextUntapStep.isEmpty()) { ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature"); effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game)); game.addEffect(effect, source); } } } if (attackerMap != null) { attackerMap.clear(); } return true; }
@Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { Permanent permanent = game.getPermanent(sourceId); Player player = game.getPlayer(permanent.getControllerId()); this.amountPaid = player.getAmount( minimalCountersToPay, permanent.getCounters().getCount(name), "Choose X counters to remove", game); if (this.amountPaid >= minimalCountersToPay) { permanent.removeCounters(name, amountPaid, game); this.paid = true; } game.informPlayers( player.getName() + " removes " + this.amountPaid + " " + name + " counter from " + permanent.getName()); return paid; }
@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); } } }