[FIN] Implement Memories Returning

This commit is contained in:
theelk801 2025-05-27 16:58:24 -04:00
parent 5e03fda7e9
commit 85d85a4b17
36 changed files with 168 additions and 40 deletions

View file

@ -76,7 +76,7 @@ class AidFromTheCowlEffect extends OneShotEffect {
if (card.isPermanent(game) && controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " onto the battlefield?", source, game)) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
} else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " on the bottom of your library?", source, game)) {
controller.putCardsOnBottomOfLibrary(card, game, source, false);
controller.putCardsOnBottomOfLibrary(card, game, source);
} else {
game.informPlayers(controller.getLogName() + " puts the revealed card back to the top of the library.");
}

View file

@ -90,7 +90,7 @@ class AjaniSleeperAgentEffect extends OneShotEffect {
if (card.isCreature(game) || card.isPlaneswalker(game)) {
controller.moveCards(card, Zone.HAND, source, game);
} else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on the bottom of your library?", source, game)) {
controller.putCardsOnBottomOfLibrary(card, game, source, true);
controller.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -71,7 +71,7 @@ class AmassTheComponentsEffect extends OneShotEffect {
if (player.choose(Outcome.Detriment, player.getHand(), target, source, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
return player.putCardsOnBottomOfLibrary(card, game, source, true);
return player.putCardsOnBottomOfLibrary(card, game, source);
}
}
}

View file

@ -88,7 +88,7 @@ class ArdentDustspeakerCost extends CostImpl {
if (controller != null && (controller.chooseTarget(Outcome.Benefit, this.getTargets().get(0), source, game))) {
Card card = game.getCard(this.getTargets().get(0).getFirstTarget());
if (card != null) {
controller.putCardsOnBottomOfLibrary(card, game, source, true);
controller.putCardsOnBottomOfLibrary(card, game, source);
paid = true;
}
}

View file

@ -84,7 +84,7 @@ class BrutalizerExarchEffect2 extends OneShotEffect {
Permanent permanent = game.getPermanent(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
if (permanent != null && controller != null) {
return controller.putCardsOnBottomOfLibrary(permanent, game, source, true);
return controller.putCardsOnBottomOfLibrary(permanent, game, source);
}
return false;
}

View file

@ -108,7 +108,7 @@ class BucolicRanchEffect extends OneShotEffect {
if (Zone.LIBRARY.equals(game.getState().getZone(card.getId())) && player.chooseUse(
outcome, "Put " + card.getName() + " on the bottom of your library?", source, game
)) {
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -73,7 +73,7 @@ class CabarettiAscendencyEffect extends OneShotEffect {
controller.revealCards(source, new CardsImpl(card), game);
controller.moveCards(card, Zone.HAND, source, game);
} else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " on the bottom of your library?", source, game)) {
controller.putCardsOnBottomOfLibrary(card, game, source, false);
controller.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -80,6 +80,6 @@ class DeemInferiorEffect extends OneShotEffect {
)) {
return player.putCardOnTopXOfLibrary(permanent, game, source, 2, true);
}
return player.putCardsOnBottomOfLibrary(permanent, game, source, false);
return player.putCardsOnBottomOfLibrary(permanent, game, source);
}
}

View file

@ -82,7 +82,7 @@ class DescendantsPathEffect extends OneShotEffect {
CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
}
if (game.getState().getZone(card.getId()) == Zone.LIBRARY) {
controller.putCardsOnBottomOfLibrary(card, game, source, false);
controller.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -79,7 +79,7 @@ class DiscoverTheImpossibleEffect extends OneShotEffect {
player.choose(outcome, cards, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
return true;
}
player.moveCards(card, Zone.EXILED, source, game);

View file

@ -100,7 +100,7 @@ class EmergentUltimatumEffect extends OneShotEffect {
opponent.choose(outcome, cards, targetCardInExile, source, game);
Card toShuffle = game.getCard(targetCardInExile.getFirstTarget());
if (toShuffle != null) {
player.putCardsOnBottomOfLibrary(toShuffle, game, source, false);
player.putCardsOnBottomOfLibrary(toShuffle, game, source);
player.shuffleLibrary(source, game);
cards.remove(toShuffle);
}

View file

@ -85,6 +85,6 @@ class ErrandRiderOfGondorEffect extends OneShotEffect {
TargetCard target = new TargetCardInHand();
player.choose(outcome, player.getHand(), target, source, game);
Card card = game.getCard(target.getFirstTarget());
return card == null || player.putCardsOnBottomOfLibrary(card, game, source, false);
return card == null || player.putCardsOnBottomOfLibrary(card, game, source);
}
}

View file

@ -65,10 +65,10 @@ class EtherWellEffect extends OneShotEffect {
&& player.chooseUse(outcome, "Put " + permanent.getLogName() +
" on the bottom of its owner's library?", source, game
)) {
player.putCardsOnBottomOfLibrary(permanent, game, source, true);
player.putCardsOnBottomOfLibrary(permanent, game, source);
return true;
}
player.putCardsOnTopOfLibrary(new CardsImpl(permanent), game, source, true);
return true;
}
}
}

