Some more rework of player.moveCard (mainly to graveyard).

This commit is contained in:
LevelX2 2015-05-23 15:35:40 +02:00
parent 039c4f22a6
commit ce64a22c15
79 changed files with 490 additions and 653 deletions

View file

@ -104,15 +104,15 @@ class EtherwroughtPageEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (you != null && you.getLibrary().size() > 0) { if (controller != null && controller.getLibrary().size() > 0) {
Card card = you.getLibrary().getFromTop(game); Card card = controller.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
CardsImpl cards = new CardsImpl(); CardsImpl cards = new CardsImpl();
cards.add(card); cards.add(card);
you.lookAtCards("Etherwrought Page", cards, game); controller.lookAtCards("Etherwrought Page", cards, game);
if (you.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) { if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
return card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
return true; return true;
} }

View file

@ -104,9 +104,7 @@ class MindFuneralEffect extends OneShotEffect {
cards.add(card); cards.add(card);
} }
opponent.revealCards("Mind Funeral", cards, game); opponent.revealCards("Mind Funeral", cards, game);
for (Card card: cards.getCards(game)) { opponent.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
return true; return true;
} }

View file

@ -55,7 +55,7 @@ public class HelmOfObedience extends CardImpl {
super(ownerId, 163, "Helm of Obedience", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}"); super(ownerId, 163, "Helm of Obedience", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}");
this.expansionSetCode = "ALL"; this.expansionSetCode = "ALL";
// {X}, {tap}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0. // {X}, {T}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0.
VariableManaCost xCosts = new VariableManaCost(); VariableManaCost xCosts = new VariableManaCost();
xCosts.setMinX(1); xCosts.setMinX(1);
SimpleActivatedAbility abilitiy = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HelmOfObedienceEffect(), xCosts); SimpleActivatedAbility abilitiy = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HelmOfObedienceEffect(), xCosts);
@ -106,7 +106,7 @@ class HelmOfObedienceEffect extends OneShotEffect {
while(player.getLibrary().size() > 0) { while(player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card != null){ if (card != null){
if(card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false)){ player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if(card.getCardType().contains(CardType.CREATURE)){ if(card.getCardType().contains(CardType.CREATURE)){
// If a creature card is put into that graveyard this way, sacrifice Helm of Obedience // If a creature card is put into that graveyard this way, sacrifice Helm of Obedience
// and put that card onto the battlefield under your control. // and put that card onto the battlefield under your control.
@ -125,9 +125,7 @@ class HelmOfObedienceEffect extends OneShotEffect {
break; break;
} }
} }
} } else{
}
else{
return false; return false;
} }
} }

View file

@ -94,32 +94,26 @@ class SatyrWayfinderEffect 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());
MageObject sourceObject = game.getObject(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null && sourceObject != null) { if (controller != null && sourceObject != null) {
Cards cards = new CardsImpl(Zone.LIBRARY); Cards cards = new CardsImpl(Zone.LIBRARY);
cards.addAll(player.getLibrary().getTopCards(game, 4)); cards.addAll(controller.getLibrary().getTopCards(game, 4));
boolean properCardFound = cards.count(filterPutInHand, source.getControllerId(), source.getSourceId(), game) > 0; boolean properCardFound = cards.count(filterPutInHand, source.getControllerId(), source.getSourceId(), game) > 0;
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
player.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand);
if (properCardFound && if (properCardFound &&
player.chooseUse(outcome, "Put a land card into your hand?", game) && controller.chooseUse(outcome, "Put a land card into your hand?", game) &&
player.choose(Outcome.DrawCard, cards, target, game)) { controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
} }
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (UUID cardId : cards) {
Card card = game.getCard(cardId);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
return true; return true;
} }

View file

