* Some more fixed/reworked card movement handling.

This commit is contained in:
LevelX2 2018-05-08 23:46:34 +02:00
parent d07209c33b
commit dcd3e7c039
34 changed files with 253 additions and 436 deletions

View file

@ -1,6 +1,5 @@
XMage.de 1 (Europe/Germany) fast :xmage.de:17171 XMage.de 1 (Europe/Germany) fast :xmage.de:17171
old xmage.de (Europe/Germany) :185.3.232.200:17171 old xmage.de (Europe/Germany) :185.3.232.200:17171
xmage.us (North America/USA) :xmage.us:17171
XMage Players MTG:xmageplayersmtg.ddns.net:17171 XMage Players MTG:xmageplayersmtg.ddns.net:17171
XMage.tahiti :xmage.tahiti.one:443 XMage.tahiti :xmage.tahiti.one:443
Seedds Server (Asia) :115.29.203.80:17171 Seedds Server (Asia) :115.29.203.80:17171

View file

@ -79,29 +79,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
} }
Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard();
if (spellCard != null) { if (spellCard != null) {
List<Card> top6 = new ArrayList<>(); controller.putCardOnTopXOfLibrary(spellCard, game, source, 7);
// Cut the top 6 cards off into a temporary array
for (int i = 0; i < 6 && controller.getLibrary().hasCards(); ++i) {
top6.add(controller.getLibrary().removeFromTop(game));
}
// Is the library now empty, thus the rise is on the bottom (for the message to the players)?
boolean isOnBottom = controller.getLibrary().size() < 6;
// Put this card (if the ability came from an ApproachOfTheSecondSun spell card) on top
spellCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
// put the top 6 we took earlier back on top (going in reverse order this time to get them back
// on top in the proper order)
for (int i = top6.size() - 1; i >= 0; --i) {
controller.getLibrary().putOnTop(top6.get(i), game);
}
// Inform the players
if (isOnBottom) {
game.informPlayers(controller.getLogName() + " puts " + spell.getLogName() + " on the bottom of their library.");
} else {
game.informPlayers(controller.getLogName() + " puts " + spell.getLogName() + " into their library 7th from the top.");
}
} }
} }
return true; return true;

View file

@ -30,12 +30,10 @@ package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
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.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
@ -48,8 +46,7 @@ import mage.target.common.TargetCreaturePermanent;
public class Chronostutter extends CardImpl { public class Chronostutter extends CardImpl {
public Chronostutter(UUID ownerId, CardSetInfo setInfo) { public Chronostutter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{U}");
// Put target creature into its owner's library second from the top. // Put target creature into its owner's library second from the top.
this.getSpellAbility().addEffect(new ChronostutterEffect()); this.getSpellAbility().addEffect(new ChronostutterEffect());
@ -85,22 +82,11 @@ class ChronostutterEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId());
if (permanent != null) { if (controller != null) {
Player owner = game.getPlayer(permanent.getOwnerId()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(permanent.getControllerId()); if (permanent != null) {
if (owner == null || controller == null) { controller.putCardOnTopXOfLibrary(permanent, game, source, 2);
return false;
}
Card card = null;
if (owner.getLibrary().hasCards()) {
card = owner.getLibrary().removeFromTop(game);
}
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
if (card != null) {
owner.getLibrary().putOnTop(card, game);
} }
return true; return true;
} }

View file

@ -33,7 +33,6 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.keyword.AftermathAbility; import mage.abilities.keyword.AftermathAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.SplitCard; import mage.cards.SplitCard;
@ -107,43 +106,16 @@ class CommitEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId());
if (permanent != null) { if (controller != null) {
Player owner = game.getPlayer(permanent.getOwnerId()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(permanent.getControllerId()); if (permanent != null) {
if (owner == null || controller == null) { return controller.putCardOnTopXOfLibrary(permanent, game, source, 2);
return false;
} }
Spell spell = game.getStack().getSpell(source.getFirstTarget());
Card card = null; if (spell != null) {
if (owner.getLibrary().hasCards()) { return controller.putCardOnTopXOfLibrary(spell, game, source, 2);
card = owner.getLibrary().removeFromTop(game);
} }
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
if (card != null) {
owner.getLibrary().putOnTop(card, game);
}
return true;
}
Spell spell = game.getStack().getSpell(source.getFirstTarget());
if (spell != null) {
Player owner = game.getPlayer(spell.getOwnerId());
Player controller = game.getPlayer(spell.getControllerId());
if (owner == null || controller == null) {
return false;
}
Card card = null;
if (owner.getLibrary().hasCards()) {
card = owner.getLibrary().removeFromTop(game);
}
spell.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
if (card != null) {
owner.getLibrary().putOnTop(card, game);
}
return true;
} }
return false; return false;
} }

View file

@ -89,21 +89,19 @@ class CreamOfTheCropEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game);
if (player != null && permanent != null) { if (controller != null && permanent != null) {
int numLooked = Math.min(permanent.getPower().getValue(), player.getLibrary().size()); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, permanent.getPower().getValue()));
if (numLooked > 0) { if (!cards.isEmpty()) {
Cards cards = new CardsImpl();
for (int i = 0; i < numLooked; i++) {
cards.add(player.getLibrary().removeFromTop(game));
}
TargetCard target = new TargetCardInHand(new FilterCard("card to put on top of your library")); TargetCard target = new TargetCardInHand(new FilterCard("card to put on top of your library"));
player.choose(Outcome.Benefit, cards, target, game); controller.choose(Outcome.Benefit, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
cards.remove(card); if (card != null) {
player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); cards.remove(card);
player.putCardsOnBottomOfLibrary(cards, game, source, true); controller.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, true);
}
controller.putCardsOnBottomOfLibrary(cards, game, source, true);
} }
return true; return true;
} }

