package magic.model.action; import magic.ai.ArtificialScoringSystem; import magic.model.MagicCard; import magic.model.MagicGame; import magic.model.MagicLocationType; import magic.model.MagicPermanent; import magic.model.MagicPlayer; import magic.model.MagicSource; import magic.model.stack.MagicCardOnStack; import magic.model.trigger.MagicTrigger; import magic.model.trigger.MagicTriggerType; public class MoveCardAction extends MagicAction { public final MagicCard card; public final MagicPermanent permanent; public final MagicLocationType fromLocation; private MagicLocationType toLocation; private MoveCardAction(final MagicCard card, final MagicPermanent permanent, final MagicLocationType fromLocation, final MagicLocationType toLocation) { this.card=card; this.permanent=permanent; this.fromLocation=fromLocation; this.toLocation=toLocation; } public MoveCardAction(final MagicCard card,final MagicLocationType fromLocation,final MagicLocationType toLocation) { this(card,MagicPermanent.NONE,fromLocation,toLocation); } public MoveCardAction(final MagicPermanent permanent,final MagicLocationType toLocation) { this(permanent.getCard(),permanent,MagicLocationType.Battlefield,toLocation); } public MoveCardAction(final MagicCardOnStack cardOnStack) { this(cardOnStack.getCard(),MagicPermanent.NONE,MagicLocationType.Stack,cardOnStack.getMoveLocation()); } public boolean from(MagicLocationType loc) { return fromLocation == loc; } public boolean to(MagicLocationType loc) { return toLocation == loc; } public void setToLocation(final MagicLocationType aToLocation) { toLocation = aToLocation; } @Override public void doAction(final MagicGame game) { game.executeTrigger(MagicTriggerType.WouldBeMoved, this); final MagicSource triggerSource = permanent.isValid() ? permanent : card; // Execute replacement triggers for (final MagicTrigger<MoveCardAction> trigger : card.getCardDefinition().getPutIntoGraveyardTriggers()) { if (toLocation == MagicLocationType.Graveyard && trigger.getPriority() == MagicTrigger.REPLACEMENT) { game.executeTrigger(trigger, permanent, triggerSource, this); } } // Move card if (!card.isToken()) { final MagicPlayer owner=card.getOwner(); switch (toLocation) { case TopOfOwnersLibrary: owner.getLibrary().addToTop(card); break; case BottomOfOwnersLibrary: owner.getLibrary().addToBottom(card); break; case OwnersLibrary: owner.getLibrary().addToTop(card); game.doAction(new ShuffleLibraryAction(owner)); break; case OwnersHand: owner.addCardToHand(card); setScore(owner,ArtificialScoringSystem.getCardScore(card)); break; case Graveyard: owner.getGraveyard().addToTop(card); break; case Exile: owner.getExile().addToTop(card); break; } } // Execute triggers for (final MagicTrigger<MoveCardAction> trigger : card.getCardDefinition().getPutIntoGraveyardTriggers()) { if (toLocation == MagicLocationType.Graveyard && trigger.getPriority() > MagicTrigger.REPLACEMENT) { game.executeTrigger(trigger, permanent, triggerSource, this); } } if (toLocation == MagicLocationType.Graveyard) { game.executeTrigger(MagicTriggerType.WhenOtherPutIntoGraveyard, this); } game.setStateCheckRequired(); } @Override public void undoAction(final MagicGame game) { if (!card.isToken()) { final MagicPlayer owner=card.getOwner(); switch (toLocation) { case TopOfOwnersLibrary: case BottomOfOwnersLibrary: case OwnersLibrary: owner.getLibrary().remove(card); break; case OwnersHand: owner.removeCardFromHand(card); break; case Graveyard: owner.getGraveyard().remove(card); break; case Exile: owner.getExile().remove(card); break; } } } @Override public String toString() { return super.toString()+" ("+card+','+fromLocation+','+toLocation+')'; } }