@ -37,6 +37,8 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.SearchEffect; import mage.abilities.effects.SearchEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
@ -99,12 +101,7 @@ class InameDeathAspectEffect extends SearchEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null && player.searchLibrary(target, game)) { if (player != null && player.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
for (UUID cardId: target.getTargets()) { player.moveCards(new CardsImpl(target.getTargets()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
} }
player.shuffleLibrary(game); player.shuffleLibrary(game);
return true; return true;

View file

@ -27,12 +27,13 @@
*/ */
package mage.sets.commander; package mage.sets.commander;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect; import mage.abilities.effects.SearchEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
@ -87,19 +88,12 @@ class BuriedAliveEffect extends SearchEffect {
@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) { if (controller != null) {
if (player.searchLibrary(target, game)) { if (controller.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { controller.moveCards(new CardsImpl(target.getTargets()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (UUID cardId: target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
} controller.shuffleLibrary(game);
}
}
player.shuffleLibrary(game);
return true; return true;
} }
return false; return false;

View file

@ -84,11 +84,9 @@ public class SzadekLordOfSecrets extends CardImpl {
class SzadekLordOfSecretsEffect extends ReplacementEffectImpl { class SzadekLordOfSecretsEffect extends ReplacementEffectImpl {
List<Card> cards;
SzadekLordOfSecretsEffect() { SzadekLordOfSecretsEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit); super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "If {this} would deal combat damage to a player, instead put that many +1/+1 counters on Szadek and that player puts that many cards from the top of his or her library into his or her graveyard"; staticText = "If {this} would deal combat damage to a player, instead put that many +1/+1 counters on {this} and that player puts that many cards from the top of his or her library into his or her graveyard";
} }
SzadekLordOfSecretsEffect(final SzadekLordOfSecretsEffect effect) { SzadekLordOfSecretsEffect(final SzadekLordOfSecretsEffect effect) {
@ -101,24 +99,25 @@ class SzadekLordOfSecretsEffect extends ReplacementEffectImpl {
Player damagedPlayer = game.getPlayer(damageEvent.getTargetId()); Player damagedPlayer = game.getPlayer(damageEvent.getTargetId());
if (damageEvent.isCombatDamage()) { if (damageEvent.isCombatDamage()) {
Permanent p = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (p != null) { if (permanent != null) {
p.addCounters(CounterType.P1P1.createInstance(damageEvent.getAmount()), game); permanent.addCounters(CounterType.P1P1.createInstance(damageEvent.getAmount()), game);
if (damagedPlayer != null) { if (damagedPlayer != null) {
cards = damagedPlayer.getLibrary().getTopCards(game, damageEvent.getAmount()); damagedPlayer.moveCards(damagedPlayer.getLibrary().getTopCards(game, damageEvent.getAmount()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
}
for (Card card : cards) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
} }
} }
return true; return true;
} }
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
}
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER if (event.getSourceId().equals(source.getSourceId())) {
&& event.getSourceId().equals(source.getSourceId())) {
DamagePlayerEvent damageEvent = (DamagePlayerEvent) event; DamagePlayerEvent damageEvent = (DamagePlayerEvent) event;
if (damageEvent.isCombatDamage()) { if (damageEvent.isCombatDamage()) {
return true; return true;

View file

@ -86,34 +86,22 @@ class StrategicPlanningEffect 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) {
Cards cards = new CardsImpl(Zone.PICK);
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);
game.setZone(card.getId(), Zone.PICK);
}
}
if (controller != null) {
Cards cards = new CardsImpl();
cards.addAll(controller.getLibrary().getTopCards(game, 3));
if (cards.size() > 0) { if (cards.size() > 0) {
player.lookAtCards("Strategic Planning", cards, game); controller.lookAtCards("Strategic Planning", cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand"));
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand")); if (controller.choose(Outcome.Benefit, cards, target, game)) {
if (player.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
cards.remove(card); cards.remove(card);
} }
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (Card card : cards.getCards(game)) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
} }
return true; return true;
} }

View file

@ -99,12 +99,12 @@ class TeleminPerformanceEffect extends OneShotEffect {
} }
if (!creatureFound) { if (!creatureFound) {
cards.add(card); cards.add(card);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
} }
} }
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
opponent.revealCards("Telemin Performance", cards, game); opponent.revealCards("Telemin Performance", cards, game);
opponent.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
if (creature != null) { if (creature != null) {
return creature.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); return creature.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());

View file

@ -53,7 +53,6 @@ public class ChillOfForeboding extends CardImpl {
super(ownerId, 32, "Chill of Foreboding", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{U}"); super(ownerId, 32, "Chill of Foreboding", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{U}");
this.expansionSetCode = "DKA"; this.expansionSetCode = "DKA";
// Each player puts the top five cards of his or her library into his or her graveyard. // Each player puts the top five cards of his or her library into his or her graveyard.
this.getSpellAbility().addEffect(new ChillOfForebodingEffect()); this.getSpellAbility().addEffect(new ChillOfForebodingEffect());
// Flashback {7}{U} // Flashback {7}{U}
@ -92,13 +91,7 @@ class ChillOfForebodingEffect extends OneShotEffect {
for (UUID playerId : sourcePlayer.getInRange()) { for (UUID playerId : sourcePlayer.getInRange()) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
int count = Math.min(5, player.getLibrary().size()); player.moveCards(player.getLibrary().getTopCards(game, 5), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
} }
return true; return true;

View file

@ -49,7 +49,6 @@ import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.TargetSpell;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
/** /**
@ -108,9 +107,13 @@ class CurseOfEchoesCopyTriggeredAbility extends TriggeredAbilityImpl {
return new CurseOfEchoesCopyTriggeredAbility(this); return new CurseOfEchoesCopyTriggeredAbility(this);
} }
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) {
Permanent enchantment = game.getPermanent(sourceId); Permanent enchantment = game.getPermanent(sourceId);
@ -122,7 +125,6 @@ class CurseOfEchoesCopyTriggeredAbility extends TriggeredAbilityImpl {
} }
} }
} }
}
return false; return false;
} }

View file

@ -74,7 +74,7 @@ class IncreasingConfusionEffect extends OneShotEffect {
public IncreasingConfusionEffect() { public IncreasingConfusionEffect() {
super(Outcome.Detriment); super(Outcome.Detriment);
staticText = "Target player puts the top X cards of his or her library into his or her graveyard. If Increasing Confusion was cast from a graveyard, that player puts twice that many cards into his or her graveyard instead"; staticText = "Target player puts the top X cards of his or her library into his or her graveyard. If {this} was cast from a graveyard, that player puts twice that many cards into his or her graveyard instead";
} }
public IncreasingConfusionEffect(final IncreasingConfusionEffect effect) { public IncreasingConfusionEffect(final IncreasingConfusionEffect effect) {
@ -91,15 +91,7 @@ class IncreasingConfusionEffect extends OneShotEffect {
if (spell.getFromZone() == Zone.GRAVEYARD) { if (spell.getFromZone() == Zone.GRAVEYARD) {
amount *= 2; amount *= 2;
} }
Card card; player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < amount; i++) {
card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} else {
break;
}
}
return true; return true;
} }
} }

View file

@ -91,14 +91,14 @@ class TrackersInstinctsEffect 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) { if (controller != null) {
Cards cards = new CardsImpl(Zone.PICK); Cards cards = new CardsImpl(Zone.PICK);
boolean creaturesFound = false; boolean creaturesFound = false;
int count = Math.min(player.getLibrary().size(), 4); int count = Math.min(controller.getLibrary().size(), 4);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game); Card card = controller.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
cards.add(card); cards.add(card);
if (card.getCardType().contains(CardType.CREATURE)) { if (card.getCardType().contains(CardType.CREATURE)) {
@ -108,9 +108,9 @@ class TrackersInstinctsEffect extends OneShotEffect {
} }
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
player.revealCards("Tracker's Instincts", cards, game); controller.revealCards("Tracker's Instincts", cards, game);
TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to put in hand")); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to put in hand"));
if (creaturesFound && player.choose(Outcome.DrawCard, cards, target, game)) { if (creaturesFound && controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
@ -118,13 +118,7 @@ class TrackersInstinctsEffect extends OneShotEffect {
} }
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (UUID cardId : cards) {
Card card = game.getCard(cardId);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
return true; return true;
} }

View file

@ -34,6 +34,7 @@ import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -99,8 +100,8 @@ class MirkoVoskMindDrinkerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Card sourceCard = game.getCard(source.getSourceId()); MageObject sourceObject = source.getSourceObject(game);
if (player == null || sourceCard == null) { if (player == null || sourceObject == null) {
return false; return false;
} }
int landsToReveal = 4; int landsToReveal = 4;
@ -117,12 +118,8 @@ class MirkoVoskMindDrinkerEffect extends OneShotEffect {
} }
} }
} }
player.revealCards("by " + sourceCard.getName() + " from " + player.getName(), cards, game); player.revealCards("by " + sourceObject.getName() + " from " + player.getName(), cards, game);
for(Card card : cards.getCards(game)){ player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if(card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
return true; return true;
} }
} }

View file

@ -77,7 +77,7 @@ class SanityGrindingEffect extends OneShotEffect {
public SanityGrindingEffect() { public SanityGrindingEffect() {
super(Outcome.Neutral); super(Outcome.Neutral);
staticText = "<i>Chroma</i> - Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order"; staticText = "<i>Chroma</i> &mdash; Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order";
} }
public SanityGrindingEffect(final SanityGrindingEffect effect) { public SanityGrindingEffect(final SanityGrindingEffect effect) {
@ -87,24 +87,22 @@ class SanityGrindingEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player targetOpponent = game.getPlayer(source.getFirstTarget()); Player targetOpponent = game.getPlayer(source.getFirstTarget());
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Cards revealed = new CardsImpl(); Cards revealed = new CardsImpl();
int amount; int amount;
if (you == null) { if (controller == null) {
return false; return false;
} }
amount = (Math.min(10, you.getLibrary().size())); amount = (Math.min(10, controller.getLibrary().size()));
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
revealed.add(you.getLibrary().removeFromTop(game)); revealed.add(controller.getLibrary().removeFromTop(game));
} }
you.revealCards("Sanity Grinding", revealed, game); controller.revealCards("Sanity Grinding", revealed, game);
if (targetOpponent != null) { if (targetOpponent != null) {
amount = (Math.min(targetOpponent.getLibrary().size(), new ChromaSanityGrindingCount(revealed).calculate(game, source, this))); targetOpponent.moveCards(targetOpponent.getLibrary().getTopCards(game, new ChromaSanityGrindingCount(revealed).calculate(game, source, this)),
for (int i = 0; i < amount; i++) { Zone.LIBRARY, Zone.GRAVEYARD, source, game);
targetOpponent.getLibrary().removeFromTop(game).moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
} return controller.putCardsOnBottomOfLibrary(revealed, game, source, true);
return you.putCardsOnBottomOfLibrary(revealed, game, source, true);
} }
@Override @Override
@ -115,7 +113,7 @@ class SanityGrindingEffect extends OneShotEffect {
class ChromaSanityGrindingCount implements DynamicValue { class ChromaSanityGrindingCount implements DynamicValue {
private Cards revealed; private final Cards revealed;
public ChromaSanityGrindingCount(Cards revealed) { public ChromaSanityGrindingCount(Cards revealed) {
this.revealed = revealed; this.revealed = revealed;

View file

@ -114,8 +114,8 @@ class BalustradeSpyEffect extends OneShotEffect {
} }
} }
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
controller.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY);
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
return true; return true;
} }
return true; return true;

View file

@ -108,28 +108,24 @@ class BorborygmosEnragedEffect 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) { if (controller != null) {
Cards cards = new CardsImpl(Zone.PICK); Cards cards = new CardsImpl();
int count = Math.min(player.getLibrary().size(), 3); cards.addAll(controller.getLibrary().getTopCards(game, 3));
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
game.setZone(card.getId(), Zone.PICK);
if (card.getCardType().contains(CardType.LAND)) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
} else {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
}
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
player.revealCards("Borborygmous Enraged", cards, game); controller.revealCards("Borborygmous Enraged", cards, game);
return true; Cards landCards = new CardsImpl();
for(Card card: cards.getCards(game) ) {
if (card.getCardType().contains(CardType.LAND)) {
landCards.add(card);
cards.remove(card);
} }
} }
controller.moveCards(landCards, Zone.LIBRARY, Zone.HAND, source, game);
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
}
return true;
}
return false; return false;
} }
} }

View file

@ -36,6 +36,8 @@ import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
@ -88,16 +90,14 @@ class CoercedConfessionMillEffect extends OneShotEffect {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) { if (player != null) {
int foundCreatures = 0; int foundCreatures = 0;
int cardsCount = Math.min(4, player.getLibrary().size()); Cards cards = new CardsImpl();
for (int i = 0; i < cardsCount; i++) { for(Card card: player.getLibrary().getTopCards(game, 4)) {
Card card = player.getLibrary().removeFromTop(game); cards.add(card);
if (card != null) {
if (card.getCardType().contains(CardType.CREATURE)) { if (card.getCardType().contains(CardType.CREATURE)) {
++foundCreatures; ++foundCreatures;
} }
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
} }
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if (foundCreatures > 0) { if (foundCreatures > 0) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {

View file

@ -116,11 +116,7 @@ class ConsumingAberrationEffect extends OneShotEffect {
} }
} }
player.revealCards("Consuming Aberrtion", cards, game); player.revealCards("Consuming Aberrtion", cards, game);
for(Card card : cards.getCards(game)){ player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if(card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
} }
return true; return true;
} }

View file

@ -123,19 +123,14 @@ class DimirCharmEffect extends OneShotEffect {
} }
} }
if(cards.size() > 0){ if(cards.size() > 0){
TargetCard target = new TargetCard(Zone.PICK, 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); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
cards.remove(card); cards.remove(card);
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for(Card card2 : cards.getCards(game)){
if(card2 != null){
card2.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
} }
} }

View file

@ -117,11 +117,7 @@ class MindGrindEffect extends OneShotEffect {
} }
} }
player.revealCards("by " + sourceCard.getName() + " from " + player.getName(), cards, game); player.revealCards("by " + sourceCard.getName() + " from " + player.getName(), cards, game);
for(Card card : cards.getCards(game)){ player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if(card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
} }
return true; return true;
} }

View file

@ -117,11 +117,7 @@ class UndercityInformerEffect extends OneShotEffect {
} }
} }
player.revealCards("Undercity Informer", cards, game); player.revealCards("Undercity Informer", cards, game);
for(Card card : cards.getCards(game)){ player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if(card != null){
card.moveToZone(Zone.GRAVEYARD, id, game, true);
}
}
return true; return true;
} }
} }

View file

@ -70,36 +70,3 @@ public class ArmoredSkaab extends CardImpl {
return new ArmoredSkaab(this); return new ArmoredSkaab(this);
} }
} }
class ArmoredSkaabEffect extends OneShotEffect {
public ArmoredSkaabEffect() {
super(Outcome.Discard);
this.staticText = "put the top four cards of your library into your graveyard";
}
public ArmoredSkaabEffect(final ArmoredSkaabEffect effect) {
super(effect);
}
@Override
public ArmoredSkaabEffect copy() {
return new ArmoredSkaabEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
int cardsCount = Math.min(4, player.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
return true;
}
return false;
}
}

View file

@ -93,7 +93,7 @@ class CellarDoorEffect extends OneShotEffect {
if (player != null && player.getLibrary().size() > 0) { if (player != null && player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromBottom(game); Card card = player.getLibrary().removeFromBottom(game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if (card.getCardType().contains(CardType.CREATURE)) { if (card.getCardType().contains(CardType.CREATURE)) {
ZombieToken token = new ZombieToken("ISD"); ZombieToken token = new ZombieToken("ISD");
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());

View file

@ -89,7 +89,7 @@ class GhoulcallersBellEffect extends OneShotEffect {
if (player.getLibrary().size() > 0) { if (player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
} }
} }

View file

@ -27,6 +27,7 @@
*/ */
package mage.sets.innistrad; package mage.sets.innistrad;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -74,7 +75,7 @@ class HereticsPunishmentEffect extends OneShotEffect {
public HereticsPunishmentEffect() { public HereticsPunishmentEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "Choose target creature or player, then put the top three cards of your library into your graveyard. Heretic's Punishment deals damage to that creature or player equal to the highest converted mana cost among those cards"; staticText = "Choose target creature or player, then put the top three cards of your library into your graveyard. {this} deals damage to that creature or player equal to the highest converted mana cost among those cards";
} }
public HereticsPunishmentEffect(final HereticsPunishmentEffect effect) { public HereticsPunishmentEffect(final HereticsPunishmentEffect effect) {
@ -83,18 +84,17 @@ class HereticsPunishmentEffect 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) { if (controller != null) {
int maxCost = 0; int maxCost = 0;
for (int i = 0; i < Math.min(3, player.getLibrary().size()); i++) { List<Card> cardList = controller.getLibrary().getTopCards(game, 3);
Card card = player.getLibrary().removeFromTop(game); for (Card card: cardList) {
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
int test = card.getManaCost().convertedManaCost(); int test = card.getManaCost().convertedManaCost();
if (test > maxCost) if (test > maxCost) {
maxCost = test; maxCost = test;
} }
} }
controller.moveCards(cardList, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) { if (permanent != null) {
permanent.damage(maxCost, source.getSourceId(), game, false, true); permanent.damage(maxCost, source.getSourceId(), game, false, true);

View file

@ -92,17 +92,20 @@ class MindshriekerEffect 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 targetPlayer = game.getPlayer(source.getFirstTarget());
if (player != null && player.getLibrary().size() > 0) { if (targetPlayer != null) {
Card card = player.getLibrary().removeFromTop(game); if (targetPlayer.getLibrary().size() > 0) {
Card card = targetPlayer.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); targetPlayer.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
int amount = card.getManaCost().convertedManaCost(); int amount = card.getManaCost().convertedManaCost();
if (amount > 0) if (amount > 0) {
game.addEffect(new BoostSourceEffect(amount, amount, Duration.EndOfTurn), source); game.addEffect(new BoostSourceEffect(amount, amount, Duration.EndOfTurn), source);
return true;
} }
} }
}
return true;
}
return false; return false;
} }

View file

@ -98,8 +98,9 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
while (true) { while (true) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card == null) if (card == null) {
break; break;
}
if (card.getName().equals("Mirror-Mad Phantasm")) { if (card.getName().equals("Mirror-Mad Phantasm")) {
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
break; break;
@ -107,9 +108,7 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
cards.add(card); cards.add(card);
} }
player.revealCards("Mirror-Mad Phantasm", cards, game); player.revealCards("Mirror-Mad Phantasm", cards, game);
for (Card card: cards.getCards(game)) { player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
return true; return true;
} }
} }

View file

@ -119,7 +119,7 @@ class VoidEffect extends OneShotEffect {
targetPlayer.revealCards("Void", targetPlayer.getHand(), game); targetPlayer.revealCards("Void", targetPlayer.getHand(), game);
for (Card card : targetPlayer.getHand().getCards(game)) { for (Card card : targetPlayer.getHand().getCards(game)) {
if (filterCard.match(card, game)) { if (filterCard.match(card, game)) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); targetPlayer.discard(card, source, game);
} }
} }
} else { } else {

View file

@ -105,17 +105,9 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
} }
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl(target.getTargets());
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
cards.add(card);
}
}
if (cards.size() > 0) {
player.revealCards("Quiet Speculation", cards, game); player.revealCards("Quiet Speculation", cards, game);
} player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
player.shuffleLibrary(game); player.shuffleLibrary(game);
return true; return true;