View file

@ -89,51 +89,30 @@ class CruelFateEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard != null) { if (sourceCard != null) {
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(source.getFirstTarget()); Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null && you != null) { if (targetOpponent != null && controller != null) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(targetOpponent.getLibrary().getTopCards(game, 5));
int count = Math.min(player.getLibrary().size(), 5); controller.lookAtCards(source, null, cards, game);
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
you.lookAtCards(sourceCard.getIdName(), cards, game);
// card to put into opponent's graveyard // card to put into opponent's graveyard
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard")); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard"));
if (player.canRespond()) { if (targetOpponent.isInGame()) {
if (cards.size() > 1) { if (cards.size() > 1) {
you.choose(Outcome.Detriment, cards, target, game); controller.choose(Outcome.Detriment, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); controller.moveCards(card, Zone.GRAVEYARD, source, game);
} }
} } else if (cards.size() == 1) {
else if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game); Card card = cards.get(cards.iterator().next(), game);
controller.moveCards(card, Zone.GRAVEYARD, source, game);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
cards.clear();
} }
} }
// cards to put on the top of opponent's library controller.putCardsOnTopOfLibrary(cards, game, source, true);
TargetCard target2 = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on the top of target opponent's library"));
while (player.canRespond() && cards.size() > 1) {
you.choose(Outcome.Neutral, cards, target2, game);
Card card = cards.get(target2.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
target2.clearChosen();
}
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
return true; return true;
} }
} }

View file

@ -87,14 +87,7 @@ class DarkBargainEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
MageObject sourceOject = source.getSourceObject(game); MageObject sourceOject = source.getSourceObject(game);
if (player != null && sourceOject != null) { if (player != null && sourceOject != null) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3));
int cardsCount = Math.min(3, player.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
Cards cardsToHand = new CardsImpl(); Cards cardsToHand = new CardsImpl();
player.lookAtCards(sourceOject.getIdName(), cards, game); player.lookAtCards(sourceOject.getIdName(), cards, game);

View file

@ -34,8 +34,8 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.*; import mage.cards.*;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -49,7 +49,7 @@ import mage.players.Player;
public class DarkConfidant extends CardImpl { public class DarkConfidant extends CardImpl {
public DarkConfidant(UUID ownerId, CardSetInfo setInfo) { public DarkConfidant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD); this.subtype.add(SubType.WIZARD);
@ -87,7 +87,7 @@ class DarkConfidantEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && sourcePermanent != null) { if (controller != null && sourcePermanent != null) {
if (controller.getLibrary().hasCards()) { if (controller.getLibrary().hasCards()) {
Card card = controller.getLibrary().removeFromTop(game); Card card = controller.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
Cards cards = new CardsImpl(card); Cards cards = new CardsImpl(card);
controller.revealCards(sourcePermanent.getIdName(), cards, game); controller.revealCards(sourcePermanent.getIdName(), cards, game);

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.cards.d; package mage.cards.d;
import java.util.UUID; import java.util.UUID;
@ -47,7 +46,7 @@ import mage.players.Player;
public class DarkTutelage extends CardImpl { public class DarkTutelage extends CardImpl {
public DarkTutelage(UUID ownerId, CardSetInfo setInfo) { public DarkTutelage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new DarkTutelageEffect(), false)); this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new DarkTutelageEffect(), false));
} }
@ -75,15 +74,13 @@ class DarkTutelageEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (player != null && player.getLibrary().hasCards()) { if (controller != null) {
Card card = player.getLibrary().removeFromTop(game); Card card = controller.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
controller.revealCards(source, new CardsImpl(card), game);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
player.loseLife(card.getConvertedManaCost(), game, false); controller.loseLife(card.getConvertedManaCost(), game, false);
Cards cards = new CardsImpl();
cards.add(card);
player.revealCards("Dark Tutelage", cards, game);
return true; return true;
} }
} }

View file

@ -32,8 +32,6 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card; import mage.cards.Card;
@ -41,6 +39,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -103,15 +103,15 @@ class DemonlordBelzenlokEffect extends OneShotEffect {
} }
boolean cont = true; boolean cont = true;
int addedToHand = 0; int addedToHand = 0;
while (controller.getLibrary().hasCards() && controller.canRespond() && cont) { while (controller.getLibrary().hasCards() && cont) {
Card card = controller.getLibrary().removeFromTop(game); Card card = controller.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
controller.moveCardToExileWithInfo(card, null, null, source.getSourceId(), game, Zone.LIBRARY, true); controller.moveCards(card, Zone.EXILED, source, game);
if (!card.isLand()) { if (!card.isLand()) {
if (card.getConvertedManaCost() < 4) { if (card.getConvertedManaCost() < 4) {
cont = false; cont = false;
} }
card.moveToZone(Zone.HAND, source.getSourceId(), game, true); controller.moveCards(card, Zone.HAND, source, game);
addedToHand++; addedToHand++;
} }
} }

