package magic.model.trigger; import magic.model.MagicCard; import magic.model.MagicCardList; import magic.model.MagicGame; import magic.model.MagicLocationType; import magic.model.MagicPermanent; import magic.model.MagicType; import magic.model.action.ShiftCardAction; import magic.model.action.CastCardAction; import magic.model.choice.MagicMayChoice; import magic.model.event.MagicEvent; import magic.model.event.MagicEventAction; import magic.model.stack.MagicCardOnStack; public class CascadeTrigger extends ThisSpellIsCastTrigger { private static final CascadeTrigger INSTANCE = new CascadeTrigger(); private CascadeTrigger() {} public static CascadeTrigger create() { return INSTANCE; } @Override public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent permanent, final MagicCardOnStack spell) { return new MagicEvent( spell, this, "Cascade" ); } @Override public void executeEvent(final MagicGame game, final MagicEvent event) { final MagicCardList library = event.getPlayer().getLibrary(); final MagicCardList exiled = new MagicCardList(); MagicCard nonland = MagicCard.NONE; // exile cards from the top of your library until you exile a nonland card // whose converted mana cost is less than this spell's converted mana cost. while (nonland == MagicCard.NONE && library.isEmpty() == false) { final MagicCard top = library.getCardAtTop(); game.doAction(new ShiftCardAction( top, MagicLocationType.OwnersLibrary, MagicLocationType.Exile )); exiled.add(top); if (top.hasType(MagicType.Land) == false && top.getConvertedCost() < event.getCardOnStack().getConvertedCost()) { nonland = top; } } // You may cast that card without paying its mana cost. // Then put all cards exiled this way that weren't cast on the bottom of your library in random order if (nonland.isInExile()) { game.addEvent(new MagicEvent( event.getSource(), event.getPlayer(), new MagicMayChoice("Cast " + nonland + " without paying its mana cost?"), exiled, CAST_ACTION, "PN may$ cast RN without paying its mana cost. " + "Then put all cards exiled this way that weren't cast on the bottom of PN's library in random order." )); } else { game.addEvent(new MagicEvent( event.getSource(), event.getPlayer(), exiled, RESTORE_CARDS, "Put all cards exiled this way that weren't cast on the bottom of PN's library in random order." )); } } private final MagicEventAction RESTORE_CARDS = (final MagicGame game, final MagicEvent event) -> { final MagicCardList cards = event.getRefCardList(); cards.shuffle(); for (final MagicCard card : cards) { game.doAction(new ShiftCardAction( card, MagicLocationType.Exile, MagicLocationType.BottomOfOwnersLibrary )); } }; private final MagicEventAction CAST_ACTION = (final MagicGame game, final MagicEvent event) -> { final MagicCardList exiled = new MagicCardList(event.getRefCardList()); if (event.isYes()) { final MagicCard card = exiled.removeCardAtTop(); game.doAction(CastCardAction.WithoutManaCost( event.getPlayer(), card, MagicLocationType.Exile, MagicLocationType.Graveyard )); } game.addEvent(new MagicEvent( event.getSource(), event.getPlayer(), exiled, RESTORE_CARDS, "" )); }; }