View file

@ -30,7 +30,6 @@ package mage.sets.khansoftarkir;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.ZoneChangeTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect; import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
import mage.cards.Card; import mage.cards.Card;
@ -41,9 +40,8 @@ import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; 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.ZoneChangeGroupEvent;
import mage.game.permanent.token.ZombieToken; import mage.game.permanent.token.ZombieToken;
import mage.game.stack.StackObject;
/** /**
* *
@ -102,56 +100,36 @@ class SidisiBroodTyrantAbility extends TriggeredAbilityImpl {
if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) { if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) {
return true; return true;
} }
if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId());
return true;
}
return false;
} }
@Override @Override
public String getRule() { public String getRule() {
return "Whenever {this} enters the battlefield or attacks, put the top three cards of your library into your graveyard."; return "Whenever {this} enters the battlefield or attacks, put the top three cards of your library into your graveyard.";
} }
} }
class SidisiBroodTyrantTriggeredAbility extends ZoneChangeTriggeredAbility { class SidisiBroodTyrantTriggeredAbility extends TriggeredAbilityImpl {
UUID lastStackObjectId = null;
public SidisiBroodTyrantTriggeredAbility() { public SidisiBroodTyrantTriggeredAbility() {
super(Zone.BATTLEFIELD, Zone.LIBRARY, Zone.GRAVEYARD, new CreateTokenEffect(new ZombieToken("KTK")), "", false); super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken("KTK")), false);
} }
public SidisiBroodTyrantTriggeredAbility(final SidisiBroodTyrantTriggeredAbility ability) { public SidisiBroodTyrantTriggeredAbility(final SidisiBroodTyrantTriggeredAbility ability) {
super(ability); super(ability);
this.lastStackObjectId = ability.lastStackObjectId;
} }
@Override @Override
public boolean checkEventType(GameEvent event, Game game) { public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE; return event.getType() == GameEvent.EventType.ZONE_CHANGE_GROUP;
} }
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent)event; ZoneChangeGroupEvent zEvent = (ZoneChangeGroupEvent)event;
if ((fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone)) { if (Zone.LIBRARY == zEvent.getFromZone() && Zone.GRAVEYARD == zEvent.getToZone()) {
Card card = game.getCard(event.getTargetId()); for (Card card: zEvent.getCards()) {
if (card != null && card.getOwnerId().equals(getControllerId()) && card.getCardType().contains(CardType.CREATURE)) { if (card.getOwnerId().equals(getControllerId()) && card.getCardType().contains(CardType.CREATURE)) {
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
if (stackObject == null) {
stackObject = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK);
}
// If multiple cards go to graveyard from replacement effect (e.g. Dredge) each card is wrongly handled as a new event
if (stackObject != null) {
if (stackObject.getId().equals(lastStackObjectId)) {
return false; // was already handled
}
lastStackObjectId = stackObject.getId();
return true;
} else {
// special action or replacement effect, so we can't check yet if multiple cards are moved with one effect
return true; return true;
} }
} }

View file

@ -104,7 +104,7 @@ class SultaiSoothsayerEffect extends OneShotEffect {
if (controller.choose(Outcome.Benefit, cards, target, game)) { if (controller.choose(Outcome.Benefit, 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.LIBRARY, Zone.GRAVEYARD, source, game); controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
cards.remove(card); cards.remove(card);
} }
} }

View file

@ -180,17 +180,12 @@ class WarpWorldEffect extends OneShotEffect {
player = playerList.getNext(game); player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId())); } while (!player.getId().equals(game.getActivePlayerId()));
// put the rest of the cards into the graveyard // put the rest of the cards on buttom of the library
playerList.setCurrent(game.getActivePlayerId()); playerList.setCurrent(game.getActivePlayerId());
player = game.getPlayer(game.getActivePlayerId()); player = game.getPlayer(game.getActivePlayerId());
do { do {
CardsImpl cards = cardsRevealed.get(player.getId()); CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) { player.putCardsOnBottomOfLibrary(cards, game, source, false);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
player = playerList.getNext(game); player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId())); } while (!player.getId().equals(game.getActivePlayerId()));

View file

@ -86,13 +86,13 @@ class GlimpseTheFutureEffect 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) { if (controller != null) {
Cards cards = new CardsImpl(Zone.PICK); Cards cards = new CardsImpl(Zone.PICK);
int cardsCount = Math.min(3, player.getLibrary().size()); int cardsCount = Math.min(3, controller.getLibrary().size());
for (int i = 0; i < cardsCount; i++) { for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game); Card card = controller.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
cards.add(card); cards.add(card);
game.setZone(card.getId(), Zone.PICK); game.setZone(card.getId(), Zone.PICK);
@ -100,20 +100,17 @@ class GlimpseTheFutureEffect extends OneShotEffect {
} }
if (cards.size() > 0) { if (cards.size() > 0) {
player.lookAtCards("Glimpse the Future", cards, game); controller.lookAtCards("Glimpse the Future", cards, game);
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
if (player.choose(Outcome.Benefit, cards, target, game)) { if (controller.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
cards.remove(card); cards.remove(card);
} }
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (Card card : cards.getCards(game)) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
} }
return true; return true;
} }

View file

@ -27,6 +27,7 @@
*/ */
package mage.sets.magic2014; package mage.sets.magic2014;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -102,35 +103,32 @@ class JaceMindseekerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Cards cards = new CardsImpl(); Cards cardsToCast = new CardsImpl();
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) { if (targetOpponent != null) {
// putting cards to grave shouldn't end the game, so getting minimun available List<Card> allCards = targetOpponent.getLibrary().getTopCards(game, 5);
int cardsCount = Math.min(5, player.getLibrary().size()); targetOpponent.moveCards(allCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < cardsCount; i++) { for(Card card : allCards) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
if (filter.match(card, game)) { if (filter.match(card, game)) {
cards.add(card); Zone zone = game.getState().getZone(card.getId());
// If the five cards are put into a public zone such as exile instead of a graveyard (perhaps due to the ability of Rest in Peace),
// you can cast one of those instant or sorcery cards from that zone.
if (zone.equals(Zone.GRAVEYARD) || zone.equals(Zone.EXILED)) {
cardsToCast.add(card);
} }
} }
else {
throw new IllegalArgumentException("couldn't get card from library");
}
} }
} }
// cast an instant or sorcery for free // cast an instant or sorcery for free
// TODO: Check if card can also be cast if it doesn't end in the graveyard due to other active effects (LevelX2 08.07.2013). if (cardsToCast.size() > 0) {
if (cards.size() > 0) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
TargetCard target = new TargetCard(Zone.PICK, filter); TargetCard target = new TargetCard(Zone.GRAVEYARD, filter); // zone should be ignored here
target.setNotTarget(true); target.setNotTarget(true);
if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", game) if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", game)
&& controller.choose(outcome, cards, target, game)) { && controller.choose(outcome, cardsToCast, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
controller.cast(card.getSpellAbility(), game, true); controller.cast(card.getSpellAbility(), game, true);
} }

