Add common effect class for "Its controller searches..." (Path to Exile, etc) Fixes #9654

This commit is contained in:
Alex W. Jackson 2022-10-15 21:27:55 -04:00
parent 58c55bf08c
commit 76fcfafc8b
19 changed files with 243 additions and 653 deletions

View file

@ -62,14 +62,9 @@ public class SacrificeTargetEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
if (staticText.isEmpty() && !mode.getTargets().isEmpty()) {
if (mode.getTargets().get(0).getNumberOfTargets() == 1) {
return "The controller of target " + mode.getTargets().get(0).getTargetName() + " sacrifices it";
} else {
return "The controller of " + mode.getTargets().get(0).getNumberOfTargets() + " target " + mode.getTargets().get(0).getTargetName() + " sacrifices it";
}
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return staticText;
return getTargetPointer().describeTargets(mode.getTargets(), "that permanent") + "'s controller sacrifices it";
}
}

View file

@ -2,7 +2,7 @@ package mage.abilities.effects.common.search;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.SearchEffect;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
@ -11,26 +11,18 @@ import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.util.CardUtil;
/**
* @author TheElk801
*/
public class SearchLibraryAndExileTargetEffect extends OneShotEffect {
private final int amount;
private final boolean upTo;
public class SearchLibraryAndExileTargetEffect extends SearchEffect {
public SearchLibraryAndExileTargetEffect(int amount, boolean upTo) {
super(Outcome.Benefit);
this.amount = amount;
this.upTo = upTo;
super(new TargetCardInLibrary(upTo ? 0 : amount, amount, amount > 1 ? StaticFilters.FILTER_CARD_CARDS : StaticFilters.FILTER_CARD), Outcome.Exile);
}
private SearchLibraryAndExileTargetEffect(final SearchLibraryAndExileTargetEffect effect) {
super(effect);
this.amount = effect.amount;
this.upTo = effect.upTo;
}
@Override
@ -45,16 +37,12 @@ public class SearchLibraryAndExileTargetEffect extends OneShotEffect {
if (controller == null || player == null) {
return false;
}
TargetCardInLibrary target = new TargetCardInLibrary(upTo ? 0 : amount, amount, StaticFilters.FILTER_CARD);
controller.searchLibrary(target, source, game, player.getId());
Cards cards = new CardsImpl();
target.getTargets()
.stream()
.map(uuid -> player.getLibrary().getCard(uuid, game))
.forEach(cards::add);
if (cards.isEmpty()) {
return false;
}
controller.moveCards(cards, Zone.EXILED, source, game);
player.shuffleLibrary(source, game);
return true;
@ -62,24 +50,14 @@ public class SearchLibraryAndExileTargetEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
StringBuilder sb = new StringBuilder("search ");
if (mode.getTargets().isEmpty()) {
sb.append("that player");
} else {
sb.append("target ");
sb.append(mode.getTargets().get(0).getTargetName());
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
sb.append("'s library for ");
if (amount > 1) {
if (upTo) {
sb.append("up to ");
}
sb.append(CardUtil.numberToText(amount));
sb.append(" cards and exile them");
} else {
sb.append("a card and exile it");
}
sb.append(". Then that player shuffles");
return sb.toString();
return "search "
+ getTargetPointer().describeTargets(mode.getTargets(), "that player")
+ "'s library for "
+ target.getDescription()
+ (target.getMaxNumberOfTargets() > 1 ? " and exile them" : " and exile it")
+ ". Then that player shuffles";
}
}

View file

@ -8,7 +8,6 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.util.CardUtil;
import java.util.List;
import java.util.UUID;
@ -41,7 +40,12 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect {
super(target, outcome);
this.tapped = tapped;
this.forceShuffle = forceShuffle;
setText();
staticText = "search your library for "
+ target.getDescription()
+ (forceShuffle ? ", " : " and ")
+ (target.getMaxNumberOfTargets() > 1 ? "put them onto the battlefield" : "put it onto the battlefield")
+ (tapped ? " tapped" : "")
+ (forceShuffle ? ", then shuffle" : ". If you do, shuffle");
}
public SearchLibraryPutInPlayEffect(final SearchLibraryPutInPlayEffect effect) {
@ -72,39 +76,10 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect {
if (forceShuffle) {
player.shuffleLibrary(source, game);
}
return false;
}
private void setText() {
StringBuilder sb = new StringBuilder();
sb.append("search your library for ");
if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) {
sb.append("any number of ");
} else {
sb.append("up to ").append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(' ');
}
sb.append(target.getTargetName());
sb.append(forceShuffle ? ", " : " and ");
sb.append("put them onto the battlefield");
} else {
sb.append(CardUtil.addArticle(target.getTargetName()));
sb.append(forceShuffle ? ", " : " and ");
sb.append("put it onto the battlefield");
}
if (tapped) {
sb.append(" tapped");
}
if (forceShuffle) {
sb.append(", then shuffle");
} else {
sb.append(". If you do, shuffle");
}
staticText = sb.toString();
return true;
}
public List<UUID> getTargets() {
return target.getTargets();
}
}

