mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Fix ShuffleIntoLibraryTargetEffect to support multiple target cards with possibly different owners
This commit is contained in:
parent
30aafb7672
commit
b5b4b38cc6
6 changed files with 86 additions and 75 deletions
|
@ -32,8 +32,8 @@ public final class GhostlyCastigator extends CardImpl {
|
||||||
// Flying
|
// Flying
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Ghostly Castigator enters the battlefield, shuffle up to three target cards from your graveyard into your library.
|
// When Ghostly Castigator enters the battlefield, you may shuffle up to three target cards from your graveyard into your library.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ShuffleIntoLibraryTargetEffect());
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ShuffleIntoLibraryTargetEffect(), true);
|
||||||
ability.addTarget(new TargetCardInYourGraveyard(0, 3));
|
ability.addTarget(new TargetCardInYourGraveyard(0, 3));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.p;
|
package mage.cards.p;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -7,18 +6,11 @@ import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.common.ExileSourceCost;
|
import mage.abilities.costs.common.ExileSourceCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
|
||||||
import mage.abilities.effects.common.MillCardsControllerEffect;
|
import mage.abilities.effects.common.MillCardsControllerEffect;
|
||||||
import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
|
import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.CardsImpl;
|
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.FilterCard;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,12 +23,12 @@ public final class PerpetualTimepiece extends CardImpl {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||||
|
|
||||||
// {T}: Put the top two cards of your library into your graveyard.
|
// {T}: Put the top two cards of your library into your graveyard.
|
||||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new MillCardsControllerEffect(2), new TapSourceCost()));
|
this.addAbility(new SimpleActivatedAbility(new MillCardsControllerEffect(2), new TapSourceCost()));
|
||||||
|
|
||||||
// {2}, Exile Perpetual Timepiece: Shuffle any number of target cards from your graveyard into your library.
|
// {2}, Exile Perpetual Timepiece: Shuffle any number of target cards from your graveyard into your library.
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleIntoLibraryTargetEffect(), new GenericManaCost(2));
|
Ability ability = new SimpleActivatedAbility(new ShuffleIntoLibraryTargetEffect(), new GenericManaCost(2));
|
||||||
ability.addCost(new ExileSourceCost());
|
ability.addCost(new ExileSourceCost());
|
||||||
ability.addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCard("cards to shuffle into your library")));
|
ability.addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,31 +41,3 @@ public final class PerpetualTimepiece extends CardImpl {
|
||||||
return new PerpetualTimepiece(this);
|
return new PerpetualTimepiece(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PerpetualTimepieceShuffleEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
PerpetualTimepieceShuffleEffect() {
|
|
||||||
super(Outcome.Neutral);
|
|
||||||
this.staticText = "Shuffle any number of target cards from your graveyard into your library";
|
|
||||||
}
|
|
||||||
|
|
||||||
PerpetualTimepieceShuffleEffect(final PerpetualTimepieceShuffleEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PerpetualTimepieceShuffleEffect copy() {
|
|
||||||
return new PerpetualTimepieceShuffleEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
|
||||||
if (controller != null) {
|
|
||||||
controller.moveCards(new CardsImpl(this.getTargetPointer().getTargets(game, source)), Zone.LIBRARY, source, game);
|
|
||||||
controller.shuffleLibrary(source, game);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,10 @@ package mage.cards.s;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
|
import mage.abilities.effects.common.MillCardsTargetEffect;
|
||||||
import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
|
|
||||||
import mage.abilities.keyword.ReplicateAbility;
|
import mage.abilities.keyword.ReplicateAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.Cards;
|
|
||||||
import mage.cards.CardsImpl;
|
import mage.cards.CardsImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
@ -16,7 +14,6 @@ import mage.players.Player;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
import mage.target.targetpointer.SecondTargetPointer;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -28,14 +25,11 @@ public final class StreamOfThought extends CardImpl {
|
||||||
public StreamOfThought(UUID ownerId, CardSetInfo setInfo) {
|
public StreamOfThought(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}");
|
||||||
|
|
||||||
// Target player puts the top four cards of their library into their graveyard.
|
// Target player mills four cards. You shuffle up to four cards from your graveyard into your library.
|
||||||
this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(4));
|
this.getSpellAbility().addEffect(new MillCardsTargetEffect(4));
|
||||||
|
this.getSpellAbility().addEffect(new StreamOfThoughtEffect());
|
||||||
this.getSpellAbility().addTarget(new TargetPlayer());
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
|
|
||||||
// You shuffle up to four cards from your graveyard into your library.
|
|
||||||
this.getSpellAbility().addEffect(new ShuffleIntoLibraryTargetEffect().setTargetPointer(new SecondTargetPointer()));
|
|
||||||
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 4));
|
|
||||||
|
|
||||||
// Replicate {2}{U}{U}
|
// Replicate {2}{U}{U}
|
||||||
this.addAbility(new ReplicateAbility("{2}{U}{U}"));
|
this.addAbility(new ReplicateAbility("{2}{U}{U}"));
|
||||||
}
|
}
|
||||||
|
@ -49,3 +43,35 @@ public final class StreamOfThought extends CardImpl {
|
||||||
return new StreamOfThought(this);
|
return new StreamOfThought(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StreamOfThoughtEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
StreamOfThoughtEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "You shuffle up to four cards from your graveyard into your library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private StreamOfThoughtEffect(final StreamOfThoughtEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamOfThoughtEffect copy() {
|
||||||
|
return new StreamOfThoughtEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TargetCard target = new TargetCardInYourGraveyard(0, 4);
|
||||||
|
target.setNotTarget(true);
|
||||||
|
if (!player.choose(outcome, player.getGraveyard(), target, game)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
player.shuffleCardsToLibrary(new CardsImpl(target.getTargets()), game, source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.keyword.FlashbackAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.TimingRule;
|
import mage.filter.FilterCard;
|
||||||
import mage.target.common.TargetCardInGraveyard;
|
import mage.target.common.TargetCardInGraveyard;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -17,15 +17,15 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class TurnTheEarth extends CardImpl {
|
public final class TurnTheEarth extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCard filter = new FilterCard("cards in graveyards");
|
||||||
|
|
||||||
public TurnTheEarth(UUID ownerId, CardSetInfo setInfo) {
|
public TurnTheEarth(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
|
||||||
|
|
||||||
// Choose up to three target cards in graveyards. The owners of those cards shuffle them into their libraries. You gain 2 life.
|
// Choose up to three target cards in graveyards. The owners of those cards shuffle them into their libraries. You gain 2 life.
|
||||||
this.getSpellAbility().addEffect(new ShuffleIntoLibraryTargetEffect()
|
this.getSpellAbility().addEffect(new ShuffleIntoLibraryTargetEffect());
|
||||||
.setText("choose up to three target cards in graveyards. " +
|
|
||||||
"The owners of those cards shuffle them into their libraries."));
|
|
||||||
this.getSpellAbility().addEffect(new GainLifeEffect(2));
|
this.getSpellAbility().addEffect(new GainLifeEffect(2));
|
||||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard(0, 3));
|
this.getSpellAbility().addTarget(new TargetCardInGraveyard(0, 3, filter));
|
||||||
|
|
||||||
// Flashback {1}{G}
|
// Flashback {1}{G}
|
||||||
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{1}{G}")));
|
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{1}{G}")));
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
import mage.cards.Cards;
|
||||||
|
import mage.cards.CardsImpl;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Styxo
|
* @author awjackson
|
||||||
*/
|
*/
|
||||||
public class ShuffleIntoLibraryTargetEffect extends OneShotEffect {
|
public class ShuffleIntoLibraryTargetEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
@ -38,30 +43,46 @@ public class ShuffleIntoLibraryTargetEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
MageObject cardObject = game.getObject(getTargetPointer().getFirst(game, source));
|
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (cardObject != null && controller != null && cardObject instanceof Card) {
|
if (controller == null) {
|
||||||
if (!optional
|
return false;
|
||||||
|| controller.chooseUse(Outcome.Benefit, "Shuffle " + cardObject.getIdName() + " into "
|
}
|
||||||
+ (((Card) cardObject).getOwnerId().equals(source.getControllerId()) ? "your" : "its owners")
|
Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source));
|
||||||
+ " library?", source, game)) {
|
if (cards.isEmpty()) {
|
||||||
Player owner = game.getPlayer(((Card) cardObject).getOwnerId());
|
return true;
|
||||||
|
}
|
||||||
|
if (optional && !controller.chooseUse(Outcome.Benefit, "Shuffle the target card" + (cards.size() > 1 ? "s" : "") + " into your library?", source, game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// sort the target cards by owner
|
||||||
|
Map<UUID, Cards> cardsByOwner = new HashMap<>();
|
||||||
|
for (Card card : cards.getCards(game)) {
|
||||||
|
cardsByOwner.computeIfAbsent(card.getOwnerId(), x -> new CardsImpl()).add(card);
|
||||||
|
}
|
||||||
|
// then each player shuffles the cards they own
|
||||||
|
for (Map.Entry<UUID, Cards> entry : cardsByOwner.entrySet()) {
|
||||||
|
Player owner = game.getPlayer(entry.getKey());
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
return owner.shuffleCardsToLibrary(((Card) cardObject), game, source);
|
owner.shuffleCardsToLibrary(entry.getValue(), game, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText(Mode mode
|
public String getText(Mode mode)
|
||||||
) {
|
{
|
||||||
if (staticText != null && !staticText.isEmpty()) {
|
if (staticText != null && !staticText.isEmpty()) {
|
||||||
return staticText;
|
return staticText;
|
||||||
} else {
|
|
||||||
return "choose target " + mode.getTargets().get(0).getTargetName() + ". Its owner shuffles it into their library";
|
|
||||||
}
|
}
|
||||||
|
String targetDescription = getTargetPointer().describeTargets(mode.getTargets(), "");
|
||||||
|
if (targetDescription.contains("your graveyard")) {
|
||||||
|
return (optional ? "you may shuffle " : "shuffle ") + targetDescription + " into your library";
|
||||||
|
}
|
||||||
|
return "choose " + targetDescription + (
|
||||||
|
getTargetPointer().isPlural(mode.getTargets()) ?
|
||||||
|
". The owners of those cards shuffle them into their libraries" :
|
||||||
|
". Its owner shuffles it into their library"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class TargetCardInYourGraveyard extends TargetCard {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetCardInYourGraveyard(int minNumTargets, int maxNumTargets) {
|
public TargetCardInYourGraveyard(int minNumTargets, int maxNumTargets) {
|
||||||
this(minNumTargets, maxNumTargets, StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD);
|
this(minNumTargets, maxNumTargets, maxNumTargets > 1 ? StaticFilters.FILTER_CARDS_FROM_YOUR_GRAVEYARD : StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetCardInYourGraveyard(int minNumTargets, int maxNumTargets, FilterCard filter) {
|
public TargetCardInYourGraveyard(int minNumTargets, int maxNumTargets, FilterCard filter) {
|
||||||
|
|
Loading…
Reference in a new issue