View file

@ -103,23 +103,20 @@ class CountrysideCrusherEffect 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 = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (permanent == null) { if (controller != null && sourcePermanent != null) {
permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (player != null && permanent != null) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
while (player.getLibrary().size() > 0) { while (controller.getLibrary().size() > 0) {
Card card = player.getLibrary().getFromTop(game); Card card = controller.getLibrary().getFromTop(game);
cards.add(card); cards.add(card);
if (card.getCardType().contains(CardType.LAND)) { if (card.getCardType().contains(CardType.LAND)) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} else { } else {
break; break;
} }
} }
player.revealCards(permanent.getName(), cards, game); controller.revealCards(sourcePermanent.getName(), cards, game);
return true; return true;
} }
return false; return false;

View file

@ -127,8 +127,7 @@ class NogginWhackEffect extends OneShotEffect {
for (UUID cardId : (List<UUID>) targetInHand.getTargets()) { for (UUID cardId : (List<UUID>) targetInHand.getTargets()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); controller.discard(card, source, game);
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": Discarded card ").append(card.getName()).toString());
} }
} }
} }

View file

@ -40,7 +40,6 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PlayTargetWithoutPayingManaEffect; import mage.abilities.effects.common.PlayTargetWithoutPayingManaEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -107,10 +106,7 @@ class ChancellorOfTheSpiresDelayedTriggeredAbility extends DelayedTriggeredAbili
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE) { return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE;
return true;
}
return false;
} }
@Override @Override
public ChancellorOfTheSpiresDelayedTriggeredAbility copy() { public ChancellorOfTheSpiresDelayedTriggeredAbility copy() {
@ -132,16 +128,9 @@ class ChancellorOfTheSpiresEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) { for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(opponentId); Player opponent = game.getPlayer(opponentId);
if (player != null) { if (opponent != null) {
int cardsCount = Math.min(7, player.getLibrary().size()); opponent.moveCards(opponent.getLibrary().getTopCards(game, 7), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null)
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
else
break;
}
} }
} }
return true; return true;

View file

@ -37,12 +37,12 @@ import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -82,13 +82,17 @@ class MindcrankTriggeredAbility extends TriggeredAbilityImpl {
return new MindcrankTriggeredAbility(this); return new MindcrankTriggeredAbility(this);
} }
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.LOST_LIFE;
}
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Set<UUID> opponents = game.getOpponents(this.getControllerId()); Set<UUID> opponents = game.getOpponents(this.getControllerId());
if (event.getType() == EventType.LOST_LIFE && opponents.contains(event.getPlayerId())) { if (opponents.contains(event.getPlayerId())) {
Effect effect = this.getEffects().get(0); Effect effect = this.getEffects().get(0);
effect.setValue("targetPlayer", event.getPlayerId()); effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
effect.setValue("amount", event.getAmount());
return true; return true;
} }
return false; return false;
@ -117,21 +121,13 @@ class MindcrankEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
UUID targetId = (UUID) getValue("targetPlayer"); Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
Player player = game.getPlayer(targetId); if (targetPlayer != null) {
if (player != null) {
Integer amount = (Integer) getValue("amount"); Integer amount = (Integer) getValue("amount");
if (amount == null) { if (amount == null) {
amount = 0; amount = 0;
} }
// putting cards to grave shouldn't end the game, so getting minimum available targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
amount = Math.min(amount, player.getLibrary().size());
for (int i = 0; i < amount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
} }
return true; return true;
} }

View file

@ -89,16 +89,16 @@ class ThinkTankLookLibraryEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (you != null) { if (controller != null) {
if (you.getLibrary().size() > 0) { if (controller.getLibrary().size() > 0) {
Card card = you.getLibrary().getFromTop(game); Card card = controller.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
CardsImpl cards = new CardsImpl(); CardsImpl cards = new CardsImpl();
cards.add(card); cards.add(card);
you.lookAtCards("Think Tank", cards, game); controller.lookAtCards("Think Tank", cards, game);
if (you.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) { if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
return card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
} }

View file

@ -69,7 +69,7 @@ public class InfernalGenesis extends CardImpl {
class InfernalGenesisEffect extends OneShotEffect { class InfernalGenesisEffect extends OneShotEffect {
InfernalGenesisEffect() { InfernalGenesisEffect() {
super(Outcome.BoostCreature); super(Outcome.PutCreatureInPlay);
staticText = "that player puts the top card of his or her library into his or her graveyard. Then he or she puts X 1/1 black Minion creature tokens onto the battlefield, where X is that card's converted mana cost"; staticText = "that player puts the top card of his or her library into his or her graveyard. Then he or she puts X 1/1 black Minion creature tokens onto the battlefield, where X is that card's converted mana cost";
} }
@ -79,14 +79,14 @@ class InfernalGenesisEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) { if (player != null) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
if (card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false)) { if (player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game)) {
int cmc = card.getManaCost().convertedManaCost(); int cmc = card.getManaCost().convertedManaCost();
MinionToken token = new MinionToken(); MinionToken token = new MinionToken();
token.putOntoBattlefield(cmc, game, id, player.getId()); token.putOntoBattlefield(cmc, game, source.getSourceId(), player.getId());
} }
} }
} }