View file

@ -88,7 +88,7 @@ class ExpressiveIterationEffect extends OneShotEffect {
player.choose(outcome, cards, target, source, game);
card = game.getCard(target.getFirstTarget());
if (card != null) {
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
cards.remove(card);
}
if (cards.isEmpty()) {

View file

@ -73,7 +73,7 @@ class FireProphecyEffect extends OneShotEffect {
if (card == null) {
return false;
}
if (player.putCardsOnBottomOfLibrary(card, game, source, false)) {
if (player.putCardsOnBottomOfLibrary(card, game, source)) {
player.drawCards(1, source, game);
}
return true;

View file

@ -107,7 +107,7 @@ class GarrukSavageHeraldEffect extends OneShotEffect {
if (card.isCreature(game)) {
return player.moveCards(card, Zone.HAND, source, game);
} else {
return player.putCardsOnBottomOfLibrary(card, game, source, false);
return player.putCardsOnBottomOfLibrary(card, game, source);
}
}
}

View file

@ -131,8 +131,8 @@ class KenessosPriestOfThassaActivatedEffect extends OneShotEffect {
return player.moveCards(card, Zone.BATTLEFIELD, source, game);
}
if (player.chooseUse(outcome, "Put " + card.getName() + " on the bottom of your library?", source, game)) {
return player.putCardsOnBottomOfLibrary(card, game, source, true);
return player.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}
}
}

View file

@ -157,7 +157,7 @@ class KyloxsVoltstriderReplacementEffect extends ReplacementEffectImpl {
return false;
}
controller.putCardsOnBottomOfLibrary(card, game, source, false);
controller.putCardsOnBottomOfLibrary(card, game, source);
return true;
}
}

View file