View file

@ -89,27 +89,15 @@ class DeployTheGatewatchEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller == null) { if (controller == null) {
return false; return false;
} }
// Look at the top seven cards of your library. // Look at the top seven cards of your library.
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 7));
boolean planeswalkerIncluded = false; controller.lookAtCards(source, null, cards, game);
for (int i = 0; i < 7; i++) {
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
if (filter.match(card, game)) {
planeswalkerIncluded = true;
}
}
}
controller.lookAtCards("Deploy the Gatewatch", cards, game);
// Put up to two planeswalker cards from among them onto the battlefield. // Put up to two planeswalker cards from among them onto the battlefield.
if (planeswalkerIncluded) { if (cards.count(filter, game) > 0) {
TargetCard target = new TargetCard(0, 2, Zone.LIBRARY, filter); TargetCard target = new TargetCard(0, 2, Zone.LIBRARY, filter);
if (controller.choose(Outcome.DrawCard, cards, target, game)) { if (controller.choose(Outcome.DrawCard, cards, target, game)) {
Cards pickedCards = new CardsImpl(target.getTargets()); Cards pickedCards = new CardsImpl(target.getTargets());
@ -117,7 +105,6 @@ class DeployTheGatewatchEffect extends OneShotEffect {
controller.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game); controller.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game);
} }
} }
// Put the rest on the bottom of your library in a random order // Put the rest on the bottom of your library in a random order
controller.putCardsOnBottomOfLibrary(cards, game, source, false); controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true; return true;

View file

@ -28,7 +28,6 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
@ -48,7 +47,7 @@ import mage.target.common.TargetLandPermanent;
public class DestroyTheEvidence extends CardImpl { public class DestroyTheEvidence extends CardImpl {
public DestroyTheEvidence(UUID ownerId, CardSetInfo setInfo) { public DestroyTheEvidence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Destroy target land. Its controller reveals cards from the top of his // Destroy target land. Its controller reveals cards from the top of his
// or her library until he or she reveals a land card, then puts those cards into their graveyard. // or her library until he or she reveals a land card, then puts those cards into their graveyard.
@ -87,27 +86,21 @@ class DestroyTheEvidenceEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent landPermanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Permanent landPermanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
MageObject sourceObject = source.getSourceObject(game); if (landPermanent != null) {
if (sourceObject != null && landPermanent != null) {
Player player = game.getPlayer(landPermanent.getControllerId()); Player player = game.getPlayer(landPermanent.getControllerId());
if (player == null) { if (player == null) {
return false; return false;
} }
boolean landFound = false;
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
while (player.getLibrary().hasCards() && !landFound) { for (Card card : player.getLibrary().getCards(game)) {
if (!player.canRespond()) {
return false;
}
Card card = player.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
cards.add(card); cards.add(card);
if (card.isLand()) { if (card.isLand()) {
landFound = true; break;
} }
} }
} }
player.revealCards(sourceObject.getName(), cards, game, true); player.revealCards(source, cards, game);
player.moveCards(cards, Zone.GRAVEYARD, source, game); player.moveCards(cards, Zone.GRAVEYARD, source, game);
return true; return true;
} }

View file

@ -64,9 +64,8 @@ public class DimirCharm extends CardImpl {
filterSorcery.add(new CardTypePredicate(CardType.SORCERY)); filterSorcery.add(new CardTypePredicate(CardType.SORCERY));
} }
public DimirCharm (UUID ownerId, CardSetInfo setInfo) { public DimirCharm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}{B}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{B}");
//Choose one - Counter target sorcery spell //Choose one - Counter target sorcery spell
this.getSpellAbility().addEffect(new CounterTargetEffect()); this.getSpellAbility().addEffect(new CounterTargetEffect());
@ -90,14 +89,15 @@ public class DimirCharm extends CardImpl {
} }
@Override @Override
public DimirCharm copy() { public DimirCharm copy() {
return new DimirCharm(this); return new DimirCharm(this);
} }
} }
class DimirCharmEffect extends OneShotEffect { class DimirCharmEffect extends OneShotEffect {
public DimirCharmEffect() { public DimirCharmEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
} }
public DimirCharmEffect(final DimirCharmEffect effect) { public DimirCharmEffect(final DimirCharmEffect effect) {
@ -106,27 +106,21 @@ class DimirCharmEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if(controller != null && player != null){ if (controller != null && player != null) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3));
for(int i = 0; i < 3; i++){ if (!cards.isEmpty()) {
Card card = player.getLibrary().removeFromTop(game);
if(card != null){
cards.add(card);
}
}
if(!cards.isEmpty()){
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("Card to put back on top of library")); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("Card to put back on top of library"));
if(controller.chooseTarget(Outcome.Benefit, cards, target, source, game)){ if (controller.chooseTarget(Outcome.Benefit, cards, target, source, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if(card != null){ if (card != null) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
cards.remove(card); cards.remove(card);
} }
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
} }
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
} }
return true;
} }
return false; return false;
} }

View file