View file

@ -114,7 +114,7 @@ class DestroyTheEvidenceEffect extends OneShotEffect {
} }
} }
player.revealCards(sourceObject.getName(), cards, game, true); player.revealCards(sourceObject.getName(), cards, game, true);
player.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY); player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
return true; return true;
} }
return false; return false;

View file

@ -125,7 +125,7 @@ class EpicExperimentEffect extends OneShotEffect {
// move cards not cast to graveyard // move cards not cast to graveyard
ExileZone exile = game.getExile().getExileZone(source.getSourceId()); ExileZone exile = game.getExile().getExileZone(source.getSourceId());
if (exile != null) { if (exile != null) {
controller.moveCardsToGraveyardWithInfo(exile, source, game, Zone.EXILED); controller.moveCards(exile, Zone.EXILED, Zone.GRAVEYARD, source, game);
} }
return true; return true;
} }

View file

@ -59,7 +59,6 @@ public class GuildFeud extends CardImpl {
super(ownerId, 97, "Guild Feud", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}"); super(ownerId, 97, "Guild Feud", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}");
this.expansionSetCode = "RTR"; this.expansionSetCode = "RTR";
// At the beginning of your upkeep, target opponent reveals the top three cards // At the beginning of your upkeep, target opponent reveals the top three cards
// of his or her library, may put a creature card from among them onto the battlefield, // of his or her library, may put a creature card from among them onto the battlefield,
// then puts the rest into his or her graveyard. You do the same with the top three // then puts the rest into his or her graveyard. You do the same with the top three
@ -101,27 +100,20 @@ class GuildFeudEffect extends OneShotEffect {
if (opponent != null && controller != null) { if (opponent != null && controller != null) {
for (int activePlayer = 0; activePlayer < 2; activePlayer++) { for (int activePlayer = 0; activePlayer < 2; activePlayer++) {
Player player = (activePlayer == 0? opponent : controller); Player player = (activePlayer == 0? opponent : controller);
Cards topThreeCards = new CardsImpl(Zone.PICK); Cards topThreeCards = new CardsImpl();
for (int i = 0; i < 3; i++) { topThreeCards.addAll(player.getLibrary().getTopCards(game, 3));
if (player.getLibrary().size() > 0) { player.revealCards(player.getName() + " top three library cards", topThreeCards, game);
Card topCard = player.getLibrary().removeFromTop(game);
if (topCard != null) {
topThreeCards.add(topCard);
}
}
}
player.revealCards(player.getLogName() + " top three library cards", topThreeCards, game);
Card creatureToBattlefield; Card creatureToBattlefield;
if (!topThreeCards.isEmpty()) { if (!topThreeCards.isEmpty()) {
if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", game)) { if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", game)) {
TargetCard target = new TargetCard(Zone.PICK, TargetCard target = new TargetCard(Zone.LIBRARY,
new FilterCreatureCard( new FilterCreatureCard(
"creature card to put on the battlefield")); "creature card to put on the battlefield"));
if (player.choose(Outcome.PutCreatureInPlay, topThreeCards, target, game)) { if (player.choose(Outcome.PutCreatureInPlay, topThreeCards, target, game)) {
creatureToBattlefield = topThreeCards.get(target.getFirstTarget(), game); creatureToBattlefield = topThreeCards.get(target.getFirstTarget(), game);
if (creatureToBattlefield != null) { if (creatureToBattlefield != null) {
topThreeCards.remove(creatureToBattlefield); topThreeCards.remove(creatureToBattlefield);
if (creatureToBattlefield.putOntoBattlefield(game, Zone.PICK, if (creatureToBattlefield.putOntoBattlefield(game, Zone.LIBRARY,
source.getSourceId(), player.getId())) { source.getSourceId(), player.getId())) {
game.informPlayers("Guild Feud: " + player.getLogName() + " put " + creatureToBattlefield.getName() + " to the battlefield"); game.informPlayers("Guild Feud: " + player.getLogName() + " put " + creatureToBattlefield.getName() + " to the battlefield");
if (activePlayer == 0) { if (activePlayer == 0) {
@ -133,23 +125,14 @@ class GuildFeudEffect extends OneShotEffect {
} }
} }
} }
player.moveCards(topThreeCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if (topThreeCards.size() > 0) {
while (topThreeCards.size() > 0) {
Card card = topThreeCards.get(topThreeCards.iterator().next(), game);
topThreeCards.remove(card);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
} }
// If two creatures are put onto the battlefield this way, those creatures fight each other // If two creatures are put onto the battlefield this way, those creatures fight each other
if (opponentCreature != null && controllerCreature != null) { if (opponentCreature != null && controllerCreature != null) {
int power = opponentCreature.getPower().getValue(); opponentCreature.fight(controllerCreature, source, game);
opponentCreature.damage(controllerCreature.getPower().getValue(), source.getSourceId(), game, false, true);
controllerCreature.damage(power, source.getSourceId(), game, false, true);
} }
return true;
} }
return false; return false;
} }

View file

@ -57,7 +57,6 @@ public class JaradsOrders extends CardImpl {
super(ownerId, 175, "Jarad's Orders", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{G}"); super(ownerId, 175, "Jarad's Orders", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{G}");
this.expansionSetCode = "RTR"; this.expansionSetCode = "RTR";
// Search your library for up to two creature cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library. // Search your library for up to two creature cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library.
this.getSpellAbility().addEffect(new JaradsOrdersEffect()); this.getSpellAbility().addEffect(new JaradsOrdersEffect());
} }
@ -91,36 +90,35 @@ class JaradsOrdersEffect 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) { if (controller != null) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterCreatureCard("creature cards")); TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterCreatureCard("creature cards"));
if (player.searchLibrary(target, game)) { if (controller.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
Cards revealed = new CardsImpl(); Cards revealed = new CardsImpl();
for (UUID cardId: (List<UUID>)target.getTargets()) { for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().getCard(cardId, game); Card card = controller.getLibrary().getCard(cardId, game);
revealed.add(card); revealed.add(card);
} }
player.revealCards("Jarad's Orders", revealed, game); controller.revealCards("Jarad's Orders", revealed, game);
if (target.getTargets().size() == 2) { if (target.getTargets().size() == 2) {
TargetCard target2 = new TargetCard(Zone.PICK, filter); TargetCard target2 = new TargetCard(Zone.PICK, filter);
player.choose(Outcome.Benefit, revealed, target2, game); controller.choose(Outcome.Benefit, revealed, target2, game);
Card card = revealed.get(target2.getFirstTarget(), game); Card card = revealed.get(target2.getFirstTarget(), game);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
revealed.remove(card); revealed.remove(card);
card = revealed.getCards(game).iterator().next(); card = revealed.getCards(game).iterator().next();
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} } else if (target.getTargets().size() == 1) {
else if (target.getTargets().size() == 1) {
Card card = revealed.getCards(game).iterator().next(); Card card = revealed.getCards(game).iterator().next();
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
} }
} }
player.shuffleLibrary(game); controller.shuffleLibrary(game);
return true; return true;
} }
player.shuffleLibrary(game); controller.shuffleLibrary(game);
} }
return false; return false;

View file

@ -90,14 +90,7 @@ class PsychicSpiralEffect extends OneShotEffect {
if (cardsInGraveyard > 0) { if (cardsInGraveyard > 0) {
Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) { if (targetPlayer != null) {
for (int i = 0; i<cardsInGraveyard ; i++) { targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, cardsInGraveyard), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if (targetPlayer.getLibrary().size() > 0) {
Card card = targetPlayer.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
}
} }
} }
return true; return true;

View file

@ -91,20 +91,9 @@ class KeeningStoneEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());
if (player != null) { if (player != null) {
Library library = player.getLibrary(); player.moveCards(player.getLibrary().getTopCards(game, player.getGraveyard().size()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
int amount = Math.min(player.getGraveyard().size(), library.size());
for (int i = 0; i < amount; i++) {
Card card = library.removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
if (amount > 0) {
return true; return true;
} }
}
return false; return false;
} }
} }

View file

