package magic.model.stack; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import magic.model.MagicAbility; import magic.model.MagicCard; import magic.model.MagicCardDefinition; import magic.model.MagicCopyMap; import magic.model.MagicGame; import magic.model.MagicLocationType; import magic.model.MagicObject; import magic.model.MagicPayedCost; import magic.model.MagicPlayer; import magic.model.MagicSource; import magic.model.MurmurHash3; import magic.model.action.MagicPermanentAction; import magic.model.action.MoveCardAction; import magic.model.event.MagicCardEvent; import magic.model.event.MagicEvent; import magic.model.event.MagicSourceActivation; public class MagicCardOnStack extends MagicItemOnStack implements MagicSource { private MagicLocationType moveLocation=MagicLocationType.Graveyard; private MagicLocationType fromLocation=MagicLocationType.OwnersHand; private final MagicPayedCost payedCost; private final MagicCardEvent cardEvent; private final MagicEvent event; private final MagicCardDefinition cardDef; private final List<? extends MagicPermanentAction> modifications; public MagicCardOnStack( final MagicCard card, final MagicObject obj, final MagicPlayer controller, final MagicCardEvent aCardEvent, final MagicPayedCost aPayedCost, final List<? extends MagicPermanentAction> aModifications ) { super(card, controller); payedCost = aPayedCost; cardEvent = aCardEvent; cardDef = obj.getCardDefinition(); event = aCardEvent.getEvent(this, aPayedCost); assert event != MagicEvent.NONE : "event is NONE for " + cardDef; modifications = aModifications; } public MagicCardOnStack(final MagicCard card,final MagicCardEvent aCardEvent, final MagicPayedCost aPayedCost) { this(card, card, card.getController(), aCardEvent, aPayedCost, Collections.<MagicPermanentAction>emptyList()); } public MagicCardOnStack(final MagicCard card,final MagicPlayer controller,final MagicPayedCost aPayedCost) { this(card, card, controller, card.getCardDefinition().getCardEvent(), aPayedCost, Collections.<MagicPermanentAction>emptyList()); } public MagicCardOnStack(final MagicCard card,final MagicPlayer controller,final MagicPayedCost aPayedCost, final List<? extends MagicPermanentAction> aModifications) { this(card, card, controller, card.getCardDefinition().getCardEvent(), aPayedCost, aModifications); } public MagicCardOnStack(final MagicCard card,final MagicPayedCost aPayedCost) { this(card, card.getCardDefinition().getCardEvent(), aPayedCost); } private MagicCardOnStack(final MagicCopyMap copyMap, final MagicCardOnStack cardOnStack) { super(copyMap, cardOnStack); payedCost = copyMap.copy(cardOnStack.payedCost); moveLocation = cardOnStack.moveLocation; fromLocation = cardOnStack.fromLocation; cardEvent = cardOnStack.cardEvent; cardDef = cardOnStack.cardDef; event = copyMap.copy(cardOnStack.event); modifications = cardOnStack.modifications; } public MagicCardOnStack copyCardOnStack(final MagicPlayer player) { final MagicCard card=MagicCard.createTokenCard(getCardDefinition(),player); final MagicCardOnStack copyCardOnStack=new MagicCardOnStack(card,cardEvent,payedCost); final Object[] choiceResults=getChoiceResults(); if (choiceResults!=null) { copyCardOnStack.setChoiceResults(Arrays.copyOf(choiceResults,choiceResults.length)); } return copyCardOnStack; } @Override public long getStateId() { return MurmurHash3.hash(new long[] { super.getStateId(), moveLocation.ordinal(), fromLocation.ordinal(), payedCost.getStateId(), cardDef.getIndex() }); } @Override public MagicCardDefinition getCardDefinition() { return cardDef; } @Override public MagicEvent getEvent() { return event; } @Override public void resolve(final MagicGame game) { super.resolve(game); // Move card to move location that is not play if (moveLocation != MagicLocationType.Battlefield) { game.doAction(new MoveCardAction(this)); } } @Override public MagicCardOnStack copy(final MagicCopyMap copyMap) { return new MagicCardOnStack(copyMap, this); } @Override public MagicCardOnStack map(final MagicGame game) { return (MagicCardOnStack)super.map(game); } public MagicCard getCard() { return (MagicCard)getSource(); } public void setMoveLocation(final MagicLocationType loc) { moveLocation = loc; } public MagicLocationType getMoveLocation() { return moveLocation; } public void setFromLocation(final MagicLocationType loc) { fromLocation = loc; } public MagicLocationType getFromLocation() { return fromLocation; } public List<? extends MagicPermanentAction> getModifications() { return modifications; } @Override public int getConvertedCost() { return getCardDefinition().getConvertedCost(payedCost.getX()); } public int getX() { return payedCost.getX(); } public MagicPayedCost getPayedCost() { return payedCost; } @Override public boolean isSpell() { return true; } public boolean isCast() { return payedCost != MagicPayedCost.NOT_SPELL; } public boolean isRepresentedByACard() { return getCard().isToken() == false; } @Override public boolean canBeCountered() { return !getCardDefinition().hasAbility(MagicAbility.CannotBeCountered); } @Override public MagicGame getGame() { return getSource().getGame(); } @Override public Collection<MagicSourceActivation<? extends MagicSource>> getSourceActivations() { return Collections.emptyList(); } public int getKicker() { return payedCost.getKicker(); } public boolean isKicked() { return payedCost.isKicked(); } public boolean isFaceDown() { return false; } }