@ -31,9 +31,9 @@ import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.TransmuteAbility; import mage.abilities.keyword.TransmuteAbility;
import mage.cards.Card;
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;
@ -51,7 +51,7 @@ import mage.target.TargetPlayer;
public class DimirMachinations extends CardImpl { public class DimirMachinations extends CardImpl {
public DimirMachinations(UUID ownerId, CardSetInfo setInfo) { public DimirMachinations(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Look at the top three cards of target player's library. Exile any number of those cards, then put the rest back in any order. // Look at the top three cards of target player's library. Exile any number of those cards, then put the rest back in any order.
this.getSpellAbility().addEffect(new DimirMachinationsEffect()); this.getSpellAbility().addEffect(new DimirMachinationsEffect());
@ -93,37 +93,16 @@ class DimirMachinationsEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (controller != null && targetPlayer != null) { if (controller != null && targetPlayer != null) {
int numCardsToLookAt = Math.min(3, targetPlayer.getLibrary().size()); CardsImpl cards = new CardsImpl(targetPlayer.getLibrary().getTopCards(game, 3));
if (numCardsToLookAt > 0) { if (!cards.isEmpty()) {
CardsImpl cards = new CardsImpl(); controller.lookAtCards(source, null, cards, game);
for (int i = 0; i < numCardsToLookAt; i++) { TargetCard targetExile = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, new FilterCard("cards to exile"));
cards.add(targetPlayer.getLibrary().removeFromTop(game));
}
TargetCard targetExile = new TargetCard(0, numCardsToLookAt, Zone.LIBRARY, new FilterCard("card to exile"));
if (controller.choose(Outcome.Exile, cards, targetExile, game)) { if (controller.choose(Outcome.Exile, cards, targetExile, game)) {
for (UUID cardId : targetExile.getTargets()) { Cards toExile = new CardsImpl(targetExile.getTargets());
Card card = cards.get(cardId, game); controller.moveCards(toExile, Zone.EXILED, source, game);
if (card != null) { cards.removeAll(toExile);
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true);
cards.remove(card);
}
}
while (!cards.isEmpty()) {
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false);
cards.remove(card);
}
else {
TargetCard targetTop = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on top of library"));
if (controller.choose(Outcome.Neutral, cards, targetTop, game)) {
Card card = cards.get(targetTop.getFirstTarget(), game);
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false);
cards.remove(card);
}
}
}
} }
controller.putCardsOnTopOfLibrary(cards, game, source, true);
} }
return true; return true;
} }

View file

@ -105,23 +105,18 @@ class DivergentTransformationsEffect extends OneShotEffect {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
if (player.getLibrary().hasCards()) { if (player.getLibrary().hasCards()) {
Cards cards = new CardsImpl(); Cards toReveal = new CardsImpl();
Card card = player.getLibrary().removeFromTop(game); for (Card card : player.getLibrary().getCards(game)) {
cards.add(card); toReveal.add(card);
while (!card.isCreature() && player.getLibrary().hasCards()) { if (card.isCreature()) {
card = player.getLibrary().removeFromTop(game); player.revealCards(source, toReveal, game);
cards.add(card); player.moveCards(card, Zone.BATTLEFIELD, source, game);
toReveal.remove(card);
break;
}
} }
if (!toReveal.isEmpty()) {
if (card.isCreature()) { player.shuffleLibrary(source, game);
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
}
if (!cards.isEmpty()) {
player.revealCards(sourceObject.getIdName(), cards, game);
Set<Card> cardsToShuffle = cards.getCards(game);
cardsToShuffle.remove(card);
player.getLibrary().addAll(cardsToShuffle, game);
} }
} }
} }

View file

@ -35,8 +35,8 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -98,13 +98,11 @@ class DuskmantleSeerEffect extends OneShotEffect {
} }
for (Player player : game.getPlayers().values()) { for (Player player : game.getPlayers().values()) {
if (player.getLibrary().hasCards()) { if (player.getLibrary().hasCards()) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
Cards cards = new CardsImpl(); player.revealCards(source, ": Revealed by " + player.getName(), new CardsImpl(card), game);
cards.add(card);
player.revealCards(sourceCard.getName() + ": Revealed by " + player.getName(), cards, game);
player.loseLife(card.getConvertedManaCost(), game, false); player.loseLife(card.getConvertedManaCost(), game, false);
card.moveToZone(Zone.HAND, source.getSourceId(), game, true); player.moveCards(card, Zone.HAND, source, game);
} }
} }
} }

View file

@ -47,7 +47,7 @@ import mage.target.TargetPlayer;
public class ElementalAugury extends CardImpl { public class ElementalAugury extends CardImpl {
public ElementalAugury(UUID ownerId, CardSetInfo setInfo) { public ElementalAugury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}{B}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{B}{R}");
// {3}: Look at the top three cards of target player's library, then put them back in any order. // {3}: Look at the top three cards of target player's library, then put them back in any order.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElementalAuguryEffect(), new ManaCostsImpl("3")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElementalAuguryEffect(), new ManaCostsImpl("3"));
@ -89,15 +89,8 @@ class ElementalAuguryEffect extends OneShotEffect {
|| controller == null) { || controller == null) {
return false; return false;
} }
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(targetPlayer.getLibrary().getTopCards(game, 3));
int count = Math.min(targetPlayer.getLibrary().size(), 3); controller.lookAtCards(source, null, cards, game);
for (int i = 0; i < count; i++) {
Card card = targetPlayer.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
controller.lookAtCards("Elemental Augury", cards, game);
controller.putCardsOnTopOfLibrary(cards, game, source, true); controller.putCardsOnTopOfLibrary(cards, game, source, true);
return true; return true;
} }