@ -93,19 +93,18 @@ class ChoiceOfDamnationsEffect extends OneShotEffect {
int amount = targetPlayer.getAmount(0, Integer.MAX_VALUE, "Chooses a number", game); int amount = targetPlayer.getAmount(0, Integer.MAX_VALUE, "Chooses a number", game);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
String sb = String.valueOf("Shall " + targetPlayer.getLogName() + " lose ") + Integer.toString(amount) + " life?"; if (controller.chooseUse(outcome, "Shall " + targetPlayer.getLogName() + " lose " + amount + " life?", game)) {
if (controller.chooseUse(outcome, sb, game)) {
targetPlayer.loseLife(amount, game); targetPlayer.loseLife(amount, game);
} else { } else {
int numberPermanents = game.getState().getBattlefield().countAll(new FilterPermanent(), targetPlayer.getId(), game); int numberPermanents = game.getState().getBattlefield().countAll(new FilterPermanent(), targetPlayer.getId(), game);
if (numberPermanents > amount) { if (numberPermanents > amount) {
int numberToSacrifice = numberPermanents - amount; int numberToSacrifice = numberPermanents - amount;
Target target = new TargetControlledPermanent(numberToSacrifice, numberToSacrifice, new FilterControlledPermanent(), false); Target target = new TargetControlledPermanent(numberToSacrifice, numberToSacrifice, new FilterControlledPermanent("permanent you control to sacrifice"), false);
targetPlayer.chooseTarget(Outcome.Sacrifice, target, source, game); targetPlayer.chooseTarget(Outcome.Sacrifice, target, source, game);
for (UUID uuid : target.getTargets()) { for (UUID uuid : target.getTargets()) {
Permanent permanent = game.getPermanent(uuid); Permanent permanent = game.getPermanent(uuid);
if (permanent != null) { if (permanent != null) {
permanent.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); permanent.sacrifice(source.getSourceId(), game);
} }
} }
} }

View file

@ -33,7 +33,6 @@ import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -107,19 +106,8 @@ class CloudhoofKirinEffect extends OneShotEffect {
} }
} }
if (targetPlayer != null) { if (targetPlayer != null) {
int cardsCount = Math.min(spell.getConvertedManaCost(), targetPlayer.getLibrary().size()); return targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, spell.getConvertedManaCost()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < cardsCount; i++) {
Card card = targetPlayer.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
else {
break;
}
}
return true;
}
} }
return false; return false;
} }

View file

@ -47,7 +47,6 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.common.TargetCardInOpponentsGraveyard; import mage.target.common.TargetCardInOpponentsGraveyard;
@ -114,34 +113,15 @@ class GethLordOfTheVaultEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getFirstTarget()); Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) { if (card != null) {
// if still in graveyard card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId(), true);
if (game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) {
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());
if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId())) { if (player != null) {
player.moveCards(player.getLibrary().getTopCards(game, card.getManaCost().convertedManaCost()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
permanent.setTapped(true);
}
int xvalue = card.getManaCost().convertedManaCost();
int cardsCount = Math.min(xvalue, player.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card removedCard = player.getLibrary().getFromTop(game);
if (removedCard != null) {
removedCard.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} else {
break;
} }
} }
return true;
}
}
}
return false;
} }
@Override @Override

View file

@ -38,7 +38,6 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
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.constants.Outcome; import mage.constants.Outcome;
import mage.counters.CounterType; import mage.counters.CounterType;
@ -85,18 +84,13 @@ class GrindclockEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
int amount = game.getPermanent(source.getSourceId()).getCounters().getCount(CounterType.CHARGE); int amount = game.getPermanent(source.getSourceId()).getCounters().getCount(CounterType.CHARGE);
Player player = game.getPlayer(source.getFirstTarget()); Player targetPlayer = game.getPlayer(source.getFirstTarget());
Card card; if (targetPlayer != null) {
for (int i = 0; i < amount; i++) { targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} else {
break;
}
}
return true; return true;
} }
return false;
}
@Override @Override
public GrindclockEffect copy() { public GrindclockEffect copy() {

View file

@ -53,6 +53,7 @@ import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
import mage.players.Player;
/** /**
* @author nantuko * @author nantuko
@ -128,7 +129,7 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard"; return "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with {this} to its owner's graveyard";
} }
} }
@ -146,14 +147,14 @@ class MimicVatEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) { Player controller = game.getPlayer(source.getControllerId());
if (controller == null || permanent == null) {
return false; return false;
} }
// return older cards to graveyard // return older cards to graveyard
for (UUID imprinted : permanent.getImprinted()) { for (UUID imprinted : permanent.getImprinted()) {
Card card = game.getCard(imprinted); Card card = game.getCard(imprinted);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); controller.moveCards(card, Zone.EXILED, Zone.GRAVEYARD, source, game);
} }
permanent.clearImprinted(game); permanent.clearImprinted(game);

View file

@ -113,10 +113,7 @@ class AncestralMemoriesEffect extends OneShotEffect {
} }
} }
} }
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (Card card : cards.getCards(game)) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
} }
return true; return true;
} }

View file

@ -98,24 +98,19 @@ class SearchLibraryPutInGraveyard extends SearchEffect {
@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) { if (controller != null) {
return false; if (controller.searchLibrary(target, game)) {
}
if (player.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
Cards cards = new CardsImpl(); Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
} }
} }
player.shuffleLibrary(game); controller.shuffleLibrary(game);
return true; return true;
} }
player.shuffleLibrary(game);
return false; return false;
} }

View file

@ -93,6 +93,8 @@ class AltarOfDementiaEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
int amount = 0; int amount = 0;
for (Cost cost: source.getCosts()) { for (Cost cost: source.getCosts()) {
if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost)cost).getPermanents().size() > 0) { if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost)cost).getPermanents().size() > 0) {
@ -101,19 +103,10 @@ class AltarOfDementiaEffect extends OneShotEffect {
} }
} }
if (amount > 0) { if (amount > 0) {
Player player = game.getPlayer(source.getFirstTarget()); player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
if (player != null) {
for (int i = 0; i<amount ; i++) {
if (player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
}
}
} }
return true; return true;
} }
}
return false; return false;
} }

View file

@ -94,43 +94,42 @@ class IntuitionEffect extends SearchEffect {
@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());
Player opponent = game.getPlayer(source.getFirstTarget()); Player opponent = game.getPlayer(source.getFirstTarget());
if (player == null || opponent == null) if (controller == null || opponent == null)
return false; return false;
if (player.getLibrary().size() >= 3 && player.searchLibrary(target, game)) { if (controller.getLibrary().size() >= 3 && controller.searchLibrary(target, game)) {
if (target.getTargets().size() == 3) { if (target.getTargets().size() == 3) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
for (UUID cardId: (List<UUID>)target.getTargets()) { for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().getCard(cardId, game); Card card = controller.getLibrary().getCard(cardId, game);
if (card != null) { if (card != null) {
cards.add(card); cards.add(card);
} }
} }
player.revealCards("Reveal", cards, game); controller.revealCards("Reveal", cards, game);
TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard()); TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard());
while(!opponent.choose(Outcome.Neutral, cards, targetCard, game)); while(!opponent.choose(Outcome.Neutral, cards, targetCard, game)) {
if (!opponent.isInGame()) {
return false;
}
}
Card card = cards.get(targetCard.getFirstTarget(), game); Card card = cards.get(targetCard.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
} }
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for(UUID uuid : cards){
card = cards.get(uuid, game);
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
controller.shuffleLibrary(game);
}
player.shuffleLibrary(game);
return true; return true;
} }
player.shuffleLibrary(game); controller.shuffleLibrary(game);
return false; return false;
} }

View file

@ -114,16 +114,17 @@ class WoodSageEffect extends OneShotEffect {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
cards.addAll(controller.getLibrary().getTopCards(game, 4)); cards.addAll(controller.getLibrary().getTopCards(game, 4));
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
Cards cardsToHand = new CardsImpl();
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
for (Card card: cards.getCards(game)) { for (Card card: cards.getCards(game)) {
if (card.getName().equals(cardName)) { if (card.getName().equals(cardName)) {
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true); cardsToHand.add(card);
cards.remove(card); cards.remove(card);
} }
} }
controller.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY); controller.moveCards(cardsToHand, Zone.LIBRARY, Zone.HAND, source, game);
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
return true; return true;
} }

View file

@ -80,8 +80,7 @@ class TraumatizeEffect extends OneShotEffect {
Player player = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getFirstTarget());
if (player != null) { if (player != null) {
int amount = player.getLibrary().size() / 2; int amount = player.getLibrary().size() / 2;
player.moveCardsToGraveyardWithInfo(player.getLibrary().getTopCards(game, amount), source, game, Zone.LIBRARY); return player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
return true;
} }
return false; return false;
} }

View file

@ -83,16 +83,7 @@ class WhetstoneEffect extends OneShotEffect {
for (UUID playerId : game.getPlayerList()) { for (UUID playerId : game.getPlayerList()) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
// putting cards to grave shouldn't end the game, so getting minimun available player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
int cardsCount = Math.min(2, player.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} else {
break;
}
}
} }
} }
return true; return true;

View file

@ -33,7 +33,11 @@ public class CursesTest extends CardTestPlayerBase {
public void testCurseOfEchoes() { public void testCurseOfEchoes() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.BATTLEFIELD, playerB, "Island", 5); addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
// Enchant player
// Whenever enchanted player casts an instant or sorcery spell, each other player may copy that
// spell and may choose new targets for the copy he or she controls.
addCard(Zone.HAND, playerA, "Curse of Echoes"); addCard(Zone.HAND, playerA, "Curse of Echoes");
// Draw three cards.
addCard(Zone.HAND, playerB, "Jace's Ingenuity"); addCard(Zone.HAND, playerB, "Jace's Ingenuity");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Echoes", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Echoes", playerB);
@ -49,6 +53,8 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void testCurseOfExhaustion1() { public void testCurseOfExhaustion1() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
// Enchant player
// Enchanted player can't cast more than one spell each turn.
addCard(Zone.HAND, playerA, "Curse of Exhaustion"); addCard(Zone.HAND, playerA, "Curse of Exhaustion");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
addCard(Zone.HAND, playerB, "Lightning Bolt", 2); addCard(Zone.HAND, playerB, "Lightning Bolt", 2);

View file

@ -45,6 +45,37 @@ public class DredgeTest extends CardTestPlayerBase {
*/ */
@Test
public void testSultaiSoothsayerWithSidisiBroodTyrant() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
// Whenever Sidisi, Brood Tyrant enters the battlefield or attacks, put the top three cards of your library into your graveyard.
// Whenever one or more creature cards are put into your graveyard from your library, put a 2/2 black Zombie creature token onto the battlefield.
addCard(Zone.BATTLEFIELD, playerA, "Sidisi, Brood Tyrant");
// When Sultai Soothsayer enters the battlefield, look at the top four cards of your library.
// Put one of them into your hand and the rest into your graveyard.
addCard(Zone.HAND, playerA, "Sultai Soothsayer");
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 5);
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sultai Soothsayer");
addTarget(playerA, "Silvercoat Lion");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertHandCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 3);
assertPermanentCount(playerA, "Zombie", 1); // May only be one creature
}
/** /**
* Had a Sidisi, Brood Tyrant in play and dredge a Stinkweed Imp hitting 3 creatures. * Had a Sidisi, Brood Tyrant in play and dredge a Stinkweed Imp hitting 3 creatures.
* and Sidisi triggered 3 times instead of just one. * and Sidisi triggered 3 times instead of just one.

View file

@ -10,6 +10,14 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
* 702.87. Rebound
* 702.87a Rebound appears on some instants and sorceries. It represents a static ability that functions while
* the spell is on the stack and may create a delayed triggered ability. "Rebound" means "If this spell was cast
* from your hand, instead of putting it into your graveyard as it resolves, exile it and, at the beginning of
* your next upkeep, you may cast this card from exile without paying its mana cost."
* 702.87b Casting a card without paying its mana cost as the result of a rebound ability follows the rules for
* paying alternative costs in rules 601.2b and 601.2eg.
* 702.87c Multiple instances of rebound on the same spell are redundant.
* *
* @author jeff * @author jeff
*/ */
@ -104,6 +112,8 @@ public class ReboundTest extends CardTestPlayerBase{
addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
// Target creature gets +1/+0 until end of turn and is unblockable this turn. // Target creature gets +1/+0 until end of turn and is unblockable this turn.
// Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep,
// you may cast this card from exile without paying its mana cost.)
addCard(Zone.HAND, playerA, "Distortion Strike"); addCard(Zone.HAND, playerA, "Distortion Strike");
addCard(Zone.BATTLEFIELD, playerA, "Memnite", 1); addCard(Zone.BATTLEFIELD, playerA, "Memnite", 1);
@ -113,12 +123,12 @@ public class ReboundTest extends CardTestPlayerBase{
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Distortion Strike", "Memnite"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Distortion Strike", "Memnite");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Memnite","Distortion Strike"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Memnite","Distortion Strike");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
//check exile and graveyard //check exile and graveyard
assertGraveyardCount(playerB, "Lightning Bolt", 1); assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertGraveyardCount(playerA, "Distortion Strike", 1);
assertGraveyardCount(playerA, "Memnite", 1); assertGraveyardCount(playerA, "Memnite", 1);
assertGraveyardCount(playerA, "Distortion Strike", 1);
} }
} }

