From f4b667650c66a85251cab6b655f7b95c54077219 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 11 Oct 2015 03:57:29 +0200 Subject: [PATCH] * Fixed that enters the battlefield replacement effects of objects entering the battlefield were able to see permanents that entered the battlefield by the same effect (e.g. a Phyrexian Metamorph put onto the battlefield with Show and Tell was able to copy permanents that other players put onto the battlefield with the same Show and Tell.) fixes #594. --- Mage.Sets/src/mage/sets/exodus/Manabond.java | 48 +++++------ .../sets/innistrad/GrimoireOfTheDead.java | 40 +++++---- .../src/mage/sets/magic2010/LilianaVess.java | 31 +++---- .../mage/sets/magic2011/MassPolymorph.java | 84 ++++++++++--------- .../sets/magic2014/RiseOfTheDarkRealms.java | 23 +++-- .../sets/magicorigins/AnimistsAwakening.java | 21 +++-- .../sets/scarsofmirrodin/GenesisWave.java | 6 +- .../src/mage/sets/urzassaga/ShowAndTell.java | 19 +++-- 8 files changed, 149 insertions(+), 123 deletions(-) diff --git a/Mage.Sets/src/mage/sets/exodus/Manabond.java b/Mage.Sets/src/mage/sets/exodus/Manabond.java index 95dcbe4d6c..b3d4487f70 100644 --- a/Mage.Sets/src/mage/sets/exodus/Manabond.java +++ b/Mage.Sets/src/mage/sets/exodus/Manabond.java @@ -27,17 +27,19 @@ */ package mage.sets.exodus; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.Cards; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -51,8 +53,7 @@ public class Manabond extends CardImpl { super(ownerId, 113, "Manabond", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.expansionSetCode = "EXO"; - - // At the beginning of your end step, you may reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand. + // At the beginning of your end step, reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand. this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new ManabondEffect(), true)); } @@ -66,12 +67,11 @@ public class Manabond extends CardImpl { } } - class ManabondEffect extends OneShotEffect { public ManabondEffect() { super(Outcome.PutCardInPlay); - staticText = "reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand"; + staticText = "you may reveal your hand and put all land cards from it onto the battlefield. If you do, discard your hand"; } public ManabondEffect(final ManabondEffect effect) { @@ -80,24 +80,22 @@ class ManabondEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.revealCards("Manabond", player.getHand(), game); - - Cards hand = player.getHand().copy(); - for(UUID uuid : hand){ + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + controller.revealCards(sourceObject.getIdName(), controller.getHand(), game); + Set toBattlefield = new LinkedHashSet<>(); + for (UUID uuid : controller.getHand()) { Card card = game.getCard(uuid); - if(card != null){ - if(card.getCardType().contains(CardType.LAND)){ - card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); - } - else{ - player.discard(card, source, game); - } + if (card != null && card.getCardType().contains(CardType.LAND)) { + toBattlefield.add(card); } + } - - } + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, false, true, null); + controller.discard(controller.getHand().size(), false, source, game); + return true; + } return false; } @@ -105,4 +103,4 @@ class ManabondEffect extends OneShotEffect { public ManabondEffect copy() { return new ManabondEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java b/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java index 84e2bdea4e..bf41dc6d02 100644 --- a/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java +++ b/Mage.Sets/src/mage/sets/innistrad/GrimoireOfTheDead.java @@ -27,14 +27,9 @@ */ package mage.sets.innistrad; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardTargetCost; @@ -47,6 +42,13 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -101,15 +103,21 @@ class GrimoireOfTheDeadEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Player player: game.getPlayers().values()) { - for (Card card: player.getGraveyard().getCards(game)) { - if (card.getCardType().contains(CardType.CREATURE)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - game.addEffect(new GrimoireOfTheDeadEffect2(card.getId()), source); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Set creatureCards = new LinkedHashSet<>(); + for (Player player : game.getPlayers().values()) { + for (Card card : player.getGraveyard().getCards(game)) { + if (card.getCardType().contains(CardType.CREATURE)) { + creatureCards.add(card); + game.addEffect(new GrimoireOfTheDeadEffect2(card.getId()), source); + } } } + controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null); + return true; } - return true; + return false; } @Override @@ -121,10 +129,10 @@ class GrimoireOfTheDeadEffect extends OneShotEffect { class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl { - private UUID targetId; + private final UUID targetId; public GrimoireOfTheDeadEffect2(UUID targetId) { - super(Duration.EndOfGame, Outcome.Neutral); + super(Duration.Custom, Outcome.Neutral); this.targetId = targetId; staticText = "Becomes a black Zombie in addition to its other colors and types"; } @@ -170,4 +178,4 @@ class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl { return layer == Layer.ColorChangingEffects_5 || layer == Layer.TypeChangingEffects_4; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java index d03f79e665..5f955caa78 100644 --- a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java +++ b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,28 +20,29 @@ * 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.sets.magic2010; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.players.Player; @@ -98,14 +99,16 @@ class LilianaVessEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getGraveyard().getCards(game)) { + Set creatureCards = new LinkedHashSet<>(); + for (Card card : player.getGraveyard().getCards(game)) { if (card.getCardType().contains(CardType.CREATURE)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); + creatureCards.add(card); } } + controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, false, null); } } return true; diff --git a/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java b/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java index 9e159d7af7..95bb22a363 100644 --- a/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java +++ b/Mage.Sets/src/mage/sets/magic2011/MassPolymorph.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,32 +20,34 @@ * 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.sets.magic2011; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import java.util.List; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -82,34 +84,36 @@ class MassPolymorphEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int count; - List creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game); - count = creatures.size(); - for (Permanent creature: creatures) { - creature.moveToExile(null, null, source.getSourceId(), game); - } - Cards revealed = new CardsImpl(); - Cards creatureCards = new CardsImpl(); - Cards nonCreatureCards = new CardsImpl(); - Player player = game.getPlayer(source.getControllerId()); - while (creatureCards.size() < count && player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); - revealed.add(card); - if (card.getCardType().contains(CardType.CREATURE)) { - creatureCards.add(card); - } else { - nonCreatureCards.add(card); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + int count; + // Cards creatures = new CardsImpl(); + List creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game); + Set creaturesToExile = new HashSet<>(); + creaturesToExile.addAll(creatures); + count = creatures.size(); + controller.moveCards(creaturesToExile, null, Zone.HAND, source, game); + + Cards revealed = new CardsImpl(); + Set creatureCards = new LinkedHashSet<>(); + Cards nonCreatureCards = new CardsImpl(); + while (creatureCards.size() < count && controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); + revealed.add(card); + if (card.getCardType().contains(CardType.CREATURE)) { + creatureCards.add(card); + } else { + nonCreatureCards.add(card); + } } + controller.revealCards(sourceObject.getIdName(), revealed, game); + controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null); + controller.putCardsOnTopOfLibrary(nonCreatureCards, game, source, false); + controller.shuffleLibrary(game); + return true; } - player.revealCards("Mass Polymorph", revealed, game); - for (Card creatureCard: creatureCards.getCards(game)) { - creatureCard.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); - } - for (Card card: nonCreatureCards.getCards(game)) { - player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true, true); - } - player.shuffleLibrary(game); - return true; + return false; } @Override @@ -117,4 +121,4 @@ class MassPolymorphEffect extends OneShotEffect { return new MassPolymorphEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java b/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java index 8b84ffb612..4fbe776a8c 100644 --- a/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java +++ b/Mage.Sets/src/mage/sets/magic2014/RiseOfTheDarkRealms.java @@ -27,6 +27,8 @@ */ package mage.sets.magic2014; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -49,7 +51,6 @@ public class RiseOfTheDarkRealms extends CardImpl { super(ownerId, 111, "Rise of the Dark Realms", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{7}{B}{B}"); this.expansionSetCode = "M14"; - // Put all creature cards from all graveyards onto the battlefield under your control. this.getSpellAbility().addEffect(new RiseOfTheDarkRealmsEffect()); } @@ -78,17 +79,23 @@ class RiseOfTheDarkRealmsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - for (UUID playerId: controller.getInRange()) { - Player player = game.getPlayer(playerId); - if (player != null) { - for (Card card: player.getGraveyard().getCards(game)) { - if (card.getCardType().contains(CardType.CREATURE)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); + if (controller != null) { + + Set creatureCards = new LinkedHashSet<>(); + for (UUID playerId : controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + for (Card card : player.getGraveyard().getCards(game)) { + if (card.getCardType().contains(CardType.CREATURE)) { + creatureCards.add(card); + } } } } + controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, true, null); + return true; } - return true; + return false; } @Override diff --git a/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java index 4cbe0168fc..4ccfccda7a 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java +++ b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java @@ -27,8 +27,8 @@ */ package mage.sets.magicorigins; -import java.util.ArrayList; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -94,23 +94,22 @@ class AnimistsAwakeningEffect extends OneShotEffect { Cards cards = new CardsImpl(Zone.LIBRARY); int xValue = source.getManaCostsToPay().getX(); cards.addAll(controller.getLibrary().getTopCards(game, xValue)); - List lands = new ArrayList<>(); if (cards.size() > 0) { controller.revealCards(sourceObject.getIdName(), cards, game); + Set toBattlefield = new LinkedHashSet<>(); for (Card card : cards.getCards(new FilterLandCard(), source.getSourceId(), source.getControllerId(), game)) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); - Permanent land = game.getPermanent(card.getId()); - if (land != null) { - lands.add(land); - } - + toBattlefield.add(card); } + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, true, false, true, null); controller.putCardsOnBottomOfLibrary(cards, game, source, true); if (SpellMasteryCondition.getInstance().apply(game, source)) { - for (Permanent land : lands) { - land.untap(game); + for (Card card : toBattlefield) { + Permanent land = game.getPermanent(card.getId()); + if (land != null) { + land.untap(game); + } } } } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java index b20a7cfe24..c8224d6d27 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java @@ -27,6 +27,8 @@ */ package mage.sets.scarsofmirrodin; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -115,13 +117,15 @@ class GenesisWaveEffect extends OneShotEffect { target1.setRequired(false); controller.choose(Outcome.PutCardInPlay, cards, target1, game); + Set toBattlefield = new LinkedHashSet<>(); for (UUID cardId : target1.getTargets()) { Card card = cards.get(cardId, game); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + toBattlefield.add(card); } } + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, false, false, null); controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); } return true; diff --git a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java index 856e29d194..3bbcbbefb1 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java +++ b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java @@ -28,7 +28,9 @@ package mage.sets.urzassaga; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -102,7 +104,7 @@ class ShowAndTellEffect extends OneShotEffect { if (controller == null) { return false; } - List cardsToPutIntoPlay = new ArrayList<>(); + Set cardsToPutIntoPlay = new LinkedHashSet<>(); TargetCardInHand target = new TargetCardInHand(filter); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { @@ -119,12 +121,13 @@ class ShowAndTellEffect extends OneShotEffect { } } } - for (Card card : cardsToPutIntoPlay) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - return true; + return controller.moveCards(cardsToPutIntoPlay, Zone.BATTLEFIELD, source, game, false, false, true, null); +// for (Card card : cardsToPutIntoPlay) { +// Player player = game.getPlayer(card.getOwnerId()); +// if (player != null) { +// player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); +// } +// } + // return true; } }