View file

@ -40,13 +40,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.turn.Step;
import mage.players.Library;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/** /**
* *
@ -55,7 +51,7 @@ import mage.target.targetpointer.FixedTarget;
public class ElkinBottle extends CardImpl { public class ElkinBottle extends CardImpl {
public ElkinBottle(UUID ownerId, CardSetInfo setInfo) { public ElkinBottle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {3}, {tap}, Exile the top card of your library. Until the beginning of your next upkeep, you may play that card. // {3}, {tap}, Exile the top card of your library. Until the beginning of your next upkeep, you may play that card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElkinBottleExileEffect(), new GenericManaCost(3)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElkinBottleExileEffect(), new GenericManaCost(3));
@ -92,13 +88,10 @@ class ElkinBottleExileEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null) {
if (sourcePermanent != null && controller != null && controller.getLibrary().hasCards()) { Card card = controller.getLibrary().getFromTop(game);
Library library = controller.getLibrary();
Card card = library.removeFromTop(game);
if (card != null) { if (card != null) {
String exileName = new StringBuilder(sourcePermanent.getIdName()).append(" <this card may be played until the beginning of your next upkeep>").toString(); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, null));
controller.moveCardToExileWithInfo(card, source.getSourceId(), exileName, source.getSourceId(), game, Zone.LIBRARY, true);
ContinuousEffect effect = new ElkinBottleCastFromExileEffect(); ContinuousEffect effect = new ElkinBottleCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId())); effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source); game.addEffect(effect, source);

View file

@ -47,7 +47,6 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Library;
import mage.players.Player; import mage.players.Player;
/** /**
@ -147,22 +146,14 @@ class EnigmaSphinxEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId());
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { if (controller == null) {
Player owner = game.getPlayer(card.getOwnerId()); return false;
if (owner != null && card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true)) {
// Move Sphinx to third position
game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top");
Library lib = owner.getLibrary();
if (lib != null) {
Card card1 = lib.removeFromTop(game);
if (card1 != null && card1.getId().equals(source.getSourceId())) {
lib.putCardThirdFromTheTop(card1, game);
return true;
}
}
}
} }
return false; Card card = (Card) source.getSourceObjectIfItStillExists(game);
if (card != null) {
controller.putCardOnTopXOfLibrary(card, game, source, 3);
}
return true;
} }
} }

View file

@ -28,7 +28,6 @@
package mage.cards.e; package mage.cards.e;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -51,7 +50,7 @@ public class ErraticExplosion extends CardImpl {
public ErraticExplosion(UUID ownerId, CardSetInfo setInfo) { public ErraticExplosion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
// Choose any target. Reveal cards from the top of your library until you reveal a nonland card. Erratic Explosion deals damage equal to that card's converted mana cost to that creature or player. Put the revealed cards on the bottom of your library in any order. // Choose any target. Reveal cards from the top of your library until you reveal a nonland card. Erratic Explosion deals damage equal to that card's converted mana cost to that permanent or player. Put the revealed cards on the bottom of your library in any order.
this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new ErraticExplosionEffect()); this.getSpellAbility().addEffect(new ErraticExplosionEffect());
} }
@ -85,22 +84,17 @@ class ErraticExplosionEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null) {
if (controller != null && sourceObject != null) {
CardsImpl toReveal = new CardsImpl(); CardsImpl toReveal = new CardsImpl();
Card nonLandCard = null; Card nonLandCard = null;
for (Card card : controller.getLibrary().getCards(game)) {
while (nonLandCard == null && controller.getLibrary().hasCards()) {
Card card = controller.getLibrary().removeFromTop(game);
toReveal.add(card); toReveal.add(card);
if (!card.isLand()) { if (!card.isLand()) {
nonLandCard = card; nonLandCard = card;
break;
} }
} }
// reveal cards controller.revealCards(source, toReveal, game);
if (!toReveal.isEmpty()) {
controller.revealCards(sourceObject.getIdName(), toReveal, game);
}
// the nonland card // the nonland card
if (nonLandCard != null) { if (nonLandCard != null) {
Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source));

View file

@ -52,7 +52,7 @@ import mage.target.targetpointer.FixedTarget;
public class ErraticMutation extends CardImpl { public class ErraticMutation extends CardImpl {
public ErraticMutation(UUID ownerId, CardSetInfo setInfo) { public ErraticMutation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
// Choose target creature. Reveal cards from the top of your library until you reveal a nonland card. That creature gets +X/-X until end of turn, where X is that card's converted mana cost. Put all cards revealed this way on the bottom of your library in any order. // Choose target creature. Reveal cards from the top of your library until you reveal a nonland card. That creature gets +X/-X until end of turn, where X is that card's converted mana cost. Put all cards revealed this way on the bottom of your library in any order.
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());
@ -93,18 +93,16 @@ class ErraticMutationEffect extends OneShotEffect {
if (controller != null && sourceObject != null) { if (controller != null && sourceObject != null) {
CardsImpl toReveal = new CardsImpl(); CardsImpl toReveal = new CardsImpl();
Card nonLandCard = null; Card nonLandCard = null;
for (Card card : controller.getLibrary().getCards(game)) {
while (nonLandCard == null && controller.getLibrary().hasCards()) {
Card card = controller.getLibrary().removeFromTop(game);
toReveal.add(card); toReveal.add(card);
if (!card.isLand()) { if (!card.isLand()) {
nonLandCard = card; nonLandCard = card;
break;
} }
} }
// reveal cards // reveal cards
if (!toReveal.isEmpty()) { controller.revealCards(sourceObject.getIdName(), toReveal, game);
controller.revealCards(sourceObject.getIdName(), toReveal, game);
}
// the nonland card // the nonland card
if (nonLandCard != null) { if (nonLandCard != null) {
int boostValue = nonLandCard.getConvertedManaCost(); int boostValue = nonLandCard.getConvertedManaCost();

View file

@ -90,22 +90,19 @@ class ExplosiveRevelationEffect extends OneShotEffect {
MageObject sourceObject = source.getSourceObject(game); MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) { if (controller != null && sourceObject != null) {
if (controller.getLibrary().hasCards()) { if (controller.getLibrary().hasCards()) {
CardsImpl toReveal = new CardsImpl();
CardsImpl cards = new CardsImpl();
Library library = controller.getLibrary(); Library library = controller.getLibrary();
Card card = null; Card nonLandCard = null;
do { for (Card card : library.getCards(game)) {
card = library.removeFromTop(game); toReveal.add(card);
if (card != null) { if (!card.isLand()) {
cards.add(card); nonLandCard = card;
} }
} while (library.hasCards() && card != null && card.isLand());
// reveal cards
if (!cards.isEmpty()) {
controller.revealCards(sourceObject.getIdName(), cards, game);
} }
// reveal cards
controller.revealCards(sourceObject.getIdName(), toReveal, game);
// the nonland card // the nonland card
int damage = card.getConvertedManaCost(); int damage = nonLandCard == null ? 0 : nonLandCard.getConvertedManaCost();
// assign damage to target // assign damage to target
for (UUID targetId : targetPointer.getTargets(game, source)) { for (UUID targetId : targetPointer.getTargets(game, source)) {
Permanent targetedCreature = game.getPermanent(targetId); Permanent targetedCreature = game.getPermanent(targetId);
@ -118,12 +115,13 @@ class ExplosiveRevelationEffect extends OneShotEffect {
} }
} }
} }
// move nonland card to hand if (nonLandCard != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, true); // move nonland card to hand
// remove nonland card from revealed card list controller.moveCards(nonLandCard, Zone.HAND, source, game);
cards.remove(card); toReveal.remove(nonLandCard);
}
// put the rest of the cards on the bottom of the library in any order // put the rest of the cards on the bottom of the library in any order
return controller.putCardsOnBottomOfLibrary(cards, game, source, true); return controller.putCardsOnBottomOfLibrary(toReveal, game, source, true);
} }
return true; return true;
} }

View file

@ -106,29 +106,17 @@ class EyeOfYawgmothEffect extends OneShotEffect {
} }
} }
if (power > 0) { if (power > 0) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, power));
int count = Math.min(controller.getLibrary().size(), power); controller.revealCards(source, cards, game);
for (int i = 0; i < count; i++) {
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
controller.revealCards(source.getSourceObject(game).getIdName(), cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand")); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (controller.choose(Outcome.DrawCard, cards, target, game)) { if (controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
controller.moveCards(card, Zone.HAND, source, game);
cards.remove(card); cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
game.informPlayers(source.getSourceObject(game).getIdName() + ": " + controller.getLogName() + " puts " + card.getIdName() + " into their hand");
} }
} }
for (UUID cardId : cards) { controller.moveCards(cards, Zone.EXILED, source, game);
Card card = game.getCard(cardId);
card.moveToExile(null, "", source.getSourceId(), game);
}
} }
return true; return true;
} }

View file

@ -27,8 +27,6 @@
*/ */
package mage.cards.f; package mage.cards.f;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -37,18 +35,21 @@ import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.dynamicvalue.common.CountersSourceCount;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.Card;
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.constants.*; import mage.constants.*;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.players.Library;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
/** /**
* *
@ -57,7 +58,7 @@ import mage.target.common.TargetCardInYourGraveyard;
public class FlamesOfRemembrance extends CardImpl { public class FlamesOfRemembrance extends CardImpl {
public FlamesOfRemembrance(UUID ownerId, CardSetInfo setInfo) { public FlamesOfRemembrance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}");
// At the beggining of your upkeep, you may exile a card from your graveyard. If you do, put a lore counter on Flames of Remembrance. // At the beggining of your upkeep, you may exile a card from your graveyard. If you do, put a lore counter on Flames of Remembrance.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid(new AddCountersSourceEffect(CounterType.LORE.createInstance()), new ExileFromGraveCost(new TargetCardInYourGraveyard()), null, true), TargetController.YOU, false)); this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid(new AddCountersSourceEffect(CounterType.LORE.createInstance()), new ExileFromGraveCost(new TargetCardInYourGraveyard()), null, true), TargetController.YOU, false));
@ -83,7 +84,7 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect {
public FlamesOfRemembranceExileEffect(CountersSourceCount amount) { public FlamesOfRemembranceExileEffect(CountersSourceCount amount) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.amount = amount; this.amount = amount;
this.staticText = "Exile top X cards of your library, where X is the number of lore counters on Flames of Remembrance. Until end of turn you play cards exile this way"; this.staticText = "Exile top X cards of your library, where X is the number of lore counters on {this}. Until end of turn you play cards exile this way";
} }
public FlamesOfRemembranceExileEffect(final FlamesOfRemembranceExileEffect effect) { public FlamesOfRemembranceExileEffect(final FlamesOfRemembranceExileEffect effect) {
@ -100,23 +101,12 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, amount.calculate(game, source, this)));
Library library = controller.getLibrary();
List<Card> cards = new ArrayList<>();
int count = Math.min(amount.calculate(game, source, this), library.size());
for (int i = 0; i < count; i++) {
Card card = library.removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
List<UUID> cardsId = new ArrayList<>(); controller.moveCardsToExile(cards.getCards(game), source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, ""));
for (Card card : cards) { ContinuousEffect effect = new FlamesOfRemembranceMayPlayExiledEffect();
card.moveToExile(source.getSourceId(), "Flames of Remembrance", source.getSourceId(), game); effect.setTargetPointer(new FixedTargets(cards, game));
cardsId.add(card.getId()); game.addEffect(effect, source);
}
game.addEffect(new FlamesOfRemembranceMayPlayExiledEffect(cardsId), source);
} }
return true; return true;
} }
@ -127,16 +117,12 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect {
class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl { class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl {
public List<UUID> cards = new ArrayList<>(); public FlamesOfRemembranceMayPlayExiledEffect() {
public FlamesOfRemembranceMayPlayExiledEffect(List<UUID> cards) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
this.cards.addAll(cards);
} }
public FlamesOfRemembranceMayPlayExiledEffect(final FlamesOfRemembranceMayPlayExiledEffect effect) { public FlamesOfRemembranceMayPlayExiledEffect(final FlamesOfRemembranceMayPlayExiledEffect effect) {
super(effect); super(effect);
this.cards.addAll(effect.cards);
} }
@Override @Override
@ -150,15 +136,7 @@ class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); return source.getControllerId().equals(affectedControllerId) && this.getTargetPointer().getTargets(game, source).contains(objectId);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
if (cards.contains(sourceId)) {
return true;
}
}
return false;
} }
} }

View file

@ -87,7 +87,7 @@ class LongTermPlansEffect extends OneShotEffect {
Card card = player.getLibrary().remove(target.getFirstTarget(), game); Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
player.shuffleLibrary(source, game); player.shuffleLibrary(source, game);
player.getLibrary().putCardThirdFromTheTop(card, game); player.putCardOnTopXOfLibrary(card, game, source, 3);
} }
} }
return true; return true;

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.cards.o; package mage.cards.o;
import java.util.UUID; import java.util.UUID;
@ -42,12 +41,14 @@ import mage.constants.SubType;
public class OrochiSustainer extends CardImpl { public class OrochiSustainer extends CardImpl {
public OrochiSustainer(UUID ownerId, CardSetInfo setInfo) { public OrochiSustainer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.SNAKE); this.subtype.add(SubType.SNAKE);
this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// {T}: Add {G}.
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
} }

View file

@ -38,14 +38,12 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.UntapLandsEffect; import mage.abilities.effects.common.UntapLandsEffect;
import mage.cards.Card;
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.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.command.emblems.TeferiHeroOfDominariaEmblem; import mage.game.command.emblems.TeferiHeroOfDominariaEmblem;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -114,16 +112,7 @@ class TeferiHeroOfDominariaSecondEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {
Player owner = game.getPlayer(permanent.getOwnerId()); controller.putCardOnTopXOfLibrary(permanent, game, source, 3);
if (owner == null) {
return false;
}
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
Card card = owner.getLibrary().remove(permanent.getId(), game);
if (card != null) {
owner.getLibrary().putCardThirdFromTheTop(card, game);
game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top");
}
} }
return true; return true;
} }

View file

@ -1403,6 +1403,11 @@ public class TestPlayer implements Player {
return computerPlayer.putCardsOnBottomOfLibrary(cards, game, source, anyOrder); return computerPlayer.putCardsOnBottomOfLibrary(cards, game, source, anyOrder);
} }
@Override
public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) {
return computerPlayer.putCardOnTopXOfLibrary(card, game, source, xFromTheTop);
}
@Override @Override
public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) { public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) {
return computerPlayer.putCardsOnTopOfLibrary(cards, game, source, anyOrder); return computerPlayer.putCardsOnTopOfLibrary(cards, game, source, anyOrder);

View file

@ -908,6 +908,11 @@ public class PlayerStub implements Player {
return false; return false;
} }
@Override
public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) {
return true;
}
@Override @Override
public int announceXMana(int min, int max, String message, Game game, Ability ability) { public int announceXMana(int min, int max, String message, Game game, Ability ability) {
return 0; return 0;

View file

@ -135,26 +135,17 @@ public class Library implements Serializable {
} }
} }
public void putCardThirdFromTheTop(Card card, Game game) { public void putCardToTopXPos(Card card, int pos, Game game) {
if (card != null) { if (card != null && pos > -1) {
if (card.getOwnerId().equals(playerId)) { LinkedList<Card> save = new LinkedList<>();
Card cardTop = null; int idx = 1;
Card cardSecond = null; while (hasCards() && idx < pos) {
if (hasCards()) { idx++;
cardTop = removeFromTop(game); save.add(removeFromTop(game));
} }
if (hasCards()) { putOnTop(card, game);
cardSecond = removeFromTop(game); while (!save.isEmpty()) {
} putOnTop(save.removeLast(), game);
putOnTop(card, game);
if (cardSecond != null) {
putOnTop(cardSecond, game);
}
if (cardTop != null) {
putOnTop(cardTop, game);
}
} else {
game.getPlayer(card.getOwnerId()).getLibrary().putCardThirdFromTheTop(card, game);
} }
} }
} }

View file

@ -562,6 +562,17 @@ public interface Player extends MageItem, Copyable<Player> {
*/ */
boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder); boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
/**
* Moves the card to the top x position of the library
*
* @param card
* @param game
* @param source
* @param xFromTheTop
* @return
*/
boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop);
/** /**
* Moves the cards from cards to the top of players library. * Moves the cards from cards to the top of players library.
* *

View file

@ -84,6 +84,7 @@ import mage.game.events.ZoneChangeEvent;
import mage.game.match.MatchPlayer; import mage.game.match.MatchPlayer;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.SquirrelToken; import mage.game.permanent.token.SquirrelToken;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.game.stack.StackAbility; import mage.game.stack.StackAbility;
@ -894,6 +895,26 @@ public abstract class PlayerImpl implements Player, Serializable {
return true; return true;
} }
@Override
public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) {
if (card.getOwnerId().equals(getId())) {
if (library.size() + 1 < xFromTheTop) {
putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true);
} else {
if (card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true) && !(card instanceof PermanentToken) && !card.isCopy()) {
card = getLibrary().removeFromTop(game);
getLibrary().putCardToTopXPos(card, xFromTheTop, game);
game.informPlayers(card.getLogName() + " is put into " + getLogName() + "'s library " + CardUtil.numberToOrdinalText(xFromTheTop) + " from the top");
} else {
return false;
}
}
} else {
return game.getPlayer(card.getOwnerId()).putCardOnTopXOfLibrary(card, game, source, xFromTheTop);
}
return true;
}
/** /**
* Can be cards or permanents that go to library * Can be cards or permanents that go to library
* *
@ -1840,6 +1861,7 @@ public abstract class PlayerImpl implements Player, Serializable {
return gainLife(amount, game, source.getSourceId()); return gainLife(amount, game, source.getSourceId());
} }
@Override
public int gainLife(int amount, Game game, UUID sourceId) { public int gainLife(int amount, Game game, UUID sourceId) {
if (!canGainLife || amount == 0) { if (!canGainLife || amount == 0) {
return 0; return 0;

View file

@ -51,6 +51,9 @@ public final class CardUtil {
static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
static final String[] ordinalStrings = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eightth", "ninth",
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
/** /**
* Increase spell or ability cost to be paid. * Increase spell or ability cost to be paid.
* *
@ -363,6 +366,13 @@ public final class CardUtil {
return number; return number;
} }
public static String numberToOrdinalText(int number) {
if (number >= 1 && number < 21) {
return ordinalStrings[number - 1];
}
return Integer.toString(number) + "th";
}
public static String replaceSourceName(String message, String sourceName) { public static String replaceSourceName(String message, String sourceName) {
message = message.replace("{this}", sourceName); message = message.replace("{this}", sourceName);
message = message.replace("{source}", sourceName); message = message.replace("{source}", sourceName);

View file

@ -100,7 +100,9 @@ foreach my $card (sort cardSort @setCards) {
if ($toPrint) { if ($toPrint) {
$toPrint .= "\n"; $toPrint .= "\n";
} }
$toPrint .= "@{$card}[2]|@{$card}[0]"; my $cardName = @{$card}[0];
$cardName =~ s/ /+/g;
$toPrint .= "@{$card}[2]|[@{$card}[0]](https://magiccards.info/query?q=!$cardName)";
} }
} }
@ -125,7 +127,7 @@ foreach $cn (sort keys (%cardNames))
} }
my $cn2 = $cn; my $cn2 = $cn;
$cn2 =~ s/ /+/g; $cn2 =~ s/ /+/g;
print ISSUE_TRACKER "- $x_or_not [$cn](https://www.google.com.au/search?q=$cn2+MTG&tbm=isch)\n"; print ISSUE_TRACKER "- $x_or_not [$cn](https://magiccards.info/query?q=!$cn2)\n";
} }
close ISSUE_TRACKER; close ISSUE_TRACKER;
print ("Tracking Issue text for a new Github issue (similar to https://github.com/magefree/mage/issues/2215): " . lc($sets{$setName}) ."_issue_tracker.txt\n"); print ("Tracking Issue text for a new Github issue (similar to https://github.com/magefree/mage/issues/2215): " . lc($sets{$setName}) ."_issue_tracker.txt\n");