View file

@ -68,9 +68,7 @@ public class PutTopCardOfYourLibraryToGraveyardCost extends CostImpl {
Player player = game.getPlayer(controllerId); Player player = game.getPlayer(controllerId);
if (player != null && player.getLibrary().size() >= numberOfCards) { if (player != null && player.getLibrary().size() >= numberOfCards) {
paid = true; paid = true;
Cards cards = new CardsImpl(); player.moveCards(player.getLibrary().getTopCards(game, numberOfCards), Zone.LIBRARY, Zone.GRAVEYARD, ability, game);
cards.addAll(player.getLibrary().getTopCards(game, numberOfCards));
player.moveCardsToGraveyardWithInfo(cards, ability, game, Zone.LIBRARY);
} }
return paid; return paid;
} }

View file

@ -69,7 +69,7 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
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) {
ChoiceColor choice = new ChoiceColor(false); ChoiceColor choice = new ChoiceColor(true);
if (controller.choose(outcome, choice, game)) { if (controller.choose(outcome, choice, game)) {
if (choice.getColor() == null) { if (choice.getColor() == null) {

View file

@ -94,9 +94,6 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
if (mageObject instanceof Card) { if (mageObject instanceof Card) {
Card card = (Card) mageObject; Card card = (Card) mageObject;
switch (targetZone) { switch (targetZone) {
case HAND:
controller.moveCardToHandWithInfo(card, sourceId, game, Zone.STACK);
break;
case LIBRARY: case LIBRARY:
controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true); controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true);
break; break;
@ -104,7 +101,7 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK, true); controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK, true);
break; break;
default: default:
card.moveToZone(targetZone, sourceId, game, flag); controller.moveCards(card, Zone.STACK, targetZone, source, game);
} }
} else { } else {
return false; return false;

View file

@ -74,9 +74,7 @@ public class PutLibraryIntoGraveTargetEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) { if (player != null) {
// putting cards to grave shouldn't end the game, so getting minimun available player.moveCards(player.getLibrary().getTopCards(game, amount.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
int cardsCount = Math.min(amount.calculate(game, source, this), player.getLibrary().size());
player.moveCardsToGraveyardWithInfo(player.getLibrary().getTopCards(game, cardsCount), source, game, Zone.LIBRARY);
return true; return true;
} }
return false; return false;

View file

@ -65,8 +65,7 @@ public class PutTopCardOfLibraryIntoGraveControllerEffect 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) {
controller.moveCardsToGraveyardWithInfo(controller.getLibrary().getTopCards(game, numberCards), source, game, Zone.LIBRARY); return controller.moveCards(controller.getLibrary().getTopCards(game, numberCards), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
return true;
} }
return false; return false;
} }

View file

@ -33,7 +33,6 @@ import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
@ -106,13 +105,7 @@ public class PutTopCardOfLibraryIntoGraveEachPlayerEffect extends OneShotEffect
private void putCardsToGravecard(UUID playerId, Ability source, Game game) { private void putCardsToGravecard(UUID playerId, Ability source, Game game) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
int cardsCount = Math.min(numberCards.calculate(game, source, this), player.getLibrary().size()); player.moveCards(player.getLibrary().getTopCards(game, numberCards.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
} }
} }

View file

@ -100,11 +100,14 @@ public class ReturnFromExileEffect extends OneShotEffect {
} }
break; break;
case HAND: case HAND:
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED); controller.moveCards(card, Zone.EXILED, Zone.HAND, source, game);
break; break;
case LIBRARY: case LIBRARY:
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, true); controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, true);
break; break;
case GRAVEYARD:
controller.moveCards(card, Zone.EXILED, Zone.GRAVEYARD, source, game);
break;
default: default:
card.moveToZone(zone, source.getSourceId(), game, tapped); card.moveToZone(zone, source.getSourceId(), game, tapped);
if (!game.isSimulation()) { if (!game.isSimulation()) {

View file

@ -104,8 +104,8 @@ class DredgeEffect extends ReplacementEffectImpl {
} }
Cards cardsToGrave = new CardsImpl(); Cards cardsToGrave = new CardsImpl();
cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount)); cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount));
player.moveCardsToGraveyardWithInfo(cardsToGrave, source, game, Zone.LIBRARY); player.moveCards(cardsToGrave, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
player.moveCardToHandWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD); player.moveCards(sourceCard, Zone.GRAVEYARD, Zone.HAND, source, game);
return true; return true;
} }
return false; return false;