@ -81,7 +81,7 @@ class LanternOfRevealingEffect extends OneShotEffect {
if (game.getState().getZone(card.getId()) == Zone.LIBRARY && player.chooseUse(
outcome, "Put " + card.getName() + " on the bottom of your library?", source, game
)) {
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -0,0 +1,129 @@
package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MemoriesReturning extends CardImpl {
public MemoriesReturning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
// Reveal the top five cards of your library. Put one of them into your hand. Then choose an opponent. They put one on the bottom of your library. Then you put one into your hand. Then they put one on the bottom of your library. Put the other into your hand.
this.getSpellAbility().addEffect(new MemoriesReturningEffect());
// Flashback {7}{U}{U}.
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{7}{U}{U}")));
}
private MemoriesReturning(final MemoriesReturning card) {
super(card);
}
@Override
public MemoriesReturning copy() {
return new MemoriesReturning(this);
}
}
class MemoriesReturningEffect extends OneShotEffect {
MemoriesReturningEffect() {
super(Outcome.Benefit);
staticText = "reveal the top five cards of your library. Put one of them into your hand. " +
"Then choose an opponent. They put one on the bottom of your library. " +
"Then you put one into your hand. Then they put one on the bottom of your library. " +
"Put the other into your hand";
}
private MemoriesReturningEffect(final MemoriesReturningEffect effect) {
super(effect);
}
@Override
public MemoriesReturningEffect copy() {
return new MemoriesReturningEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
controller.revealCards(source, cards, game);
if (putCardInHand(controller, cards, source, game)) {
return true;
}
TargetPlayer target = new TargetOpponent();
target.withNotTarget(true);
Player opponent = game.getPlayer(target.getFirstTarget());
if (putCardOnBottom(controller, opponent, cards, source, game)) {
return true;
}
if (putCardInHand(controller, cards, source, game)) {
return true;
}
if (putCardOnBottom(controller, opponent, cards, source, game)) {
return true;
}
putCardInHand(controller, cards, source, game);
return true;
}
private static boolean putCardInHand(Player controller, Cards cards, Ability source, Game game) {
switch (cards.size()) {
case 0:
return true;
case 1:
controller.moveCards(cards, Zone.HAND, source, game);
return true;
}
TargetCard target = new TargetCardInLibrary();
target.withChooseHint("to put in your hand");
controller.choose(Outcome.DrawCard, cards, target, source, game);
controller.moveCards(game.getCard(target.getFirstTarget()), Zone.HAND, source, game);
cards.retainZone(Zone.LIBRARY, game);
return false;
}
private static boolean putCardOnBottom(Player controller, Player opponent, Cards cards, Ability source, Game game) {
switch (cards.size()) {
case 0:
return true;
case 1:
controller.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
if (opponent == null) {
return false;
}
TargetCard target = new TargetCardInLibrary();
target.withChooseHint("to put on the bottom of " + controller.getName() + "'s library");
opponent.choose(Outcome.Discard, cards, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
return false;
}
controller.putCardsOnBottomOfLibrary(card, game, source);
cards.remove(card);
return false;
}
}

View file

@ -88,6 +88,6 @@ class MistveilPlainsGraveyardToLibraryEffect extends OneShotEffect {
|| game.getState().getZone(card.getId()) != Zone.GRAVEYARD) {
return false;
}
return player.putCardsOnBottomOfLibrary(card, game, source, false);
return player.putCardsOnBottomOfLibrary(card, game, source);
}
}

View file

@ -93,7 +93,7 @@ class MomentOfTruthEffect extends OneShotEffect {
if (card == null) {
return true;
}
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
return true;
}
}

View file

@ -75,7 +75,7 @@ class NeeraWildMageEffect extends OneShotEffect {
return false;
}
if (!spellController.putCardsOnBottomOfLibrary(spell, game, source, true)) {
if (!spellController.putCardsOnBottomOfLibrary(spell, game, source)) {
return false;
}

View file

@ -75,7 +75,7 @@ class PsychoticEpisodeEffect extends OneShotEffect {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
game.informPlayers(card.getLogName() + " was chosen.");
player.putCardsOnBottomOfLibrary(card, game, source, true);
player.putCardsOnBottomOfLibrary(card, game, source);
}
}
return true;

View file

@ -36,7 +36,6 @@ import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
@ -173,7 +172,7 @@ class QuintoriusLoremasterReplacementEffect extends ReplacementEffectImpl {
Card card = mor.getCard(game);
return controller != null
&& card != null
&& controller.putCardsOnBottomOfLibrary(card, game, source, false);
&& controller.putCardsOnBottomOfLibrary(card, game, source);
}
@Override

View file

@ -69,7 +69,7 @@ class SinisterWaltzEffect extends OneShotEffect {
}
player.moveCards(cards, Zone.BATTLEFIELD, source, game);
if (card != null) {
player.putCardsOnBottomOfLibrary(card, game, source, false);
player.putCardsOnBottomOfLibrary(card, game, source);
}
return true;
}

View file

@ -72,6 +72,6 @@ class TemporalCleansingEffect extends OneShotEffect {
)) {
return player.putCardOnTopXOfLibrary(permanent, game, source, 2, true);
}
return player.putCardsOnBottomOfLibrary(permanent, game, source, false);
return player.putCardsOnBottomOfLibrary(permanent, game, source);
}
}

