From e2f960c8fd39a5e81b45d1be1f3c86da933149dd Mon Sep 17 00:00:00 2001 From: bugfi5h Date: Wed, 26 Apr 2017 19:41:18 +0200 Subject: [PATCH 01/11] Added Card: Natural Balance --- .../src/mage/cards/n/NaturalBalance.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NaturalBalance.java diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java new file mode 100644 index 00000000000..16ac660a5ff --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java @@ -0,0 +1,137 @@ +/* + * 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.cards.n; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterBasicLandCard; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.players.PlayerList; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author Rene - bugisemail at gmail dot com + */ +public class NaturalBalance extends CardImpl { + + public NaturalBalance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + + + // Each player who controls six or more lands chooses five lands he or she controls and sacrifices the rest. Each player who controls four or fewer lands may search his or her library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands he or she controls. Then each player who searched his or her library this way shuffles it. + this.getSpellAbility().addEffect(new NaturalBalanceEffect()); + } + + public NaturalBalance(final NaturalBalance card) { + super(card); + } + + @Override + public NaturalBalance copy() { + return new NaturalBalance(this); + } + + class NaturalBalanceEffect extends OneShotEffect { + + public NaturalBalanceEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Each player who controls six or more lands chooses five lands he or she controls and sacrifices the rest. Each player who controls four or fewer lands may search his or her library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands he or she controls. Then each player who searched his or her library this way shuffles it."; + } + + public NaturalBalanceEffect(final NaturalBalanceEffect effect) { + super(effect); + } + + @Override + public NaturalBalanceEffect copy() { + return new NaturalBalanceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) + { + PlayerList players = game.getState().getPlayerList(controller.getId()); + for (UUID playerId : players) + { + Player player = game.getPlayer(playerId); + if (player != null) + { + int landCount = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); + if (landCount>5) + { + //Sacrifice lands till you have 5 + TargetControlledPermanent target = new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("lands to keep"), true); + if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) + { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) + { + if (permanent != null && !target.getTargets().contains(permanent.getId())) + { + permanent.sacrifice(source.getId(), game); + } + } + } + }else if(landCount<5) + { + //Play basic lands till you have 5 + FilterLandPermanent filter = new FilterLandPermanent(); + filter.add(new ControllerPredicate(TargetController.YOU)); + int amount = 5 - landCount; + TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterBasicLandCard()); + if (player.searchLibrary(target, game)) + { + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); + } + player.shuffleLibrary(source, game); + } + } + } + return true; + } + return false; + } + } +} From f20496e40ffe61f7d6fa2401f4427d505ce3662f Mon Sep 17 00:00:00 2001 From: bugfi5h Date: Wed, 26 Apr 2017 23:11:46 +0200 Subject: [PATCH 02/11] Auto indent class --- .../src/mage/cards/n/NaturalBalance.java | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java index 16ac660a5ff..ad75b2eec31 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalBalance.java +++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java @@ -57,7 +57,6 @@ public class NaturalBalance extends CardImpl { public NaturalBalance(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); - // Each player who controls six or more lands chooses five lands he or she controls and sacrifices the rest. Each player who controls four or fewer lands may search his or her library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands he or she controls. Then each player who searched his or her library this way shuffles it. this.getSpellAbility().addEffect(new NaturalBalanceEffect()); @@ -71,7 +70,7 @@ public class NaturalBalance extends CardImpl { public NaturalBalance copy() { return new NaturalBalance(this); } - + class NaturalBalanceEffect extends OneShotEffect { public NaturalBalanceEffect() { @@ -91,42 +90,33 @@ public class NaturalBalance extends CardImpl { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) - { + if (controller != null) { PlayerList players = game.getState().getPlayerList(controller.getId()); - for (UUID playerId : players) - { + for (UUID playerId : players) { Player player = game.getPlayer(playerId); - if (player != null) - { + if (player != null) { int landCount = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); - if (landCount>5) - { + if (landCount > 5) { //Sacrifice lands till you have 5 TargetControlledPermanent target = new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("lands to keep"), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) - { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) - { - if (permanent != null && !target.getTargets().contains(permanent.getId())) - { + if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) { + if (permanent != null && !target.getTargets().contains(permanent.getId())) { permanent.sacrifice(source.getId(), game); } } } - }else if(landCount<5) - { + } else if (landCount < 5) { //Play basic lands till you have 5 FilterLandPermanent filter = new FilterLandPermanent(); filter.add(new ControllerPredicate(TargetController.YOU)); int amount = 5 - landCount; TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterBasicLandCard()); - if (player.searchLibrary(target, game)) - { + if (player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); } player.shuffleLibrary(source, game); - } + } } } return true; From 59a790e320cb8ce5aaacb6511462e6b3b1d336c8 Mon Sep 17 00:00:00 2001 From: bugfi5h Date: Thu, 27 Apr 2017 06:33:35 +0200 Subject: [PATCH 03/11] Using getPlayersInRange instead of getPlayersList --- Mage.Sets/src/mage/cards/n/NaturalBalance.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java index ad75b2eec31..82cf67c3bc9 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalBalance.java +++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java @@ -29,7 +29,6 @@ package mage.cards.n; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -91,7 +90,7 @@ public class NaturalBalance extends CardImpl { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - PlayerList players = game.getState().getPlayerList(controller.getId()); + PlayerList players = game.getState().getPlayersInRange(controller.getId(),game); for (UUID playerId : players) { Player player = game.getPlayer(playerId); if (player != null) { From 10ecbd5adbb5cb761bc75f2f559c570e28e7fe54 Mon Sep 17 00:00:00 2001 From: igoudt Date: Fri, 28 Apr 2017 09:24:27 +0200 Subject: [PATCH 04/11] fix for shadow of the grave --- Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java | 5 ++--- .../CardsCycledOrDiscardedThisTurnWatcher.java | 15 +++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java index 417732d13a6..adea148f588 100644 --- a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java +++ b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java @@ -86,12 +86,11 @@ class ShadowOfTheGraveEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); CardsCycledOrDiscardedThisTurnWatcher watcher = (CardsCycledOrDiscardedThisTurnWatcher) game.getState().getWatchers().get("CardsCycledOrDiscardedThisTurnWatcher"); if (controller != null - && watcher != null - && watcher.getCardsCycledOrDiscardedThisTurn(controller.getId()) != null) { + && watcher != null) { for (Card card : watcher.getCardsCycledOrDiscardedThisTurn(controller.getId()).getCards(game)) { if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD //must come from their graveyard - && card.getOwnerId() == controller.getId()) { //confirm ownership + && card.getOwnerId().equals(controller.getId())) { //confirm ownership controller.moveCardToHandWithInfo(card, source.getId(), game, true); } } diff --git a/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java index b54118f03d2..a4a8c29a12c 100644 --- a/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; + import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; @@ -41,12 +42,12 @@ import mage.watchers.Watcher; /** * Stores cards that were cycled or discarded by any player this turn. + * * @author jeffwadsworth */ public class CardsCycledOrDiscardedThisTurnWatcher extends Watcher { - + private final Map cycledOrDiscardedCardsThisTurn = new HashMap<>(); - Cards cards = new CardsImpl(); public CardsCycledOrDiscardedThisTurnWatcher() { super("CardsCycledOrDiscardedThisTurnWatcher", WatcherScope.GAME); @@ -67,24 +68,22 @@ public class CardsCycledOrDiscardedThisTurnWatcher extends Watcher { if (event.getType() == GameEvent.EventType.CYCLED_CARD || event.getType() == GameEvent.EventType.DISCARDED_CARD) { UUID playerId = event.getPlayerId(); - if (playerId != null + if (playerId != null && game.getCard(event.getTargetId()) != null) { Card card = game.getCard(event.getTargetId()); - cards.add(card); - cycledOrDiscardedCardsThisTurn.putIfAbsent(playerId, cards); + getCardsCycledOrDiscardedThisTurn(playerId).add(card); } } } - public Cards getCardsCycledOrDiscardedThisTurn(UUID playerId) { - return cycledOrDiscardedCardsThisTurn.get(playerId); + public Cards getCardsCycledOrDiscardedThisTurn(UUID playerId) { + return cycledOrDiscardedCardsThisTurn.getOrDefault(playerId, new CardsImpl()); } @Override public void reset() { super.reset(); cycledOrDiscardedCardsThisTurn.clear(); - cards.clear(); } @Override From 6b66f8c05b285bab40793f254613a5fa9cbddfc0 Mon Sep 17 00:00:00 2001 From: igoudt Date: Fri, 28 Apr 2017 10:23:13 +0200 Subject: [PATCH 05/11] add cartouche as enchantment subtype --- Mage/src/main/java/mage/util/CardUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 2a89380ec71..1d3863ecba6 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -61,13 +61,13 @@ public final class CardUtil { private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone"; static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", - "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen", "twenty"}; + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; - public static final String[] NON_CHANGELING_SUBTYPES_VALUES = new String[]{ + private static final String[] NON_CHANGELING_SUBTYPES_VALUES = new String[]{ // basic lands subtypes "Mountain", "Forest", "Plains", "Swamp", "Island", // Enchantment subtypes - "Aura", "Curse", "Shrine", + "Aura", "Cartouche", "Curse", "Shrine", // Artifact subtypes "Clue", "Equipment", "Fortification", "Contraption", "Vehicle", // Land subtypes @@ -78,7 +78,7 @@ public final class CardUtil { "Tezzeret", "Tibalt", "Ugin", "Venser", "Vraska", "Xenagos", // Instant sorcery subtypes "Trap", "Arcane"}; - public static final Set NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); + private static final Set NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); From 3cc3d430ea08e08c07b7704d53f21d7d834b59e0 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 10:26:51 +0200 Subject: [PATCH 06/11] * Bontu the Glorified - Fixed that it was possible to sacrifice non creature permanents. --- .../src/mage/cards/b/BontuTheGlorified.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java index 5ba3a53b97b..6736154c0e4 100644 --- a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java +++ b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java @@ -27,14 +27,9 @@ */ package mage.cards.b; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.SacrificeTargetCost; @@ -46,11 +41,16 @@ import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.watchers.common.CreaturesDiedWatcher; @@ -61,7 +61,7 @@ import mage.watchers.common.CreaturesDiedWatcher; */ public class BontuTheGlorified extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("another creature"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another creature"); static { filter.add(new AnotherPredicate()); From 108f3faaa82a6e3e6597e68b9d0db6d79cd50ea5 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 10:56:44 +0200 Subject: [PATCH 07/11] * Natural Balance - Some minor changes. --- .../src/mage/cards/n/NaturalBalance.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java index 82cf67c3bc9..fbe00748196 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalBalance.java +++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java @@ -27,6 +27,8 @@ */ package mage.cards.n; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -35,12 +37,10 @@ import mage.cards.CardSetInfo; import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.common.FilterBasicLandCard; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterLandPermanent; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -90,34 +90,45 @@ public class NaturalBalance extends CardImpl { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - PlayerList players = game.getState().getPlayersInRange(controller.getId(),game); + PlayerList players = game.getState().getPlayersInRange(controller.getId(), game); for (UUID playerId : players) { Player player = game.getPlayer(playerId); if (player != null) { int landCount = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); if (landCount > 5) { - //Sacrifice lands till you have 5 + // chooses five lands he or she controls and sacrifices the rest TargetControlledPermanent target = new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("lands to keep"), true); if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game)) { + if (!target.getTargets().contains(permanent.getId())) { permanent.sacrifice(source.getId(), game); } } } - } else if (landCount < 5) { - //Play basic lands till you have 5 - FilterLandPermanent filter = new FilterLandPermanent(); - filter.add(new ControllerPredicate(TargetController.YOU)); - int amount = 5 - landCount; + } + } + } + List toShuffle = new ArrayList<>(); + for (UUID playerId : players) { + Player player = game.getPlayer(playerId); + if (player != null) { + int landCount = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); + int amount = 5 - landCount; + if (landCount < 5 && player.chooseUse(outcome, "Search your library for up to " + amount + " basic land cards and put them onto the battlefield?", source, game)) { + // Select lands and put them onto battlefield TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { - player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(source, game); + toShuffle.add(player); } } } + for (Player player : toShuffle) { + if (player.isInGame()) { + player.shuffleLibrary(source, game); + } + } return true; } return false; From 33f6c629c2f6028a6dfb4699b1abe5b230d9ff96 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 11:18:26 +0200 Subject: [PATCH 08/11] * Shadow of the Grave - Some minor adjustments. --- Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java | 8 ++++---- .../CardsCycledOrDiscardedThisTurnWatcher.java | 16 ++++++---------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java index adea148f588..3ebf33a7426 100644 --- a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java +++ b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java @@ -84,13 +84,13 @@ class ShadowOfTheGraveEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - CardsCycledOrDiscardedThisTurnWatcher watcher = (CardsCycledOrDiscardedThisTurnWatcher) game.getState().getWatchers().get("CardsCycledOrDiscardedThisTurnWatcher"); + CardsCycledOrDiscardedThisTurnWatcher watcher = (CardsCycledOrDiscardedThisTurnWatcher) game.getState() + .getWatchers().get(CardsCycledOrDiscardedThisTurnWatcher.class.getName()); if (controller != null && watcher != null) { for (Card card : watcher.getCardsCycledOrDiscardedThisTurn(controller.getId()).getCards(game)) { - if (card != null - && game.getState().getZone(card.getId()) == Zone.GRAVEYARD //must come from their graveyard - && card.getOwnerId().equals(controller.getId())) { //confirm ownership + if (game.getState().getZone(card.getId()) == Zone.GRAVEYARD //must come from their graveyard + && card.getOwnerId().equals(controller.getId())) { //confirm ownership, but it should not be possible to get not ownwd cards here controller.moveCardToHandWithInfo(card, source.getId(), game, true); } } diff --git a/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java index a4a8c29a12c..975ff721570 100644 --- a/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/CardsCycledOrDiscardedThisTurnWatcher.java @@ -31,7 +31,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; - import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; @@ -50,28 +49,25 @@ public class CardsCycledOrDiscardedThisTurnWatcher extends Watcher { private final Map cycledOrDiscardedCardsThisTurn = new HashMap<>(); public CardsCycledOrDiscardedThisTurnWatcher() { - super("CardsCycledOrDiscardedThisTurnWatcher", WatcherScope.GAME); + super(CardsCycledOrDiscardedThisTurnWatcher.class.getName(), WatcherScope.GAME); } public CardsCycledOrDiscardedThisTurnWatcher(final CardsCycledOrDiscardedThisTurnWatcher watcher) { super(watcher); for (Entry entry : watcher.cycledOrDiscardedCardsThisTurn.entrySet()) { - cycledOrDiscardedCardsThisTurn.put(entry.getKey(), entry.getValue()); + cycledOrDiscardedCardsThisTurn.put(entry.getKey(), entry.getValue().copy()); } } @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.UNTAP_STEP_PRE) { - reset(); - } if (event.getType() == GameEvent.EventType.CYCLED_CARD || event.getType() == GameEvent.EventType.DISCARDED_CARD) { - UUID playerId = event.getPlayerId(); - if (playerId != null - && game.getCard(event.getTargetId()) != null) { + if (event.getPlayerId() != null) { Card card = game.getCard(event.getTargetId()); - getCardsCycledOrDiscardedThisTurn(playerId).add(card); + if (card != null) { + getCardsCycledOrDiscardedThisTurn(event.getPlayerId()).add(card); + } } } } From 236608cd0f97650289e2d14303502ea6ddbb17fe Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 14:18:58 +0200 Subject: [PATCH 09/11] * Approach Of The Second Sun - Fixed that it did not always correctly determined if a player has won (fixes #3250). --- .../src/mage/cards/a/ApproachOfTheSecondSun.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java index d6c22bc413c..fe964aabca5 100644 --- a/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java +++ b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java @@ -1,7 +1,6 @@ package mage.cards.a; import java.util.*; - import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -115,7 +114,7 @@ class ApproachOfTheSecondSunWatcher extends Watcher { public ApproachOfTheSecondSunWatcher(final ApproachOfTheSecondSunWatcher watcher) { super(watcher); - approachesCast = new HashMap<>(approachesCast); + approachesCast = new HashMap<>(watcher.approachesCast); } @Override @@ -123,19 +122,13 @@ class ApproachOfTheSecondSunWatcher extends Watcher { if (event.getType() == GameEvent.EventType.SPELL_CAST) { Spell spell = game.getStack().getSpell(event.getSourceId()); if (spell != null && spell.getName().equals("Approach of the Second Sun")) { - int cast = getApproachesCast(event.getPlayerId()); - approachesCast.put(event.getPlayerId(), cast + 1); + approachesCast.put(event.getPlayerId(), getApproachesCast(event.getPlayerId()) + 1); } } } public int getApproachesCast(UUID player) { - Integer cast = approachesCast.get(player); - if (cast == null) { - return 0; - } else { - return cast; - } + return approachesCast.getOrDefault(player, 0); } @Override From 47de4cac6bedc951e6b50199468fcb82dbf0d8d0 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 14:25:04 +0200 Subject: [PATCH 10/11] * Squandered Resources - Fixed that the ability was no mana ability (fixes #3259). --- Mage.Sets/src/mage/cards/s/SquanderedResources.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SquanderedResources.java b/Mage.Sets/src/mage/cards/s/SquanderedResources.java index 21a2111de64..22ac6ff11ea 100644 --- a/Mage.Sets/src/mage/cards/s/SquanderedResources.java +++ b/Mage.Sets/src/mage/cards/s/SquanderedResources.java @@ -30,7 +30,6 @@ package mage.cards.s; import mage.Mana; import mage.abilities.Abilities; import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.common.ManaEffect; @@ -54,6 +53,7 @@ import mage.target.common.TargetControlledPermanent; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.abilities.mana.SimpleManaAbility; /** * @@ -67,7 +67,7 @@ public class SquanderedResources extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}{G}"); // Sacrifice a land: Add to your mana pool one mana of any type the sacrificed land could produce. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SquanderedResourcesEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new SquanderedResourcesEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); } public SquanderedResources(final SquanderedResources card) { From 26e81ab26d5d3af75ebc624eb21ad61c7b774d7b Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 28 Apr 2017 15:41:38 +0200 Subject: [PATCH 11/11] * Added UT for #3251. --- Mage.Sets/src/mage/cards/r/RagsRiches.java | 5 +- .../single/soi/TheGitrogMonsterTest.java | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/r/RagsRiches.java b/Mage.Sets/src/mage/cards/r/RagsRiches.java index d14601815eb..2e801390330 100644 --- a/Mage.Sets/src/mage/cards/r/RagsRiches.java +++ b/Mage.Sets/src/mage/cards/r/RagsRiches.java @@ -75,7 +75,8 @@ class RichesEffect extends OneShotEffect { Player opponent = game.getPlayer(playerId); if (opponent != null) { TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - if (opponent.chooseTarget(Outcome.Detriment, target, source, game)) { + target.setNotTarget(true); + if (opponent.choose(Outcome.Detriment, target, source.getSourceId(), game)) { creaturesToSteal.add(target.getTargets().get(0)); } } @@ -85,7 +86,7 @@ class RichesEffect extends OneShotEffect { // Has to be done as a separate loop in case there's a situation where one creature's // controller depends on another creatures controller. for (UUID target : creaturesToSteal) { - GainControlTargetEffect eff = new GainControlTargetEffect(Duration.EndOfGame, true); + GainControlTargetEffect eff = new GainControlTargetEffect(Duration.Custom, true); eff.setTargetPointer(new FixedTarget(target)); game.addEffect(eff, source); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/TheGitrogMonsterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/TheGitrogMonsterTest.java index 322f47980c7..82ca94b6a2f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/TheGitrogMonsterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/TheGitrogMonsterTest.java @@ -95,4 +95,57 @@ public class TheGitrogMonsterTest extends CardTestPlayerBase { assertPermanentCount(playerA, "The Gitrog Monster", 0); assertPermanentCount(playerB, "Planar Outburst", 0); } + + /** + * I took control of a Gitrog Monster, while the Gitrog Monster's owner + * controlled a Dryad Arbor and cast Toxic Deluge for 6. + */ + @Test + public void controlChange() { + // Deathtouch + // At the beginning of your upkeep, sacrifice The Gitrog Monster unless you sacrifice a land. + // You may play an additional land on each of your turns. + // Whenever one or more land cards are put into your graveyard from anywhere, draw a card. + addCard(Zone.HAND, playerA, "The Gitrog Monster", 1); // Creature 6/6 {3}{B}{G} + addCard(Zone.HAND, playerA, "Toxic Deluge", 1); // Sorcery {2}{B} + // (Dryad Arbor isn't a spell, it's affected by summoning sickness, and it has "{T}: Add {G} to your mana pool.") + addCard(Zone.HAND, playerA, "Dryad Arbor", 1); // Land Creature 1/1 + addCard(Zone.HAND, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + // Rags Sorcery {2}{B}{B} + // All creatures get -2/-2 until end of turn. + // Riches Sorcery {5}{U}{U} + // Each opponent chooses a creature he or she controls. You gain control of each of those creatures. + addCard(Zone.GRAVEYARD, playerB, "Rags // Riches", 1); + addCard(Zone.BATTLEFIELD, playerB, "Island", 7); + + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Swamp"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "The Gitrog Monster"); + playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Dryad Arbor"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Riches"); + setChoice(playerA, "The Gitrog Monster"); + + // As an additional cost to cast Toxic Deluge, pay X life. + // All creatures get -X/-X until end of turn. + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Toxic Deluge"); + setChoice(playerA, "X=6"); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerB, "Rags // Riches", 1); + + assertGraveyardCount(playerA, "Toxic Deluge", 1); + assertLife(playerA, 14); + + assertGraveyardCount(playerA, "The Gitrog Monster", 1); + assertGraveyardCount(playerA, "Dryad Arbor", 1); + + assertHandCount(playerB, 1); // 1 drawn in draw of turn 2 + assertHandCount(playerA, 1); // 1 drawn in draw of turn 3 - no card sfro Gitrog + + } }