View file

@ -1204,7 +1204,7 @@ public abstract class GameImpl implements Game, Serializable {
top.resolve(this); top.resolve(this);
} finally { } finally {
if (top != null) { if (top != null) {
state.getStack().remove(top); state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed
rememberLKI(top.getSourceId(), Zone.STACK, top); rememberLKI(top.getSourceId(), Zone.STACK, top);
if (!getTurn().isEndTurnRequested()) { if (!getTurn().isEndTurnRequested()) {
while (state.hasSimultaneousEvents()) { while (state.hasSimultaneousEvents()) {
@ -1739,8 +1739,7 @@ public abstract class GameImpl implements Game, Serializable {
boolean result = false; boolean result = false;
if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) { if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) {
if (!this.isSimulation()) { if (!this.isSimulation()) {
this.informPlayers(new StringBuilder(permanent.getLogName()) this.informPlayers(permanent.getLogName() + " is put into graveyard from battlefield");
.append(" is put into graveyard from battlefield").toString());
} }
result = true; result = true;
} }

View file

@ -81,13 +81,14 @@ public class GameEvent implements Serializable {
//player events //player events
/* ZONE_CHANGE /* ZONE_CHANGE
targetId id of the zone chaning object targetId id of the zone changing object
sourceId sourceId of the ability with the object moving effect sourceId sourceId of the ability with the object moving effect
playerId controller of the moved object playerId controller of the moved object
amount not used for this event amount not used for this event
flag not used for this event flag not used for this event
*/ */
ZONE_CHANGE, ZONE_CHANGE,
ZONE_CHANGE_GROUP,
EMPTY_DRAW, EMPTY_DRAW,
DRAW_CARD, DREW_CARD, DRAW_CARD, DREW_CARD,
MIRACLE_CARD_REVEALED, MIRACLE_CARD_REVEALED,

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.game.events;
import java.util.List;
import java.util.UUID;
import mage.cards.Card;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class ZoneChangeGroupEvent extends GameEvent {
private final Zone fromZone;
private final Zone toZone;
private final List<Card> cards;
public ZoneChangeGroupEvent(List<Card> cards, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
super(EventType.ZONE_CHANGE_GROUP, null, sourceId, playerId);
this.fromZone = fromZone;
this.toZone = toZone;
this.cards = cards;
}
public Zone getFromZone() {
return fromZone;
}
public Zone getToZone() {
return toZone;
}
public List<Card> getCards() {
return cards;
}
}

View file

@ -201,13 +201,14 @@ public class Spell implements StackObject, Card {
result |= spellAbility.resolve(game); result |= spellAbility.resolve(game);
} }
} }
// game.getState().handleSimultaneousEvent(game);
// game.resetShortLivingLKI();
index++; index++;
} }
} }
if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) { if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) {
card.moveToZone(Zone.GRAVEYARD, ability.getSourceId(), game, false); Player player = game.getPlayer(getControllerId());
if (player != null) {
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, ability, game);
}
} }
return result; return result;
} }
@ -524,7 +525,15 @@ public class Spell implements StackObject, Card {
public void counter(UUID sourceId, Game game) { public void counter(UUID sourceId, Game game) {
this.countered = true; this.countered = true;
if (!isCopiedSpell()) { if (!isCopiedSpell()) {
card.moveToZone(Zone.GRAVEYARD, sourceId, game, false); Player player = game.getPlayer(getControllerId());
if (player != null) {
Ability counteringAbility = null;
MageObject counteringObject = game.getObject(sourceId);
if (counteringObject instanceof StackObject) {
counteringAbility = ((StackObject)counteringObject).getStackAbility();
}
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, counteringAbility, game);
}
} }
} }

View file

@ -502,10 +502,8 @@ public interface Player extends MageItem, Copyable<Player> {
/** /**
* Moves 1 to n cards to the graveyard. The owner of the cards may determine the order, * Internal used to move cards
* if more than one card is moved to graveyard. * Use commonly player.moveCards()
* Uses card.moveToZone and posts a inform message about moving the card to graveyard
* into the game log
* *
* @param cards * @param cards
* @param source * @param source
@ -513,7 +511,6 @@ public interface Player extends MageItem, Copyable<Player> {
* @param fromZone if null, this info isn't postet * @param fromZone if null, this info isn't postet
* @return * @return
*/ */
boolean moveCardsToGraveyardWithInfo(Cards cards, Ability source, Game game, Zone fromZone);
boolean moveCardsToGraveyardWithInfo(List<Card> cards, Ability source, Game game, Zone fromZone); boolean moveCardsToGraveyardWithInfo(List<Card> cards, Ability source, Game game, Zone fromZone);
/** /**

View file

@ -113,6 +113,7 @@ import mage.game.events.DamagePlayerEvent;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeGroupEvent;
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;
@ -2844,14 +2845,19 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCards(List<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) { public boolean moveCards(List<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
if (cards.isEmpty()) {
return true;
}
game.fireEvent(new ZoneChangeGroupEvent(cards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone));
switch(toZone) { switch(toZone) {
case GRAVEYARD: case GRAVEYARD:
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone); return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
case HAND: case HAND:
boolean result = false;
for(Card card: cards) { for(Card card: cards) {
moveCardToHandWithInfo(card, playerId, game, fromZone); result |= moveCardToHandWithInfo(card, playerId, game, fromZone);
} }
return true; return result;
default: default:
throw new UnsupportedOperationException("to Zone not supported yet"); throw new UnsupportedOperationException("to Zone not supported yet");
} }
@ -2887,32 +2893,24 @@ public abstract class PlayerImpl implements Player, Serializable {
return result; return result;
} }
@Override
public boolean moveCardsToGraveyardWithInfo(Cards allCards, Ability source, Game game, Zone fromZone) {
ArrayList<Card> cards = new ArrayList<>();
cards.addAll(allCards.getCards(game));
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
}
@Override @Override
public boolean moveCardsToGraveyardWithInfo(List<Card> allCards, Ability source, Game game, Zone fromZone) { public boolean moveCardsToGraveyardWithInfo(List<Card> allCards, Ability source, Game game, Zone fromZone) {
while (!allCards.isEmpty()) { while (!allCards.isEmpty()) {
// identify cards from one owner // identify cards from one owner
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
UUID ownerId = null; UUID ownerId = null;
for (Card card: allCards) { for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
Card card = it.next();
if (cards.isEmpty()) { if (cards.isEmpty()) {
ownerId = card.getOwnerId(); ownerId = card.getOwnerId();
} }
if (card.getOwnerId().equals(ownerId)) { if (card.getOwnerId().equals(ownerId)) {
it.remove();
cards.add(card); cards.add(card);
} }
} }
allCards.removeAll(cards.getCards(game));
// move cards ot graveyard in order the owner decides // move cards ot graveyard in order the owner decides
if (cards.size() != 0) { if (!cards.isEmpty()) {
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
target.setRequired(true);
Player choosingPlayer = this; Player choosingPlayer = this;
if (ownerId != this.getId()) { if (ownerId != this.getId()) {
choosingPlayer = game.getPlayer(ownerId); choosingPlayer = game.getPlayer(ownerId);
@ -2925,6 +2923,8 @@ public abstract class PlayerImpl implements Player, Serializable {
chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", game); chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", game);
} }
if (chooseOrder) { if (chooseOrder) {
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
target.setRequired(true);
while (choosingPlayer.isInGame() && cards.size() > 1) { while (choosingPlayer.isInGame() && cards.size() > 1) {
choosingPlayer.chooseTarget(Outcome.Neutral, cards, target, source, game); choosingPlayer.chooseTarget(Outcome.Neutral, cards, target, source, game);
UUID targetObjectId = target.getFirstTarget(); UUID targetObjectId = target.getFirstTarget();
@ -2936,7 +2936,7 @@ public abstract class PlayerImpl implements Player, Serializable {
target.clearChosen(); target.clearChosen();
} }
if (cards.size() == 1) { if (cards.size() == 1) {
choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source.getSourceId(), game, fromZone); choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source == null ? null : source.getSourceId(), game, fromZone);
} }
} else { } else {
for (Card card : cards.getCards(game)) { for (Card card : cards.getCards(game)) {

View file

@ -83,7 +83,7 @@ public class TargetPermanentOrPlayer extends TargetImpl {
@Override @Override
public Filter getFilter() { public Filter getFilter() {
return this.filter; return filter;
} }
public void setFilter(FilterPermanentOrPlayer filter) { public void setFilter(FilterPermanentOrPlayer filter) {

View file

@ -34,7 +34,6 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import java.util.UUID; import java.util.UUID;
import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.CounterPredicate; import mage.filter.predicate.permanent.CounterPredicate;