View file

@ -93,7 +93,7 @@ class TolarianContemptEffect extends OneShotEffect {
)) {
owner.putCardsOnTopOfLibrary(permanent, game, source, false);
} else {
owner.putCardsOnBottomOfLibrary(permanent, game, source, false);
owner.putCardsOnBottomOfLibrary(permanent, game, source);
}
}
return true;

View file

@ -85,7 +85,7 @@ class VolcanicSpiteEffect extends OneShotEffect {
if (card == null) {
return false;
}
if (player.putCardsOnBottomOfLibrary(card, game, source, false)) {
if (player.putCardsOnBottomOfLibrary(card, game, source)) {
player.drawCards(1, source, game);
}
return true;

View file

@ -84,7 +84,7 @@ class WriteIntoBeingEffect extends OneShotEffect {
if (controller.getLibrary().hasCards()) {
Card cardToPutBack = controller.getLibrary().getFromTop(game);
if (controller.chooseUse(Outcome.Detriment, "Put " + cardToPutBack.getName() + " on bottom of library?", source, game)) {
controller.putCardsOnBottomOfLibrary(cardToPutBack, game, source, true);
controller.putCardsOnBottomOfLibrary(cardToPutBack, game, source);
} else {
controller.putCardsOnTopOfLibrary(cardToPutBack, game, source, true);
}

View file

@ -109,7 +109,7 @@ class YidaroWanderingMonsterEffect extends OneShotEffect {
}
YidaroWanderingMonsterWatcher watcher = game.getState().getWatcher(YidaroWanderingMonsterWatcher.class);
if (watcher == null || watcher.getYidaroCount(player.getId()) < 4) {
player.putCardsOnBottomOfLibrary(card, game, source, true);
player.putCardsOnBottomOfLibrary(card, game, source);
player.shuffleLibrary(source, game);
} else {
player.moveCards(card, Zone.BATTLEFIELD, source, game);

View file

@ -295,6 +295,7 @@ public final class FinalFantasy extends ExpansionSet {
cards.add(new SetCardInfo("Malboro", 106, Rarity.COMMON, mage.cards.m.Malboro.class));
cards.add(new SetCardInfo("Matoya, Archon Elder", 439, Rarity.RARE, mage.cards.m.MatoyaArchonElder.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Matoya, Archon Elder", 62, Rarity.RARE, mage.cards.m.MatoyaArchonElder.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Memories Returning", 63, Rarity.RARE, mage.cards.m.MemoriesReturning.class));
cards.add(new SetCardInfo("Midgar, City of Mako", 286, Rarity.RARE, mage.cards.m.MidgarCityOfMako.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Midgar, City of Mako", 313, Rarity.RARE, mage.cards.m.MidgarCityOfMako.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Minwu, White Mage", 26, Rarity.RARE, mage.cards.m.MinwuWhiteMage.class, NON_FULL_USE_VARIOUS));

View file

@ -3240,8 +3240,8 @@ public class TestPlayer implements Player {
}
@Override
public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
return computerPlayer.putCardsOnBottomOfLibrary(card, game, source, anyOrder);
public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source) {
return computerPlayer.putCardsOnBottomOfLibrary(card, game, source);
}
@Override

View file

@ -1,6 +1,5 @@
package mage.abilities.effects.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -46,6 +45,6 @@ public class PutOnLibrarySourceEffect extends OneShotEffect {
if (onTop) {
return player.putCardsOnTopOfLibrary(card, game, source, false);
}
return player.putCardsOnBottomOfLibrary(card, game, source, false);
return player.putCardsOnBottomOfLibrary(card, game, source);
}
}

View file

@ -715,7 +715,7 @@ public interface Player extends MageItem, Copyable<Player> {
*/
boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder);
boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source);
/**
* Moves the card to the top x position of the library

View file

@ -1034,8 +1034,8 @@ public abstract class PlayerImpl implements Player, Serializable {
}
@Override
public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
return putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, anyOrder);
public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source) {
return putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, false);
}
@Override