From 4d335fc396cdc529e1d89e324975417ba70c3483 Mon Sep 17 00:00:00 2001 From: Shaun Hannah Date: Wed, 9 May 2018 19:50:49 -0400 Subject: [PATCH 1/8] Added No Banned List Modern format This is just as the name implied, modern with no banned cards. Why? Because I want to gear up for the SCG-CON's no banned list modern tourney: http://scgcon.starcitygames.com/open.php#prizes Sure I could play in a freeform game, but modern can't compete with vintage cards; so not really a good test case. --- .../src/mage/deck/ModernNoBannedList.java | 56 +++++++++++++++++++ Mage.Server/config/config.xml | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java new file mode 100644 index 0000000000..96a097d821 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java @@ -0,0 +1,56 @@ + +/* +* Copyright 2011 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.deck; + +import java.util.Date; +import java.util.GregorianCalendar; + +import mage.cards.ExpansionSet; +import mage.cards.Sets; +import mage.cards.decks.Constructed; +import mage.constants.SetType; + +/** + * + * @author LevelX2 + */ +public class Modern extends Constructed { + + public Modern() { + super("Constructed - Modern - No Banned List"); + + Date cutoff = new GregorianCalendar(2003, 6, 28).getTime(); // Eight edition release date + for (ExpansionSet set : Sets.getInstance().values()) { + if ((set.getReleaseDate().after(cutoff) || set.getReleaseDate().equals(cutoff)) + && (set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION)) { + setCodes.add(set.getCode()); + } + } + } +} diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 468a2934ac..de0605b1e3 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -150,6 +150,7 @@ + From 755569d9966e50749d214c539244a61ae98c8048 Mon Sep 17 00:00:00 2001 From: Shaun Hannah Date: Thu, 10 May 2018 05:13:02 -0400 Subject: [PATCH 2/8] Fix class name mis-match --- .../src/mage/deck/ModernNoBannedList.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java index 96a097d821..430ff0b455 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ModernNoBannedList.java @@ -40,9 +40,9 @@ import mage.constants.SetType; * * @author LevelX2 */ -public class Modern extends Constructed { +public class ModernNoBannedList extends Constructed { - public Modern() { + public ModernNoBannedList() { super("Constructed - Modern - No Banned List"); Date cutoff = new GregorianCalendar(2003, 6, 28).getTime(); // Eight edition release date From 1c3fea2e3e269316537ebe7e5b81d0b58977a335 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Sun, 13 May 2018 00:23:07 -0400 Subject: [PATCH 3/8] Fix for Herald's Horn's spell reduction Correctly reduces chosen type of controlled spells again after change in last release. As mentioned multiple times in #4895. --- .../effects/common/cost/SpellsCostReductionAllEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java index c66870598c..3f07900238 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java @@ -142,7 +142,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (onlyControlled && abilityToModify.getControllerId().equals(source.getControllerId())) { + if (onlyControlled && !abilityToModify.getControllerId().equals(source.getControllerId())) { return false; } if (abilityToModify instanceof SpellAbility) { From 49c3f94cdbc96f91049c6be4c9ca0698ba62961f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 14 May 2018 22:59:25 -0400 Subject: [PATCH 4/8] added Mage.Verify/mageclient.log to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c07f8d4d29..3d7e99c65e 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ mage.updater.client/target # Mage.Verify Mage.Verify/target +Mage.Verify/mageclient.log Mage.Verify/AllCards.json.zip Mage.Verify/AllSets.json.zip From 08b9f61749bd45900c3fa791a9840feede6cc834 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 15 May 2018 14:31:37 +0200 Subject: [PATCH 5/8] Removed wrong import in TestPlayer.java. --- .../java/org/mage/test/player/TestPlayer.java | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 8970be0c12..4582e497d6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -31,8 +31,6 @@ import java.io.Serializable; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; - -import com.sun.org.apache.xpath.internal.operations.Bool; import mage.MageObject; import mage.MageObjectReference; import mage.ObjectColor; @@ -81,7 +79,6 @@ import mage.target.*; import mage.target.common.*; import org.junit.Assert; import org.junit.Ignore; - import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*; /** @@ -156,7 +153,7 @@ public class TestPlayer implements Player { /** * @param maxCallsWithoutAction max number of priority passes a player may - * have for this test (default = 100) + * have for this test (default = 100) */ public void setMaxCallsWithoutAction(int maxCallsWithoutAction) { this.maxCallsWithoutAction = maxCallsWithoutAction; @@ -751,7 +748,7 @@ public class TestPlayer implements Player { // Loop through players and validate can attack/block this turn UUID defenderId = null; //List - for (Iterator it = actions.iterator(); it.hasNext(); ) { + for (Iterator it = actions.iterator(); it.hasNext();) { PlayerAction action = it.next(); if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) { String command = action.getAction(); @@ -2404,7 +2401,7 @@ public class TestPlayer implements Player { @Override public boolean choose(Outcome outcome, Target target, - UUID sourceId, Game game + UUID sourceId, Game game ) { // needed to call here the TestPlayer because it's overwitten return choose(outcome, target, sourceId, game, null); @@ -2412,7 +2409,7 @@ public class TestPlayer implements Player { @Override public boolean choose(Outcome outcome, Cards cards, - TargetCard target, Game game + TargetCard target, Game game ) { if (!choices.isEmpty()) { for (String choose2 : choices) { @@ -2444,7 +2441,7 @@ public class TestPlayer implements Player { @Override public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.chooseTargetAmount(outcome, target, source, game); } @@ -2457,15 +2454,15 @@ public class TestPlayer implements Player { @Override public boolean choosePile(Outcome outcome, String message, - List pile1, List pile2, - Game game + List pile1, List pile2, + Game game ) { return computerPlayer.choosePile(outcome, message, pile1, pile2, game); } @Override public boolean playMana(Ability ability, ManaCost unpaid, - String promptText, Game game + String promptText, Game game ) { groupsForTargetHandling = null; return computerPlayer.playMana(ability, unpaid, promptText, game); @@ -2479,15 +2476,15 @@ public class TestPlayer implements Player { @Override public UUID chooseBlockerOrder(List blockers, CombatGroup combatGroup, - List blockerOrder, Game game + List blockerOrder, Game game ) { return computerPlayer.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game); } @Override public void assignDamage(int damage, List targets, - String singleTargetName, UUID sourceId, - Game game + String singleTargetName, UUID sourceId, + Game game ) { computerPlayer.assignDamage(damage, targets, singleTargetName, sourceId, game); } @@ -2506,14 +2503,14 @@ public class TestPlayer implements Player { @Override public void pickCard(List cards, Deck deck, - Draft draft + Draft draft ) { computerPlayer.pickCard(cards, deck, draft); } @Override public boolean scry(int value, Ability source, - Game game + Game game ) { // Don't scry at the start of the game. if (game.getTurnNum() == 1 && game.getStep() == null) { @@ -2524,37 +2521,37 @@ public class TestPlayer implements Player { @Override public boolean moveCards(Card card, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(card, toZone, source, game); } @Override public boolean moveCards(Card card, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } @Override public boolean moveCards(Cards cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(cards, toZone, source, game); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(cards, toZone, source, game); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } From e2f22d3bc98db8e16f4343241ff6c608f542dfc0 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 15 May 2018 17:56:55 +0200 Subject: [PATCH 6/8] Reworked some card movement handling (#4866). --- .../src/mage/cards/a/AcademyResearchers.java | 4 +- Mage.Sets/src/mage/cards/a/AccursedWitch.java | 7 +- Mage.Sets/src/mage/cards/a/AllHallowsEve.java | 10 +-- .../src/mage/cards/a/AngelOfGlorysRise.java | 29 +++---- .../src/mage/cards/a/ArachnusSpinner.java | 34 ++++---- .../src/mage/cards/a/AuratouchedMage.java | 26 ++++--- .../src/mage/cards/b/BreakingEntering.java | 8 +- .../src/mage/cards/c/CharmedGriffin.java | 4 +- .../src/mage/cards/c/CollectiveVoyage.java | 10 +-- .../mage/cards/d/DarigaazReincarnated.java | 17 ++-- .../src/mage/cards/d/DarkSupplicant.java | 78 +++++++++---------- Mage.Sets/src/mage/cards/d/DoublingChant.java | 64 ++++++++------- Mage.Sets/src/mage/cards/d/DreadSlaver.java | 12 +-- .../src/mage/cards/d/DruidicSatchel.java | 25 +++--- Mage.Sets/src/mage/cards/e/Evershrike.java | 20 ++--- .../src/mage/cards/g/GateToTheAfterlife.java | 11 ++- .../src/mage/cards/p/PraetorsCounsel.java | 23 +++--- .../effects/common/CreateTokenEffect.java | 6 +- .../main/java/mage/players/PlayerImpl.java | 9 +++ 19 files changed, 199 insertions(+), 198 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AcademyResearchers.java b/Mage.Sets/src/mage/cards/a/AcademyResearchers.java index d57acd4553..965f5c223f 100644 --- a/Mage.Sets/src/mage/cards/a/AcademyResearchers.java +++ b/Mage.Sets/src/mage/cards/a/AcademyResearchers.java @@ -54,7 +54,7 @@ import mage.target.common.TargetCardInHand; public class AcademyResearchers extends CardImpl { public AcademyResearchers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -104,7 +104,7 @@ class AcademyResearchersEffect extends OneShotEffect { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { game.getState().setValue("attachTo:" + auraInHand.getId(), academyResearchers); - auraInHand.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), controller.getId()); + controller.moveCards(auraInHand, Zone.BATTLEFIELD, source, game); if (academyResearchers.addAttachment(auraInHand.getId(), game)) { game.informPlayers(controller.getLogName() + " put " + auraInHand.getLogName() + " on the battlefield attached to " + academyResearchers.getLogName() + '.'); return true; diff --git a/Mage.Sets/src/mage/cards/a/AccursedWitch.java b/Mage.Sets/src/mage/cards/a/AccursedWitch.java index f3fcf89481..c81b3be1ca 100644 --- a/Mage.Sets/src/mage/cards/a/AccursedWitch.java +++ b/Mage.Sets/src/mage/cards/a/AccursedWitch.java @@ -37,10 +37,10 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.keyword.TransformAbility; -import mage.cards.i.InfectiousCurse; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.i.InfectiousCurse; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -55,7 +55,7 @@ import mage.util.CardUtil; public class AccursedWitch extends CardImpl { public AccursedWitch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(4); @@ -106,8 +106,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect { //note: should check for null after game.getCard Card card = game.getCard(source.getSourceId()); if (card != null) { - card.removeFromZone(game, Zone.GRAVEYARD, source.getSourceId()); - card.putOntoBattlefield(game, Zone.BATTLEFIELD, source.getSourceId(), source.getControllerId(), false); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return true; diff --git a/Mage.Sets/src/mage/cards/a/AllHallowsEve.java b/Mage.Sets/src/mage/cards/a/AllHallowsEve.java index ea588cba6b..e79afec154 100644 --- a/Mage.Sets/src/mage/cards/a/AllHallowsEve.java +++ b/Mage.Sets/src/mage/cards/a/AllHallowsEve.java @@ -41,7 +41,7 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; @@ -101,18 +101,12 @@ class AllHallowsEveEffect extends OneShotEffect { allHallowsEve.getCounters(game).removeCounter(CounterType.SCREAM, 1); if (allHallowsEve.getCounters(game).getCount(CounterType.SCREAM) == 0) { allHallowsEve.moveToZone(Zone.GRAVEYARD, source.getId(), game, false); - Cards creatures = new CardsImpl(); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card creatureCard : player.getGraveyard().getCards(new FilterCreatureCard(), game)) { - creatures.add(creatureCard); - } + player.moveCards(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game), Zone.BATTLEFIELD, source, game); } } - for (Card card : creatures.getCards(game)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getId(), card.getOwnerId()); - } } return true; } diff --git a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java index b44b630479..39355c6b02 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java @@ -27,6 +27,8 @@ */ package mage.cards.a; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -44,7 +46,6 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; /** @@ -54,7 +55,7 @@ import mage.players.Player; public class AngelOfGlorysRise extends CardImpl { public AngelOfGlorysRise(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}"); this.subtype.add(SubType.ANGEL); this.power = new MageInt(4); @@ -79,14 +80,6 @@ public class AngelOfGlorysRise extends CardImpl { class AngelOfGlorysRiseEffect extends OneShotEffect { - private static final FilterCreatureCard filterHuman = new FilterCreatureCard(); - private static final FilterCreaturePermanent filterZombie = new FilterCreaturePermanent(); - - static { - filterZombie.add(new SubtypePredicate(SubType.ZOMBIE)); - filterHuman.add(new SubtypePredicate(SubType.HUMAN)); - } - public AngelOfGlorysRiseEffect() { super(Outcome.PutCreatureInPlay); staticText = "Exile all Zombies, then return all Human creature cards from your graveyard to the battlefield"; @@ -103,14 +96,14 @@ class AngelOfGlorysRiseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (Permanent zombie : game.getBattlefield().getActivePermanents(filterZombie, source.getControllerId(), source.getSourceId(), game)) { - zombie.moveToExile(source.getSourceId(), zombie.getName(), source.getSourceId(), game); - } - for (Card human : player.getGraveyard().getCards(filterHuman, game)) { - human.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Set toExile = new HashSet<>(game.getBattlefield() + .getActivePermanents(new FilterCreaturePermanent(SubType.ZOMBIE, "Zombie"), source.getControllerId(), source.getSourceId(), game)); + controller.moveCards(toExile, Zone.EXILED, source, game); + FilterCreatureCard filterHuman = new FilterCreatureCard(); + filterHuman.add(new SubtypePredicate(SubType.HUMAN)); + controller.moveCards(controller.getGraveyard().getCards(filterHuman, game), Zone.GRAVEYARD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/a/ArachnusSpinner.java b/Mage.Sets/src/mage/cards/a/ArachnusSpinner.java index ebd6060424..c9e8c9982a 100644 --- a/Mage.Sets/src/mage/cards/a/ArachnusSpinner.java +++ b/Mage.Sets/src/mage/cards/a/ArachnusSpinner.java @@ -69,7 +69,7 @@ public class ArachnusSpinner extends CardImpl { } public ArachnusSpinner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); this.subtype.add(SubType.SPIDER); this.power = new MageInt(5); @@ -98,8 +98,10 @@ public class ArachnusSpinner extends CardImpl { class ArachnusSpinnerEffect extends OneShotEffect { public ArachnusSpinnerEffect() { - super(Outcome.UnboostCreature); - this.staticText = "Search your graveyard and/or library for a card named Arachnus Web and put it onto the battlefield attached to target creature. If you search your library this way, shuffle it"; + super(Outcome.PutCardInPlay); + this.staticText = "Search your graveyard and/or library for a card named Arachnus Web " + + "and put it onto the battlefield attached to target creature. " + + "If you search your library this way, shuffle it"; } public ArachnusSpinnerEffect(final ArachnusSpinnerEffect effect) { @@ -113,8 +115,8 @@ class ArachnusSpinnerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } @@ -122,34 +124,28 @@ class ArachnusSpinnerEffect extends OneShotEffect { filter.add(new NamePredicate("Arachnus Web")); Card card = null; - Zone zone = null; - if (player.chooseUse(Outcome.Neutral, "Search your graveyard for Arachnus Web?", source, game)) { + if (controller.chooseUse(Outcome.Neutral, "Search your graveyard for Arachnus Web?", source, game)) { TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); - if (player.choose(Outcome.PutCardInPlay, player.getGraveyard(), target, game)) { + if (controller.choose(Outcome.PutCardInPlay, controller.getGraveyard(), target, game)) { card = game.getCard(target.getFirstTarget()); - if (card != null) { - zone = Zone.GRAVEYARD; - } } } if (card == null) { TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { card = game.getCard(target.getFirstTarget()); - if (card != null) { - zone = Zone.LIBRARY; - } } - player.shuffleLibrary(source, game); + controller.shuffleLibrary(source, game); } if (card != null) { Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { game.getState().setValue("attachTo:" + card.getId(), permanent.getId()); - card.putOntoBattlefield(game, zone, source.getSourceId(), source.getControllerId()); - return permanent.addAttachment(card.getId(), game); + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + permanent.addAttachment(card.getId(), game); // shouldn't this be done automatically by the logic using the "attachTo:" calue? + } } } - return false; + return true; } } diff --git a/Mage.Sets/src/mage/cards/a/AuratouchedMage.java b/Mage.Sets/src/mage/cards/a/AuratouchedMage.java index 5db38557b0..5c0dee373c 100644 --- a/Mage.Sets/src/mage/cards/a/AuratouchedMage.java +++ b/Mage.Sets/src/mage/cards/a/AuratouchedMage.java @@ -88,28 +88,32 @@ class AuratouchedMageEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent auratouchedMage = game.getPermanentOrLKIBattlefield(source.getSourceId()); //must be LKI to resolve - if (controller != null && auratouchedMage != null) { - FilterCard filter = new FilterCard("aura that could enchant " + auratouchedMage.getName()); + + if (controller != null) { + FilterCard filter = new FilterCard("aura that could enchant " + source.getSourceObject(game).getName()); filter.add(new SubtypePredicate(SubType.AURA)); - filter.add(new AuraCardCanAttachToLKIPermanentId(auratouchedMage.getId())); + filter.add(new AuraCardCanAttachToLKIPermanentId(source.getSourceId())); TargetCardInLibrary target = new TargetCardInLibrary(filter); target.setNotTarget(true); if (controller.searchLibrary(target, game)) { if (target.getFirstTarget() != null) { Card aura = game.getCard(target.getFirstTarget()); - if (game.getBattlefield().containsPermanent(auratouchedMage.getId())) { //verify that it is still on the battlefield + Permanent auratouchedMage = source.getSourcePermanentIfItStillExists(game); + if (aura != null && auratouchedMage != null + && game.getState().getZoneChangeCounter(source.getSourceId()) == source.getSourceObjectZoneChangeCounter()) { game.getState().setValue("attachTo:" + aura.getId(), auratouchedMage); - aura.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), controller.getId()); - return auratouchedMage.addAttachment(aura.getId(), game); + if (controller.moveCards(aura, Zone.BATTLEFIELD, source, game)) { + auratouchedMage.addAttachment(aura.getId(), game); + } + } else { + Cards auraRevealed = new CardsImpl(aura); + controller.revealCards(source, auraRevealed, game); + controller.moveCards(aura, Zone.HAND, source, game); } - Cards auraRevealed = new CardsImpl(); - auraRevealed.add(aura); - controller.revealCards(auratouchedMage.getName(), auraRevealed, game); - controller.putInHand(aura, game); } } controller.shuffleLibrary(source, game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/b/BreakingEntering.java b/Mage.Sets/src/mage/cards/b/BreakingEntering.java index 9779e83afc..9a3756f816 100644 --- a/Mage.Sets/src/mage/cards/b/BreakingEntering.java +++ b/Mage.Sets/src/mage/cards/b/BreakingEntering.java @@ -94,15 +94,15 @@ class EnteringReturnFromGraveyardToBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Target target = new TargetCardInGraveyard(new FilterCreatureCard()); target.setNotTarget(true); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && player.chooseTarget(outcome, target, source, game)) { + && controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/c/CharmedGriffin.java b/Mage.Sets/src/mage/cards/c/CharmedGriffin.java index c596f29aa6..93e724de4f 100644 --- a/Mage.Sets/src/mage/cards/c/CharmedGriffin.java +++ b/Mage.Sets/src/mage/cards/c/CharmedGriffin.java @@ -37,8 +37,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterArtifactOrEnchantmentCard; import mage.game.Game; @@ -105,7 +105,7 @@ class CharmedGriffinEffect extends OneShotEffect { && player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java b/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java index 88728d6027..bd26b4b556 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java @@ -33,9 +33,9 @@ import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -103,13 +103,7 @@ class CollectiveVoyageEffect extends OneShotEffect { if (player != null) { TargetCardInLibrary target = new TargetCardInLibrary(0, xSum, StaticFilters.FILTER_BASIC_LAND_CARD); if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); - } - - } + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); player.shuffleLibrary(source, game); } diff --git a/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java b/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java index 12d2e82177..c381ca3fa5 100644 --- a/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java +++ b/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java @@ -29,6 +29,7 @@ package mage.cards.d; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -181,14 +182,18 @@ class DarigaazReincarnatedReturnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Card card = game.getCard(source.getSourceId()); - if (player == null || card == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - new RemoveCounterSourceEffect(CounterType.EGG.createInstance()).apply(game, source); - if (card.getCounters(game).getCount(CounterType.EGG) == 0) { - return card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), player.getId()); + MageObject sourceObject = source.getSourceObjectIfItStillExists(game); + if (sourceObject != null && sourceObject instanceof Card) { + Card card = (Card) sourceObject; + new RemoveCounterSourceEffect(CounterType.EGG.createInstance()).apply(game, source); + if (card.getCounters(game).getCount(CounterType.EGG) == 0) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/d/DarkSupplicant.java b/Mage.Sets/src/mage/cards/d/DarkSupplicant.java index 34d342b90d..11ea6f0ef4 100644 --- a/Mage.Sets/src/mage/cards/d/DarkSupplicant.java +++ b/Mage.Sets/src/mage/cards/d/DarkSupplicant.java @@ -27,7 +27,6 @@ */ package mage.cards.d; -import java.util.List; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -38,7 +37,6 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -49,7 +47,9 @@ import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; +import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetControlledPermanent; /** @@ -65,14 +65,14 @@ public class DarkSupplicant extends CardImpl { } public DarkSupplicant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); this.toughness = new MageInt(1); - // {tap}, Sacrifice three Clerics: Search your graveyard, hand, and/or library for a card named Scion of Darkness and put it onto the battlefield. If you search your library this way, shuffle it. + // {T}, Sacrifice three Clerics: Search your graveyard, hand, and/or library for a card named Scion of Darkness and put it onto the battlefield. If you search your library this way, shuffle it. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DarkSupplicantEffect(), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, true))); this.addAbility(ability); @@ -91,7 +91,7 @@ public class DarkSupplicant extends CardImpl { class DarkSupplicantEffect extends OneShotEffect { public DarkSupplicantEffect() { - super(Outcome.Benefit); + super(Outcome.PutCardInPlay); this.staticText = "Search your graveyard, hand, and/or library for a card named Scion of Darkness and put it onto the battlefield. If you search your library this way, shuffle it"; } @@ -106,51 +106,49 @@ class DarkSupplicantEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); FilterCard filter = new FilterCard("card named Scion of Darkness"); filter.add(new NamePredicate("Scion of Darkness")); - TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player == null) { + if (controller == null) { return false; } - // Library check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your library for Scion of Darkness?", source, game)) { - if (player.searchLibrary(target, game)) { - if (!target.getTargets().isEmpty()) { - for (UUID cardId : (List) target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - if (card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId())) { - return true; - } - } - } - } - } - player.shuffleLibrary(source, game); - } + Card selectedCard = null; // Graveyard check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your graveyard for Scion of Darkness?", source, game)) { - Cards graveyard = player.getGraveyard().copy(); - for (UUID card : graveyard) { - Card checkCard = game.getCard(card); - if (checkCard.getName().equals("Scion of Darkness")) { - checkCard.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - return true; - } + if (controller.chooseUse(Outcome.Benefit, "Do you want to search your graveyard for Scion of Darkness?", source, game)) { + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(1, 1, filter, true); + if (controller.choose(outcome, controller.getGraveyard(), target, game)) { + selectedCard = game.getCard(target.getFirstTarget()); } } // Hand check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your hand for Scion of Darkness?", source, game)) { - Cards hand = player.getHand().copy(); - for (UUID card : hand) { - Card checkCard = game.getCard(card); - if (checkCard.getName().equals("Scion of Darkness")) { - checkCard.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - return true; + if (selectedCard == null + && controller.chooseUse(Outcome.Benefit, "Do you want to search your hand for Scion of Darkness?", source, game)) { + TargetCardInHand target = new TargetCardInHand(0, 1, filter); + if (controller.choose(Outcome.PutCardInPlay, controller.getHand(), target, game)) { + if (!target.getTargets().isEmpty()) { + selectedCard = game.getCard(target.getFirstTarget()); } } } - return false; + // Library check + boolean librarySearched = false; + if (selectedCard == null + && controller.chooseUse(Outcome.Benefit, "Do you want to search your library for Scion of Darkness?", source, game)) { + librarySearched = true; + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + if (controller.searchLibrary(target, game)) { + if (!target.getTargets().isEmpty()) { + selectedCard = game.getCard(target.getFirstTarget()); + } + } + + } + if (selectedCard != null) { + controller.moveCards(selectedCard, Zone.BATTLEFIELD, source, game); + } + if (librarySearched) { + controller.shuffleLibrary(source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DoublingChant.java b/Mage.Sets/src/mage/cards/d/DoublingChant.java index 61f724ed0d..7e1cb66810 100644 --- a/Mage.Sets/src/mage/cards/d/DoublingChant.java +++ b/Mage.Sets/src/mage/cards/d/DoublingChant.java @@ -28,7 +28,9 @@ package mage.cards.d; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -40,6 +42,8 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardIdPredicate; import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; import mage.game.permanent.Permanent; @@ -55,6 +59,8 @@ public class DoublingChant extends CardImpl { public DoublingChant(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}"); + // For each creature you control, you may search your library for a creature card with the same name as that creature. + // Put those cards onto the battlefield, then shuffle your library. this.getSpellAbility().addEffect(new DoublingChantEffect()); } @@ -86,41 +92,43 @@ class DoublingChantEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - List chosenCards = new ArrayList<>(); - List namesFiltered = new ArrayList<>(); - - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } + Set chosenCards = new HashSet<>(); List creatures = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game); - for (Permanent creature : creatures) { - final String creatureName = creature.getName(); - if (!namesFiltered.contains(creatureName)) { - StringBuilder sb = new StringBuilder(); - sb.append("Search for ").append(creatureName).append(" in your library?"); - - if (player.chooseUse(Outcome.PutCreatureInPlay, sb.toString(), source, game)) { - FilterCreatureCard filter = new FilterCreatureCard("creature card named" + creatureName); - filter.add(new NamePredicate(creatureName)); - TargetCardInLibrary target = new TargetCardInLibrary(filter); - - if (player.searchLibrary(target, game)) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); - if (card != null) { - chosenCards.add(card); - } - } - } else { - namesFiltered.add(creatureName); - } + if (creatures.isEmpty()) { + //9/22/2011: If you control no creatures when Doubling Chant resolves, you may still search your library and you must shuffle your library. + if (controller.chooseUse(Outcome.PutCreatureInPlay, "Search in your library?", source, game)) { + FilterCreatureCard filter = new FilterCreatureCard("nothing (no valid card available)"); + filter.add(new NamePredicate("creatureName")); + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + controller.searchLibrary(target, game); } } + for (Permanent creature : creatures) { + final String creatureName = creature.getName(); + List uuidPredicates = new ArrayList<>(); + if (controller.chooseUse(Outcome.PutCreatureInPlay, "Search for " + creatureName + " in your library?", source, game)) { + FilterCreatureCard filter = new FilterCreatureCard("creature card named " + creatureName); + filter.add(new NamePredicate(creatureName)); + if (!uuidPredicates.isEmpty()) { // Prevent to select a card twice + filter.add(Predicates.not(Predicates.or(uuidPredicates))); + } + TargetCardInLibrary target = new TargetCardInLibrary(filter); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + if (card != null) { + chosenCards.add(card); + uuidPredicates.add(new CardIdPredicate(card.getId())); + } + } + } - for (Card card : chosenCards) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); } - player.shuffleLibrary(source, game); + controller.moveCards(chosenCards, Zone.BATTLEFIELD, source, game); + controller.shuffleLibrary(source, game); return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DreadSlaver.java b/Mage.Sets/src/mage/cards/d/DreadSlaver.java index ce4f156e90..27028db67b 100644 --- a/Mage.Sets/src/mage/cards/d/DreadSlaver.java +++ b/Mage.Sets/src/mage/cards/d/DreadSlaver.java @@ -39,17 +39,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; +import mage.players.Player; import mage.target.targetpointer.FixedTarget; - - /** * @author noxx */ public class DreadSlaver extends CardImpl { public DreadSlaver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.HORROR); @@ -88,10 +87,13 @@ class DreadSlaverEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } Card card = game.getCard(targetPointer.getFirst(game, source)); if (card != null) { - Zone currentZone = game.getState().getZone(card.getId()); - if (card.putOntoBattlefield(game, currentZone, source.getSourceId(), source.getControllerId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { ContinuousEffect effect = new BecomesBlackZombieAdditionEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/d/DruidicSatchel.java b/Mage.Sets/src/mage/cards/d/DruidicSatchel.java index 2ab51a3e61..d2ffd5a27a 100644 --- a/Mage.Sets/src/mage/cards/d/DruidicSatchel.java +++ b/Mage.Sets/src/mage/cards/d/DruidicSatchel.java @@ -39,8 +39,6 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.token.SaprolingToken; -import mage.game.permanent.token.TokenImpl; -import mage.game.permanent.token.Token; import mage.players.Player; /** @@ -80,27 +78,24 @@ class DruidicSatchelEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Card card = player.getLibrary().getFromTop(game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Card card = controller.getLibrary().getFromTop(game); if (card != null) { + controller.revealCards(source, new CardsImpl(card), game); if (card.isCreature()) { - Token token = new SaprolingToken(); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + new SaprolingToken().putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); } if (card.isLand()) { - player.getLibrary().getCard(card.getId(), game); - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } if (!card.isCreature() && !card.isLand()) { - player.gainLife(2, game, source); + controller.gainLife(2, game, source); } - - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Druidic Satchel", cards, game); - return true; } - return false; + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/e/Evershrike.java b/Mage.Sets/src/mage/cards/e/Evershrike.java index 6a17ed0623..586d1b8a2e 100644 --- a/Mage.Sets/src/mage/cards/e/Evershrike.java +++ b/Mage.Sets/src/mage/cards/e/Evershrike.java @@ -99,37 +99,37 @@ class EvershrikeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean exiled = true; Card evershrikeCard = game.getCard(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); - int xAmount = source.getManaCostsToPay().getX() + 1; - if (evershrikeCard != null) { + if (controller != null && evershrikeCard != null) { if (evershrikeCard.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false)) { + int xAmount = source.getManaCostsToPay().getX() + 1; Permanent evershrikePermanent = game.getPermanent(source.getSourceId()); if (evershrikePermanent == null) { return false; } + boolean exileSource = true; FilterCard filterAuraCard = new FilterCard("Aura card with converted mana cost X or less from your hand"); filterAuraCard.add(new CardTypePredicate(CardType.ENCHANTMENT)); filterAuraCard.add(new SubtypePredicate(SubType.AURA)); filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId())); filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xAmount)); int count = controller.getHand().count(filterAuraCard, game); - while (controller.canRespond() && count > 0 && controller.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", source, game)) { + if (count > 0 && controller.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto " + evershrikeCard.getIdName() + "?", source, game)) { TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard); if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) { Card aura = game.getCard(targetAura.getFirstTarget()); if (aura != null) { game.getState().setValue("attachTo:" + aura.getId(), evershrikePermanent); - aura.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), controller.getId()); - evershrikePermanent.addAttachment(aura.getId(), game); - exiled = false; - count = controller.getHand().count(filterAuraCard, game); + if (controller.moveCards(aura, Zone.BATTLEFIELD, source, game)) { + evershrikePermanent.addAttachment(aura.getId(), game); + } + exileSource = false; } } } - if (exiled) { - return evershrikePermanent.moveToExile(source.getSourceId(), "Evershrike Exile", source.getSourceId(), game); + if (exileSource) { + controller.moveCards(evershrikeCard, Zone.EXILED, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java index 1f1879647e..4b8cbaf2c5 100644 --- a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java +++ b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java @@ -132,20 +132,22 @@ class GateToTheAfterlifeEffect extends OneShotEffect { Card card = null; // Graveyard check if (controller.chooseUse(Outcome.Benefit, "Do you want to search your graveyard for " + cardName + "?", source, game)) { - TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); - if (controller.choose(Outcome.PutCardInPlay, controller.getGraveyard(), target, game)) { + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(1, 1, filter, true); + if (controller.choose(outcome, controller.getGraveyard(), target, game)) { card = game.getCard(target.getFirstTarget()); } } // Hand check if (card == null && controller.chooseUse(Outcome.Benefit, "Do you want to search your hand for " + cardName + "?", source, game)) { - TargetCardInHand target = new TargetCardInHand(filter); + TargetCardInHand target = new TargetCardInHand(0, 1, filter); if (controller.choose(Outcome.PutCardInPlay, controller.getHand(), target, game)) { card = game.getCard(target.getFirstTarget()); } } // Library check + boolean librarySearched = false; if (card == null && controller.chooseUse(Outcome.Benefit, "Do you want to search your library for " + cardName + "?", source, game)) { + librarySearched = true; TargetCardInLibrary target = new TargetCardInLibrary(filter); if (controller.searchLibrary(target, game)) { card = game.getCard(target.getFirstTarget()); @@ -155,6 +157,9 @@ class GateToTheAfterlifeEffect extends OneShotEffect { if (card != null) { controller.moveCards(card, Zone.BATTLEFIELD, source, game); } + if (librarySearched) { + controller.shuffleLibrary(source, game); + } return true; } } diff --git a/Mage.Sets/src/mage/cards/p/PraetorsCounsel.java b/Mage.Sets/src/mage/cards/p/PraetorsCounsel.java index 10ac47cf8f..fc23566e4c 100644 --- a/Mage.Sets/src/mage/cards/p/PraetorsCounsel.java +++ b/Mage.Sets/src/mage/cards/p/PraetorsCounsel.java @@ -1,16 +1,16 @@ /* * Copyright 2011 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,7 +20,7 @@ * 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. @@ -33,12 +33,12 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect.HandSizeModification; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -49,8 +49,9 @@ import mage.players.Player; public class PraetorsCounsel extends CardImpl { public PraetorsCounsel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{G}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}{G}{G}"); + // Return all cards from your graveyard to your hand. Exile Praetor's Counsel. You have no maximum hand size for the rest of the game. this.getSpellAbility().addEffect(new PraetorsCounselEffect()); this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); this.getSpellAbility().addEffect(new MaximumHandSizeControllerEffect(Integer.MAX_VALUE, Duration.EndOfGame, HandSizeModification.SET)); @@ -85,11 +86,11 @@ class PraetorsCounselEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - for (Card card: player.getGraveyard().getCards(game)) { - player.putInHand(card, game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.moveCards(controller.getGraveyard(), Zone.HAND, source, game); + return true; } - player.getGraveyard().clear(); return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 46b82048c0..dc6a49c31c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -27,6 +27,8 @@ */ package mage.abilities.effects.common; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; @@ -37,14 +39,10 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.Token; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; -import java.util.ArrayList; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 6a0524ddc6..a2be32c19e 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -655,6 +655,15 @@ public abstract class PlayerImpl implements Player, Serializable { } } + /** + * Don't use this in normal card code, it's for more internal use. Always + * use the [Player].moveCards methods if possible for card movement of card + * code. + * + * @param card + * @param game + * @return + */ @Override public boolean putInHand(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { From 30922924f5c9b62bf6f7c1f0a98b82ae98f810f6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 15 May 2018 20:22:05 -0400 Subject: [PATCH 7/8] added TheElk801 as a dev --- Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java b/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java index 0449487c11..e2cddbaa2f 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java @@ -86,7 +86,7 @@ public class AboutDialog extends MageDialog { jLabel2.setText("Courtesy: BetaSteward@googlemail.com. Site: http://XMage.de/"); jLabel3.setText("Devs: BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, Jeff, Plopman, dustinconrad, emerald000,"); - jLabel4.setText("fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox, drmDev, spjspj, L_J, JayDi85."); + jLabel4.setText("fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox, drmDev, spjspj, TheElk801, L_J, JayDi85."); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); From 36e46d63637607a9815c8ce0ebfabbe0e6b79584 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 16 May 2018 09:04:34 -0400 Subject: [PATCH 8/8] fixed Azcanta, the Sunken Ruin not allowing players to fail to find --- Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java index 84ba6fbd28..07bf73bf34 100644 --- a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java +++ b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java @@ -71,8 +71,13 @@ public class AzcantaTheSunkenRuin extends CardImpl { this.addAbility(new BlueManaAbility()); // {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new LookLibraryAndPickControllerEffect(new StaticValue(4), false, new StaticValue(1), filter, false), new ManaCostsImpl<>("{2}{U}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new LookLibraryAndPickControllerEffect( + new StaticValue(4), false, new StaticValue(1), + filter, Zone.LIBRARY, false, true, true + ), new ManaCostsImpl<>("{2}{U}") + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); }