foul-magics/Mage/src/main/java/mage/abilities/effects/common/PutCardFromOneOfTwoZonesOntoBattlefieldEffect.java

164 lines
6.3 KiB
Java

package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CommanderCardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInCommandZone;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
* "Put a {filter} card from {zone 1} or {zone 2} onto the battlefield.
*
* @author TheElk801, Alex-Vasile
*/
public class PutCardFromOneOfTwoZonesOntoBattlefieldEffect extends OneShotEffect {
private final FilterCard filterCard;
private final boolean tapped;
private final Effect effectToApplyOnPermanent;
private final Zone zone1;
private final Zone zone2;
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect(FilterCard filterCard) {
this(filterCard, false);
}
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect(FilterCard filterCard, boolean tapped) {
this(filterCard, tapped, null);
}
/**
*
* @param filterCard Filter used to filter which cards are valid choices. (no default)
* @param tapped If the permanent should enter the battlefield tapped (default is False)
* @param effectToApplyOnPermanent An effect to apply to the permanent after it enters (default null)
* See "Swift Warkite" or "Nissa of Shadowed Boughs".
* @param zone1 The first zone to pick from (default of HAND)
* @param zone2 The second zone to pick from (defualt of GRAVEYARD)
*/
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect(FilterCard filterCard, boolean tapped, Effect effectToApplyOnPermanent, Zone zone1, Zone zone2) {
super(filterCard instanceof FilterCreatureCard ? Outcome.PutCreatureInPlay : Outcome.PutCardInPlay);
this.filterCard = filterCard;
this.tapped = tapped;
this.effectToApplyOnPermanent = effectToApplyOnPermanent;
this.zone1 = zone1;
this.zone2 = zone2;
}
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect(FilterCard filterCard, boolean tapped, Effect effectToApplyOnPermanent) {
this(filterCard, tapped, effectToApplyOnPermanent, Zone.HAND, Zone.GRAVEYARD);
}
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect(FilterCard filterCard, Zone zone1, Zone zone2) {
this(filterCard, false, null, zone1, zone2);
}
private PutCardFromOneOfTwoZonesOntoBattlefieldEffect(final PutCardFromOneOfTwoZonesOntoBattlefieldEffect effect) {
super(effect);
this.filterCard = effect.filterCard;
this.tapped = effect.tapped;
this.zone1 = effect.zone1;
this.zone2 = effect.zone2;
if (effect.effectToApplyOnPermanent != null) {
this.effectToApplyOnPermanent = effect.effectToApplyOnPermanent.copy();
} else {
this.effectToApplyOnPermanent = null;
}
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Cards cardsInZone1 = getCardsFromZone(game, controller, zone1);
Cards cardsInZone2 = getCardsFromZone(game, controller, zone2);
boolean cardsAvailableInZone1 = cardsInZone1.count(filterCard, game) > 0;
boolean cardsAvailableInZone2 = cardsInZone2.count(filterCard, game) > 0;
if (!cardsAvailableInZone1 && !cardsAvailableInZone2) {
return false;
}
boolean choose1stZone;
if (cardsAvailableInZone1 && cardsAvailableInZone2) {
choose1stZone = controller.chooseUse(outcome, "Where do you want to chose the card from?",
null, zone1.name(), zone2.name(), source, game);
} else {
choose1stZone = cardsAvailableInZone1;
}
Zone zone = choose1stZone ? zone1 : zone2;
Cards cards = choose1stZone ? cardsInZone1 : cardsInZone2;
TargetCard targetCard;
switch (zone) {
case HAND:
targetCard = new TargetCardInHand(filterCard);
break;
case GRAVEYARD:
targetCard = new TargetCardInGraveyard(filterCard);
break;
case COMMAND:
targetCard = new TargetCardInCommandZone(filterCard);
break;
default:
return false;
}
controller.choose(outcome, cards, targetCard, source, game);
Card card = game.getCard(targetCard.getFirstTarget());
if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null)) {
return false;
}
if (effectToApplyOnPermanent != null) {
effectToApplyOnPermanent.setTargetPointer(new FixedTarget(card.getId()));
effectToApplyOnPermanent.apply(game, source);
}
return true;
}
private static Cards getCardsFromZone(Game game, Player player, Zone zone) {
switch (zone) {
case HAND:
return player.getHand();
case COMMAND:
return new CardsImpl(game.getCommanderCardsFromCommandZone(player, CommanderCardType.ANY));
case GRAVEYARD:
return player.getGraveyard();
default:
return new CardsImpl();
}
}
@Override
public PutCardFromOneOfTwoZonesOntoBattlefieldEffect copy() {
return new PutCardFromOneOfTwoZonesOntoBattlefieldEffect(this);
}
@Override
public String getText(Mode mode) {
return "you may put " + CardUtil.addArticle(this.filterCard.getMessage()) +
" from your hand or graveyard onto the battlefield" +
(this.tapped ? " tapped" : "") +
(effectToApplyOnPermanent == null ? "" : ". " + effectToApplyOnPermanent.getText(mode));
}
}