View file

@ -0,0 +1,68 @@
package mage.abilities.effects.common.search;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
/**
* @author awjackson
*/
public class SearchLibraryPutInPlayTargetControllerEffect extends SearchEffect {
private boolean tapped;
public SearchLibraryPutInPlayTargetControllerEffect(boolean tapped) {
this(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), tapped, Outcome.PutLandInPlay, "its controller");
}
public SearchLibraryPutInPlayTargetControllerEffect(TargetCardInLibrary target, boolean tapped, Outcome outcome, String whoSearch) {
super(target, outcome);
this.tapped = tapped;
staticText = whoSearch
+ " may search their library for "
+ target.getDescription()
+ (target.getMaxNumberOfTargets() > 1 ? ", put them onto the battlefield" : ", put it onto the battlefield")
+ (tapped ? " tapped" : "")
+ ", then shuffle";
}
public SearchLibraryPutInPlayTargetControllerEffect(final SearchLibraryPutInPlayTargetControllerEffect effect) {
super(effect);
this.tapped = effect.tapped;
}
@Override
public SearchLibraryPutInPlayTargetControllerEffect copy() {
return new SearchLibraryPutInPlayTargetControllerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (permanent == null) {
return false;
}
Player player = game.getPlayer(permanent.getControllerId());
if (player == null) {
return false;
}
if (!player.chooseUse(outcome, "Search your library for " + target.getDescription() + '?', source, game)) {
return true;
}
if (player.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
player.moveCards(new CardsImpl(target.getTargets()).getCards(game),
Zone.BATTLEFIELD, source, game, tapped, false, false, null);
}
}
player.shuffleLibrary(source, game);
return true;
}
}

View file

@ -1,6 +1,7 @@
package mage.abilities.effects.common.search;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.SearchEffect;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
@ -9,9 +10,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.List;
import java.util.UUID;
/**
* @author LevelX2
*/
@ -46,7 +44,6 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
this.tapped = tapped;
this.forceShuffle = forceShuffle;
this.ownerIsController = ownerIsController;
setText();
}
public SearchLibraryPutInPlayTargetPlayerEffect(final SearchLibraryPutInPlayTargetPlayerEffect effect) {
@ -82,32 +79,17 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
return false;
}
private void setText() {
StringBuilder sb = new StringBuilder();
sb.append("target player searches their library for ");
if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) {
sb.append("any number of ").append(' ');
} else {
sb.append("up to ").append(target.getMaxNumberOfTargets()).append(' ');
}
sb.append(target.getTargetName()).append(", puts them onto the battlefield");
} else {
sb.append("a ").append(target.getTargetName()).append(", puts it onto the battlefield");
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
if (tapped) {
sb.append(" tapped");
}
if (forceShuffle) {
sb.append(", then shuffles");
} else {
sb.append(". If that player does, they shuffle");
}
staticText = sb.toString();
return getTargetPointer().describeTargets(mode.getTargets(), "that player")
+ " searches their library for "
+ target.getDescription()
+ (forceShuffle ? ", " : " and ")
+ (target.getMaxNumberOfTargets() > 1 ? "puts them onto the battlefield" : "puts it onto the battlefield")
+ (tapped ? " tapped" : "")
+ (forceShuffle ? ", then shuffles" : ". If that player does, they shuffle");
}
public List<UUID> getTargets() {
return target.getTargets();
}
}

View file

@ -119,7 +119,11 @@ public abstract class TargetImpl implements Target {
if (!isNotTarget() && !getTargetName().contains("target")) {
sb.append("target ");
}
sb.append(getTargetName());
if (isNotTarget() && min == 1 && max == 1) {
sb.append(CardUtil.addArticle(getTargetName()));
} else {
sb.append(getTargetName());
}
return sb.toString();
}

View file

@ -1,30 +0,0 @@
package mage.target.common;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.target.TargetCard;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TargetBasicLandCard extends TargetCard {
public TargetBasicLandCard(Zone zone) {
super(zone);
filter.add(SuperType.BASIC.getPredicate());
filter.add(CardType.LAND.getPredicate());
}
public TargetBasicLandCard(final TargetBasicLandCard target) {
super(target);
}
@Override
public TargetBasicLandCard copy() {
return new TargetBasicLandCard(this);
}
}