diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index 291f53a9c1d..91324908844 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -45,7 +45,6 @@ import java.io.InputStreamReader; import java.io.Writer; import java.net.InetSocketAddress; import java.net.Proxy; -import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.UnknownHostException; @@ -392,12 +391,7 @@ public class ConnectDialog extends MageDialog { connection.setUsername(this.txtUserName.getText().trim()); connection.setPassword(this.txtPassword.getText().trim()); connection.setForceDBComparison(this.chkForceUpdateDB.isSelected()); - String allMAC = ""; - try { - allMAC = connection.getMAC(); - } catch (SocketException ex) { - } - connection.setUserIdStr(System.getProperty("user.name") + ":" + System.getProperty("os.name") + ":" + MagePreferences.getUserNames() + ":" + allMAC); + connection.setUserIdStr(System.getProperty("user.name") + ':' + MagePreferences.getUserNames()); MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor) cbFlag.getEditor()).getImageItem()); PreferencesDialog.setProxyInformation(connection); diff --git a/Mage.Common/src/mage/remote/Connection.java b/Mage.Common/src/mage/remote/Connection.java index 855404ec87f..a5cac723360 100644 --- a/Mage.Common/src/mage/remote/Connection.java +++ b/Mage.Common/src/mage/remote/Connection.java @@ -258,24 +258,6 @@ public class Connection { return null; } - public static String getMAC() throws SocketException { - StringBuilder allMACs = new StringBuilder(); - for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) { - NetworkInterface iface = interfaces.nextElement(); - byte[] mac = iface.getHardwareAddress(); - - if (mac != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < mac.length; i++) { - sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); - } - sb.append(';'); - allMACs.append(sb.toString()); - } - } - return allMACs.toString(); - } - public void setUserData(UserData userData) { this.userData = userData; } diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index f01adb59ae9..a96129aa3b0 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -222,45 +222,47 @@ public class Session { ); } - Optional selectUser = UserManager.instance.createUser(userName, host, authorizedUser); - boolean reconnect = false; - if (!selectUser.isPresent()) { // user already exists - selectUser = UserManager.instance.getUserByName(userName); - if (selectUser.isPresent()) { - User user = selectUser.get(); - // If authentication is not activated, check the identity using IP address. - if (ConfigSettings.instance.isAuthenticationActivated() || user.getHost().equals(host)) { - user.updateLastActivity(null); // minimizes possible expiration - this.userId = user.getId(); - if (user.getSessionId().isEmpty()) { - logger.info("Reconnecting session for " + userName); - reconnect = true; - } else { - //disconnect previous session - logger.info("Disconnecting another user instance: " + userName); - SessionManager.instance.disconnect(user.getSessionId(), DisconnectReason.ConnectingOtherInstance); - } - } else { - return "User name " + userName + " already in use (or your IP address changed)"; - } - } - } + } + } + Optional selectUser = UserManager.instance.createUser(userName, host, authorizedUser); + boolean reconnect = false; + if (!selectUser.isPresent()) { // user already exists + selectUser = UserManager.instance.getUserByName(userName); + if (selectUser.isPresent()) { User user = selectUser.get(); - if (!UserManager.instance.connectToSession(sessionId, user.getId())) { - return "Error connecting " + userName; - } - this.userId = user.getId(); - if (reconnect) { // must be connected to receive the message - Optional room = GamesRoomManager.instance.getRoom(GamesRoomManager.instance.getMainRoomId()); - if (!room.isPresent()) { - logger.error("main room not found"); - return null; + // If authentication is not activated, check the identity using IP address. + if (ConfigSettings.instance.isAuthenticationActivated() || user.getHost().equals(host)) { + user.updateLastActivity(null); // minimizes possible expiration + this.userId = user.getId(); + if (user.getSessionId().isEmpty()) { + logger.info("Reconnecting session for " + userName); + reconnect = true; + } else { + //disconnect previous session + logger.info("Disconnecting another user instance: " + userName); + SessionManager.instance.disconnect(user.getSessionId(), DisconnectReason.ConnectingOtherInstance); } - ChatManager.instance.joinChat(room.get().getChatId(), userId); - ChatManager.instance.sendReconnectMessage(userId); + } else { + return "User name " + userName + " already in use (or your IP address changed)"; } } } + User user = selectUser.get(); + if (!UserManager.instance.connectToSession(sessionId, user.getId())) { + return "Error connecting " + userName; + } + this.userId = user.getId(); + if (reconnect) { // must be connected to receive the message + Optional room = GamesRoomManager.instance.getRoom(GamesRoomManager.instance.getMainRoomId()); + if (!room.isPresent()) { + logger.error("main room not found"); + return null; + } + ChatManager.instance.joinChat(room.get().getChatId(), userId); + ChatManager.instance.sendReconnectMessage(userId); + } + + return null; } diff --git a/Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java b/Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java new file mode 100644 index 00000000000..fb94ae39d7e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java @@ -0,0 +1,141 @@ +/* + * 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.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class AzoriusAEthermage extends CardImpl { + + private static final String rule = "Whenever a permanent is returned to your hand, "; + + public AzoriusAEthermage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever a permanent is returned to your hand, you may pay {1}. If you do, draw a card. + Effect effect = new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}")); + this.addAbility(new AzoriusAEthermageAbility(Zone.BATTLEFIELD, Zone.BATTLEFIELD, Zone.HAND, effect, new FilterPermanent(), rule, true)); + } + + public AzoriusAEthermage(final AzoriusAEthermage card) { + super(card); + } + + @Override + public AzoriusAEthermage copy() { + return new AzoriusAEthermage(this); + } +} + +class AzoriusAEthermageAbility extends TriggeredAbilityImpl { + + protected FilterPermanent filter; + protected Zone fromZone; + protected Zone toZone; + protected String rule; + + public AzoriusAEthermageAbility(Zone zone, Zone fromZone, Zone toZone, Effect effect, FilterPermanent filter, String rule, boolean optional) { + super(zone, effect, optional); + this.fromZone = fromZone; + this.toZone = toZone; + this.rule = rule; + this.filter = filter; + } + + public AzoriusAEthermageAbility(final AzoriusAEthermageAbility ability) { + super(ability); + this.fromZone = ability.fromZone; + this.toZone = ability.toZone; + this.rule = ability.rule; + this.filter = ability.filter; + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if ((fromZone == null || zEvent.getFromZone() == fromZone) + && (toZone == null || zEvent.getToZone() == toZone)) { + Permanent permanentThatMoved = null; + if (zEvent.getTarget() != null) { + permanentThatMoved = zEvent.getTarget(); + } + if (permanentThatMoved != null + && filter.match(permanentThatMoved, sourceId, controllerId, game) + && zEvent.getPlayerId() == controllerId) { //The controller's hand is where the permanent moved to. + return true; + } + } + return false; + } + + @Override + public String getRule() { + return rule + super.getRule(); + } + + @Override + public AzoriusAEthermageAbility copy() { + return new AzoriusAEthermageAbility(this); + } + + public Zone getFromZone() { + return fromZone; + } + + public Zone getToZone() { + return toZone; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GoblinGrenade.java b/Mage.Sets/src/mage/cards/g/GoblinGrenade.java index f2cdde9fe16..1c0a900a253 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinGrenade.java +++ b/Mage.Sets/src/mage/cards/g/GoblinGrenade.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.g; import java.util.UUID; @@ -35,9 +34,9 @@ import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreatureOrPlayer; /** @@ -45,16 +44,16 @@ import mage.target.common.TargetCreatureOrPlayer; */ public class GoblinGrenade extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Goblin"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Goblin"); static { filter.add(new SubtypePredicate("Goblin")); } public GoblinGrenade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); this.getSpellAbility().addEffect(new DamageTargetEffect(5)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/cards/s/Spellshift.java b/Mage.Sets/src/mage/cards/s/Spellshift.java index a58475d546f..ea167b19758 100644 --- a/Mage.Sets/src/mage/cards/s/Spellshift.java +++ b/Mage.Sets/src/mage/cards/s/Spellshift.java @@ -115,6 +115,7 @@ class SpellshiftEffect extends OneShotEffect { library.addAll(cards.getCards(game), game); } } + player.shuffleLibrary(source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index 19ce21b1677..3362ed00ac2 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -1,210 +1,211 @@ -/* -* 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.sets; - -import mage.cards.ExpansionSet; -import mage.constants.SetType; - -import mage.constants.Rarity; - -/** - * Created by IntelliJ IDEA. User: Loki Date: 20.12.10 Time: 21:40 - */ -public class Dissension extends ExpansionSet { - - private static final Dissension instance = new Dissension(); - - public static Dissension getInstance() { - return instance; - } - - private Dissension() { - super("Dissension", "DIS", ExpansionSet.buildDate(2006, 4, 5), SetType.EXPANSION); - this.blockName = "Ravnica"; - this.parentSet = RavnicaCityOfGuilds.getInstance(); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Aethermage's Touch", 101, Rarity.RARE, mage.cards.a.AethermagesTouch.class)); - cards.add(new SetCardInfo("Anthem of Rakdos", 102, Rarity.RARE, mage.cards.a.AnthemOfRakdos.class)); - cards.add(new SetCardInfo("Aquastrand Spider", 80, Rarity.COMMON, mage.cards.a.AquastrandSpider.class)); - cards.add(new SetCardInfo("Assault Zeppelid", 103, Rarity.COMMON, mage.cards.a.AssaultZeppelid.class)); - cards.add(new SetCardInfo("Aurora Eidolon", 1, Rarity.COMMON, mage.cards.a.AuroraEidolon.class)); - cards.add(new SetCardInfo("Avatar of Discord", 140, Rarity.RARE, mage.cards.a.AvatarOfDiscord.class)); - cards.add(new SetCardInfo("Azorius Chancery", 170, Rarity.COMMON, mage.cards.a.AzoriusChancery.class)); - cards.add(new SetCardInfo("Azorius First-Wing", 105, Rarity.COMMON, mage.cards.a.AzoriusFirstWing.class)); - cards.add(new SetCardInfo("Azorius Guildmage", 141, Rarity.UNCOMMON, mage.cards.a.AzoriusGuildmage.class)); - cards.add(new SetCardInfo("Azorius Herald", 2, Rarity.UNCOMMON, mage.cards.a.AzoriusHerald.class)); - cards.add(new SetCardInfo("Azorius Signet", 159, Rarity.COMMON, mage.cards.a.AzoriusSignet.class)); - cards.add(new SetCardInfo("Beacon Hawk", 3, Rarity.COMMON, mage.cards.b.BeaconHawk.class)); - cards.add(new SetCardInfo("Biomantic Mastery", 142, Rarity.RARE, mage.cards.b.BiomanticMastery.class)); - cards.add(new SetCardInfo("Blessing of the Nephilim", 4, Rarity.UNCOMMON, mage.cards.b.BlessingOfTheNephilim.class)); - cards.add(new SetCardInfo("Blood Crypt", 171, Rarity.RARE, mage.cards.b.BloodCrypt.class)); - cards.add(new SetCardInfo("Bond of Agony", 38, Rarity.UNCOMMON, mage.cards.b.BondOfAgony.class)); - cards.add(new SetCardInfo("Bound // Determined", 149, Rarity.RARE, mage.cards.b.BoundDetermined.class)); - cards.add(new SetCardInfo("Brain Pry", 39, Rarity.UNCOMMON, mage.cards.b.BrainPry.class)); - cards.add(new SetCardInfo("Breeding Pool", 172, Rarity.RARE, mage.cards.b.BreedingPool.class)); - cards.add(new SetCardInfo("Cackling Flames", 59, Rarity.COMMON, mage.cards.c.CacklingFlames.class)); - cards.add(new SetCardInfo("Carom", 6, Rarity.COMMON, mage.cards.c.Carom.class)); - cards.add(new SetCardInfo("Celestial Ancient", 7, Rarity.RARE, mage.cards.c.CelestialAncient.class)); - cards.add(new SetCardInfo("Coiling Oracle", 107, Rarity.COMMON, mage.cards.c.CoilingOracle.class)); - cards.add(new SetCardInfo("Condemn", 8, Rarity.UNCOMMON, mage.cards.c.Condemn.class)); - cards.add(new SetCardInfo("Court Hussar", 22, Rarity.UNCOMMON, mage.cards.c.CourtHussar.class)); - cards.add(new SetCardInfo("Crime // Punishment", 150, Rarity.RARE, mage.cards.c.CrimePunishment.class)); - cards.add(new SetCardInfo("Crypt Champion", 40, Rarity.UNCOMMON, mage.cards.c.CryptChampion.class)); - cards.add(new SetCardInfo("Cytoplast Manipulator", 23, Rarity.RARE, mage.cards.c.CytoplastManipulator.class)); - cards.add(new SetCardInfo("Cytoplast Root-Kin", 81, Rarity.RARE, mage.cards.c.CytoplastRootKin.class)); - cards.add(new SetCardInfo("Cytospawn Shambler", 82, Rarity.COMMON, mage.cards.c.CytospawnShambler.class)); - cards.add(new SetCardInfo("Delirium Skeins", 41, Rarity.COMMON, mage.cards.d.DeliriumSkeins.class)); - cards.add(new SetCardInfo("Demonfire", 60, Rarity.RARE, mage.cards.d.Demonfire.class)); - cards.add(new SetCardInfo("Demon's Jester", 42, Rarity.COMMON, mage.cards.d.DemonsJester.class)); - cards.add(new SetCardInfo("Dovescape", 143, Rarity.RARE, mage.cards.d.Dovescape.class)); - cards.add(new SetCardInfo("Dread Slag", 109, Rarity.RARE, mage.cards.d.DreadSlag.class)); - cards.add(new SetCardInfo("Drekavac", 43, Rarity.UNCOMMON, mage.cards.d.Drekavac.class)); - cards.add(new SetCardInfo("Enemy of the Guildpact", 44, Rarity.COMMON, mage.cards.e.EnemyOfTheGuildpact.class)); - cards.add(new SetCardInfo("Enigma Eidolon", 24, Rarity.COMMON, mage.cards.e.EnigmaEidolon.class)); - cards.add(new SetCardInfo("Entropic Eidolon", 45, Rarity.COMMON, mage.cards.e.EntropicEidolon.class)); - cards.add(new SetCardInfo("Evolution Vat", 161, Rarity.RARE, mage.cards.e.EvolutionVat.class)); - cards.add(new SetCardInfo("Experiment Kraj", 110, Rarity.RARE, mage.cards.e.ExperimentKraj.class)); - cards.add(new SetCardInfo("Flaring Flame-Kin", 62, Rarity.UNCOMMON, mage.cards.f.FlaringFlameKin.class)); - cards.add(new SetCardInfo("Freewind Equenaut", 9, Rarity.COMMON, mage.cards.f.FreewindEquenaut.class)); - cards.add(new SetCardInfo("Ghost Quarter", 173, Rarity.UNCOMMON, mage.cards.g.GhostQuarter.class)); - cards.add(new SetCardInfo("Gnat Alley Creeper", 63, Rarity.UNCOMMON, mage.cards.g.GnatAlleyCreeper.class)); - cards.add(new SetCardInfo("Gobhobbler Rats", 111, Rarity.COMMON, mage.cards.g.GobhobblerRats.class)); - cards.add(new SetCardInfo("Govern the Guildless", 25, Rarity.RARE, mage.cards.g.GovernTheGuildless.class)); - cards.add(new SetCardInfo("Grand Arbiter Augustin IV", 112, Rarity.RARE, mage.cards.g.GrandArbiterAugustinIV.class)); - cards.add(new SetCardInfo("Guardian of the Guildpact", 10, Rarity.COMMON, mage.cards.g.GuardianOfTheGuildpact.class)); - cards.add(new SetCardInfo("Haazda Exonerator", 11, Rarity.COMMON, mage.cards.h.HaazdaExonerator.class)); - cards.add(new SetCardInfo("Haazda Shield Mate", 12, Rarity.RARE, mage.cards.h.HaazdaShieldMate.class)); - cards.add(new SetCardInfo("Hallowed Fountain", 174, Rarity.RARE, mage.cards.h.HallowedFountain.class)); - cards.add(new SetCardInfo("Helium Squirter", 26, Rarity.COMMON, mage.cards.h.HeliumSquirter.class)); - cards.add(new SetCardInfo("Hellhole Rats", 113, Rarity.UNCOMMON, mage.cards.h.HellholeRats.class)); - cards.add(new SetCardInfo("Hide // Seek", 151, Rarity.UNCOMMON, mage.cards.h.HideSeek.class)); - cards.add(new SetCardInfo("Hit // Run", 152, Rarity.UNCOMMON, mage.cards.h.HitRun.class)); - cards.add(new SetCardInfo("Indrik Stomphowler", 86, Rarity.UNCOMMON, mage.cards.i.IndrikStomphowler.class)); - cards.add(new SetCardInfo("Infernal Tutor", 46, Rarity.RARE, mage.cards.i.InfernalTutor.class)); - cards.add(new SetCardInfo("Isperia the Inscrutable", 114, Rarity.RARE, mage.cards.i.IsperiaTheInscrutable.class)); - cards.add(new SetCardInfo("Kill-Suit Cultist", 65, Rarity.COMMON, mage.cards.k.KillSuitCultist.class)); - cards.add(new SetCardInfo("Leafdrake Roost", 116, Rarity.UNCOMMON, mage.cards.l.LeafdrakeRoost.class)); - cards.add(new SetCardInfo("Loaming Shaman", 87, Rarity.RARE, mage.cards.l.LoamingShaman.class)); - cards.add(new SetCardInfo("Lyzolda, the Blood Witch", 117, Rarity.RARE, mage.cards.l.LyzoldaTheBloodWitch.class)); - cards.add(new SetCardInfo("Macabre Waltz", 47, Rarity.COMMON, mage.cards.m.MacabreWaltz.class)); - cards.add(new SetCardInfo("Magewright's Stone", 162, Rarity.UNCOMMON, mage.cards.m.MagewrightsStone.class)); - cards.add(new SetCardInfo("Might of the Nephilim", 88, Rarity.UNCOMMON, mage.cards.m.MightOfTheNephilim.class)); - cards.add(new SetCardInfo("Minister of Impediments", 144, Rarity.COMMON, mage.cards.m.MinisterOfImpediments.class)); - cards.add(new SetCardInfo("Mistral Charger", 13, Rarity.UNCOMMON, mage.cards.m.MistralCharger.class)); - cards.add(new SetCardInfo("Momir Vig, Simic Visionary", 118, Rarity.RARE, mage.cards.m.MomirVigSimicVisionary.class)); - cards.add(new SetCardInfo("Novijen, Heart of Progress", 175, Rarity.UNCOMMON, mage.cards.n.NovijenHeartOfProgress.class)); - cards.add(new SetCardInfo("Novijen Sages", 27, Rarity.RARE, mage.cards.n.NovijenSages.class)); - cards.add(new SetCardInfo("Ocular Halo", 28, Rarity.COMMON, mage.cards.o.OcularHalo.class)); - cards.add(new SetCardInfo("Odds // Ends", 153, Rarity.RARE, mage.cards.o.OddsEnds.class)); - cards.add(new SetCardInfo("Ogre Gatecrasher", 67, Rarity.COMMON, mage.cards.o.OgreGatecrasher.class)); - cards.add(new SetCardInfo("Omnibian", 119, Rarity.RARE, mage.cards.o.Omnibian.class)); - cards.add(new SetCardInfo("Overrule", 120, Rarity.COMMON, mage.cards.o.Overrule.class)); - cards.add(new SetCardInfo("Pain Magnification", 121, Rarity.UNCOMMON, mage.cards.p.PainMagnification.class)); - cards.add(new SetCardInfo("Paladin of Prahv", 14, Rarity.UNCOMMON, mage.cards.p.PaladinOfPrahv.class)); - cards.add(new SetCardInfo("Palliation Accord", 122, Rarity.UNCOMMON, mage.cards.p.PalliationAccord.class)); - cards.add(new SetCardInfo("Patagia Viper", 89, Rarity.UNCOMMON, mage.cards.p.PatagiaViper.class)); - cards.add(new SetCardInfo("Pillar of the Paruns", 176, Rarity.RARE, mage.cards.p.PillarOfTheParuns.class)); - cards.add(new SetCardInfo("Plaxcaster Frogling", 123, Rarity.UNCOMMON, mage.cards.p.PlaxcasterFrogling.class)); - cards.add(new SetCardInfo("Plaxmanta", 29, Rarity.UNCOMMON, mage.cards.p.Plaxmanta.class)); - cards.add(new SetCardInfo("Plumes of Peace", 124, Rarity.COMMON, mage.cards.p.PlumesOfPeace.class)); - cards.add(new SetCardInfo("Prahv, Spires of Order", 177, Rarity.UNCOMMON, mage.cards.p.PrahvSpiresOfOrder.class)); - cards.add(new SetCardInfo("Pride of the Clouds", 125, Rarity.RARE, mage.cards.p.PrideOfTheClouds.class)); - cards.add(new SetCardInfo("Proclamation of Rebirth", 15, Rarity.RARE, mage.cards.p.ProclamationOfRebirth.class)); - cards.add(new SetCardInfo("Proper Burial", 16, Rarity.RARE, mage.cards.p.ProperBurial.class)); - cards.add(new SetCardInfo("Protean Hulk", 90, Rarity.RARE, mage.cards.p.ProteanHulk.class)); - cards.add(new SetCardInfo("Psychic Possession", 30, Rarity.RARE, mage.cards.p.PsychicPossession.class)); - cards.add(new SetCardInfo("Psychotic Fury", 68, Rarity.COMMON, mage.cards.p.PsychoticFury.class)); - cards.add(new SetCardInfo("Pure // Simple", 154, Rarity.UNCOMMON, mage.cards.p.PureSimple.class)); - cards.add(new SetCardInfo("Ragamuffyn", 51, Rarity.UNCOMMON, mage.cards.r.Ragamuffyn.class)); - cards.add(new SetCardInfo("Rain of Gore", 126, Rarity.RARE, mage.cards.r.RainOfGore.class)); - cards.add(new SetCardInfo("Rakdos Carnarium", 178, Rarity.COMMON, mage.cards.r.RakdosCarnarium.class)); - cards.add(new SetCardInfo("Rakdos Guildmage", 145, Rarity.UNCOMMON, mage.cards.r.RakdosGuildmage.class)); - cards.add(new SetCardInfo("Rakdos Ickspitter", 128, Rarity.COMMON, mage.cards.r.RakdosIckspitter.class)); - cards.add(new SetCardInfo("Rakdos Pit Dragon", 69, Rarity.RARE, mage.cards.r.RakdosPitDragon.class)); - cards.add(new SetCardInfo("Rakdos Signet", 165, Rarity.COMMON, mage.cards.r.RakdosSignet.class)); - cards.add(new SetCardInfo("Rakdos the Defiler", 129, Rarity.RARE, mage.cards.r.RakdosTheDefiler.class)); - cards.add(new SetCardInfo("Ratcatcher", 52, Rarity.RARE, mage.cards.r.Ratcatcher.class)); - cards.add(new SetCardInfo("Research // Development", 155, Rarity.RARE, mage.cards.r.ResearchDevelopment.class)); - cards.add(new SetCardInfo("Riot Spikes", 146, Rarity.COMMON, mage.cards.r.RiotSpikes.class)); - cards.add(new SetCardInfo("Rise // Fall", 156, Rarity.UNCOMMON, mage.cards.r.RiseFall.class)); - cards.add(new SetCardInfo("Rix Maadi, Dungeon Palace", 179, Rarity.UNCOMMON, mage.cards.r.RixMaadiDungeonPalace.class)); - cards.add(new SetCardInfo("Sandstorm Eidolon", 70, Rarity.COMMON, mage.cards.s.SandstormEidolon.class)); - cards.add(new SetCardInfo("Seal of Doom", 53, Rarity.COMMON, mage.cards.s.SealOfDoom.class)); - cards.add(new SetCardInfo("Seal of Fire", 71, Rarity.COMMON, mage.cards.s.SealOfFire.class)); - cards.add(new SetCardInfo("Shielding Plax", 147, Rarity.COMMON, mage.cards.s.ShieldingPlax.class)); - cards.add(new SetCardInfo("Silkwing Scout", 31, Rarity.COMMON, mage.cards.s.SilkwingScout.class)); - cards.add(new SetCardInfo("Simic Basilisk", 91, Rarity.UNCOMMON, mage.cards.s.SimicBasilisk.class)); - cards.add(new SetCardInfo("Simic Growth Chamber", 180, Rarity.COMMON, mage.cards.s.SimicGrowthChamber.class)); - cards.add(new SetCardInfo("Simic Guildmage", 148, Rarity.UNCOMMON, mage.cards.s.SimicGuildmage.class)); - cards.add(new SetCardInfo("Simic Initiate", 92, Rarity.COMMON, mage.cards.s.SimicInitiate.class)); - cards.add(new SetCardInfo("Simic Ragworm", 93, Rarity.COMMON, mage.cards.s.SimicRagworm.class)); - cards.add(new SetCardInfo("Simic Signet", 166, Rarity.COMMON, mage.cards.s.SimicSignet.class)); - cards.add(new SetCardInfo("Simic Sky Swallower", 130, Rarity.RARE, mage.cards.s.SimicSkySwallower.class)); - cards.add(new SetCardInfo("Skullmead Cauldron", 167, Rarity.UNCOMMON, mage.cards.s.SkullmeadCauldron.class)); - cards.add(new SetCardInfo("Sky Hussar", 131, Rarity.UNCOMMON, mage.cards.s.SkyHussar.class)); - cards.add(new SetCardInfo("Skyscribing", 32, Rarity.UNCOMMON, mage.cards.s.Skyscribing.class)); - cards.add(new SetCardInfo("Slithering Shade", 55, Rarity.UNCOMMON, mage.cards.s.SlitheringShade.class)); - cards.add(new SetCardInfo("Soulsworn Jury", 17, Rarity.COMMON, mage.cards.s.SoulswornJury.class)); - cards.add(new SetCardInfo("Spell Snare", 33, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); - cards.add(new SetCardInfo("Sporeback Troll", 94, Rarity.COMMON, mage.cards.s.SporebackTroll.class)); - cards.add(new SetCardInfo("Sprouting Phytohydra", 95, Rarity.RARE, mage.cards.s.SproutingPhytohydra.class)); - cards.add(new SetCardInfo("Stalking Vengeance", 73, Rarity.RARE, mage.cards.s.StalkingVengeance.class)); - cards.add(new SetCardInfo("Steeling Stance", 18, Rarity.COMMON, mage.cards.s.SteelingStance.class)); - cards.add(new SetCardInfo("Stoic Ephemera", 19, Rarity.UNCOMMON, mage.cards.s.StoicEphemera.class)); - cards.add(new SetCardInfo("Stomp and Howl", 96, Rarity.UNCOMMON, mage.cards.s.StompAndHowl.class)); - cards.add(new SetCardInfo("Supply // Demand", 157, Rarity.UNCOMMON, mage.cards.s.SupplyDemand.class)); - cards.add(new SetCardInfo("Taste for Mayhem", 75, Rarity.COMMON, mage.cards.t.TasteForMayhem.class)); - cards.add(new SetCardInfo("Thrive", 98, Rarity.COMMON, mage.cards.t.Thrive.class)); - cards.add(new SetCardInfo("Tidespout Tyrant", 34, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); - cards.add(new SetCardInfo("Transguild Courier", 168, Rarity.UNCOMMON, mage.cards.t.TransguildCourier.class)); - cards.add(new SetCardInfo("Trial // Error", 158, Rarity.UNCOMMON, mage.cards.t.TrialError.class)); - cards.add(new SetCardInfo("Trygon Predator", 133, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class)); - cards.add(new SetCardInfo("Twinstrike", 134, Rarity.UNCOMMON, mage.cards.t.Twinstrike.class)); - cards.add(new SetCardInfo("Utopia Sprawl", 99, Rarity.COMMON, mage.cards.u.UtopiaSprawl.class)); - cards.add(new SetCardInfo("Utvara Scalper", 76, Rarity.COMMON, mage.cards.u.UtvaraScalper.class)); - cards.add(new SetCardInfo("Valor Made Real", 20, Rarity.COMMON, mage.cards.v.ValorMadeReal.class)); - cards.add(new SetCardInfo("Verdant Eidolon", 100, Rarity.COMMON, mage.cards.v.VerdantEidolon.class)); - cards.add(new SetCardInfo("Vesper Ghoul", 57, Rarity.COMMON, mage.cards.v.VesperGhoul.class)); - cards.add(new SetCardInfo("Vigean Graftmage", 35, Rarity.UNCOMMON, mage.cards.v.VigeanGraftmage.class)); - cards.add(new SetCardInfo("Vigean Hydropon", 135, Rarity.COMMON, mage.cards.v.VigeanHydropon.class)); - cards.add(new SetCardInfo("Vision Skeins", 36, Rarity.COMMON, mage.cards.v.VisionSkeins.class)); - cards.add(new SetCardInfo("Voidslime", 137, Rarity.RARE, mage.cards.v.Voidslime.class)); - cards.add(new SetCardInfo("Wakestone Gargoyle", 21, Rarity.RARE, mage.cards.w.WakestoneGargoyle.class)); - cards.add(new SetCardInfo("Walking Archive", 169, Rarity.RARE, mage.cards.w.WalkingArchive.class)); - cards.add(new SetCardInfo("Whiptail Moloch", 79, Rarity.COMMON, mage.cards.w.WhiptailMoloch.class)); - cards.add(new SetCardInfo("Windreaver", 138, Rarity.RARE, mage.cards.w.Windreaver.class)); - cards.add(new SetCardInfo("Wit's End", 58, Rarity.RARE, mage.cards.w.WitsEnd.class)); - cards.add(new SetCardInfo("Wrecking Ball", 139, Rarity.COMMON, mage.cards.w.WreckingBall.class)); - } -} +/* +* 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.sets; + +import mage.cards.ExpansionSet; +import mage.constants.SetType; + +import mage.constants.Rarity; + +/** + * Created by IntelliJ IDEA. User: Loki Date: 20.12.10 Time: 21:40 + */ +public class Dissension extends ExpansionSet { + + private static final Dissension instance = new Dissension(); + + public static Dissension getInstance() { + return instance; + } + + private Dissension() { + super("Dissension", "DIS", ExpansionSet.buildDate(2006, 4, 5), SetType.EXPANSION); + this.blockName = "Ravnica"; + this.parentSet = RavnicaCityOfGuilds.getInstance(); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Aethermage's Touch", 101, Rarity.RARE, mage.cards.a.AethermagesTouch.class)); + cards.add(new SetCardInfo("Anthem of Rakdos", 102, Rarity.RARE, mage.cards.a.AnthemOfRakdos.class)); + cards.add(new SetCardInfo("Aquastrand Spider", 80, Rarity.COMMON, mage.cards.a.AquastrandSpider.class)); + cards.add(new SetCardInfo("Assault Zeppelid", 103, Rarity.COMMON, mage.cards.a.AssaultZeppelid.class)); + cards.add(new SetCardInfo("Aurora Eidolon", 1, Rarity.COMMON, mage.cards.a.AuroraEidolon.class)); + cards.add(new SetCardInfo("Avatar of Discord", 140, Rarity.RARE, mage.cards.a.AvatarOfDiscord.class)); + cards.add(new SetCardInfo("Azorius AEthermage", 104, Rarity.UNCOMMON, mage.cards.a.AzoriusAEthermage.class)); + cards.add(new SetCardInfo("Azorius Chancery", 170, Rarity.COMMON, mage.cards.a.AzoriusChancery.class)); + cards.add(new SetCardInfo("Azorius First-Wing", 105, Rarity.COMMON, mage.cards.a.AzoriusFirstWing.class)); + cards.add(new SetCardInfo("Azorius Guildmage", 141, Rarity.UNCOMMON, mage.cards.a.AzoriusGuildmage.class)); + cards.add(new SetCardInfo("Azorius Herald", 2, Rarity.UNCOMMON, mage.cards.a.AzoriusHerald.class)); + cards.add(new SetCardInfo("Azorius Signet", 159, Rarity.COMMON, mage.cards.a.AzoriusSignet.class)); + cards.add(new SetCardInfo("Beacon Hawk", 3, Rarity.COMMON, mage.cards.b.BeaconHawk.class)); + cards.add(new SetCardInfo("Biomantic Mastery", 142, Rarity.RARE, mage.cards.b.BiomanticMastery.class)); + cards.add(new SetCardInfo("Blessing of the Nephilim", 4, Rarity.UNCOMMON, mage.cards.b.BlessingOfTheNephilim.class)); + cards.add(new SetCardInfo("Blood Crypt", 171, Rarity.RARE, mage.cards.b.BloodCrypt.class)); + cards.add(new SetCardInfo("Bond of Agony", 38, Rarity.UNCOMMON, mage.cards.b.BondOfAgony.class)); + cards.add(new SetCardInfo("Bound // Determined", 149, Rarity.RARE, mage.cards.b.BoundDetermined.class)); + cards.add(new SetCardInfo("Brain Pry", 39, Rarity.UNCOMMON, mage.cards.b.BrainPry.class)); + cards.add(new SetCardInfo("Breeding Pool", 172, Rarity.RARE, mage.cards.b.BreedingPool.class)); + cards.add(new SetCardInfo("Cackling Flames", 59, Rarity.COMMON, mage.cards.c.CacklingFlames.class)); + cards.add(new SetCardInfo("Carom", 6, Rarity.COMMON, mage.cards.c.Carom.class)); + cards.add(new SetCardInfo("Celestial Ancient", 7, Rarity.RARE, mage.cards.c.CelestialAncient.class)); + cards.add(new SetCardInfo("Coiling Oracle", 107, Rarity.COMMON, mage.cards.c.CoilingOracle.class)); + cards.add(new SetCardInfo("Condemn", 8, Rarity.UNCOMMON, mage.cards.c.Condemn.class)); + cards.add(new SetCardInfo("Court Hussar", 22, Rarity.UNCOMMON, mage.cards.c.CourtHussar.class)); + cards.add(new SetCardInfo("Crime // Punishment", 150, Rarity.RARE, mage.cards.c.CrimePunishment.class)); + cards.add(new SetCardInfo("Crypt Champion", 40, Rarity.UNCOMMON, mage.cards.c.CryptChampion.class)); + cards.add(new SetCardInfo("Cytoplast Manipulator", 23, Rarity.RARE, mage.cards.c.CytoplastManipulator.class)); + cards.add(new SetCardInfo("Cytoplast Root-Kin", 81, Rarity.RARE, mage.cards.c.CytoplastRootKin.class)); + cards.add(new SetCardInfo("Cytospawn Shambler", 82, Rarity.COMMON, mage.cards.c.CytospawnShambler.class)); + cards.add(new SetCardInfo("Delirium Skeins", 41, Rarity.COMMON, mage.cards.d.DeliriumSkeins.class)); + cards.add(new SetCardInfo("Demonfire", 60, Rarity.RARE, mage.cards.d.Demonfire.class)); + cards.add(new SetCardInfo("Demon's Jester", 42, Rarity.COMMON, mage.cards.d.DemonsJester.class)); + cards.add(new SetCardInfo("Dovescape", 143, Rarity.RARE, mage.cards.d.Dovescape.class)); + cards.add(new SetCardInfo("Dread Slag", 109, Rarity.RARE, mage.cards.d.DreadSlag.class)); + cards.add(new SetCardInfo("Drekavac", 43, Rarity.UNCOMMON, mage.cards.d.Drekavac.class)); + cards.add(new SetCardInfo("Enemy of the Guildpact", 44, Rarity.COMMON, mage.cards.e.EnemyOfTheGuildpact.class)); + cards.add(new SetCardInfo("Enigma Eidolon", 24, Rarity.COMMON, mage.cards.e.EnigmaEidolon.class)); + cards.add(new SetCardInfo("Entropic Eidolon", 45, Rarity.COMMON, mage.cards.e.EntropicEidolon.class)); + cards.add(new SetCardInfo("Evolution Vat", 161, Rarity.RARE, mage.cards.e.EvolutionVat.class)); + cards.add(new SetCardInfo("Experiment Kraj", 110, Rarity.RARE, mage.cards.e.ExperimentKraj.class)); + cards.add(new SetCardInfo("Flaring Flame-Kin", 62, Rarity.UNCOMMON, mage.cards.f.FlaringFlameKin.class)); + cards.add(new SetCardInfo("Freewind Equenaut", 9, Rarity.COMMON, mage.cards.f.FreewindEquenaut.class)); + cards.add(new SetCardInfo("Ghost Quarter", 173, Rarity.UNCOMMON, mage.cards.g.GhostQuarter.class)); + cards.add(new SetCardInfo("Gnat Alley Creeper", 63, Rarity.UNCOMMON, mage.cards.g.GnatAlleyCreeper.class)); + cards.add(new SetCardInfo("Gobhobbler Rats", 111, Rarity.COMMON, mage.cards.g.GobhobblerRats.class)); + cards.add(new SetCardInfo("Govern the Guildless", 25, Rarity.RARE, mage.cards.g.GovernTheGuildless.class)); + cards.add(new SetCardInfo("Grand Arbiter Augustin IV", 112, Rarity.RARE, mage.cards.g.GrandArbiterAugustinIV.class)); + cards.add(new SetCardInfo("Guardian of the Guildpact", 10, Rarity.COMMON, mage.cards.g.GuardianOfTheGuildpact.class)); + cards.add(new SetCardInfo("Haazda Exonerator", 11, Rarity.COMMON, mage.cards.h.HaazdaExonerator.class)); + cards.add(new SetCardInfo("Haazda Shield Mate", 12, Rarity.RARE, mage.cards.h.HaazdaShieldMate.class)); + cards.add(new SetCardInfo("Hallowed Fountain", 174, Rarity.RARE, mage.cards.h.HallowedFountain.class)); + cards.add(new SetCardInfo("Helium Squirter", 26, Rarity.COMMON, mage.cards.h.HeliumSquirter.class)); + cards.add(new SetCardInfo("Hellhole Rats", 113, Rarity.UNCOMMON, mage.cards.h.HellholeRats.class)); + cards.add(new SetCardInfo("Hide // Seek", 151, Rarity.UNCOMMON, mage.cards.h.HideSeek.class)); + cards.add(new SetCardInfo("Hit // Run", 152, Rarity.UNCOMMON, mage.cards.h.HitRun.class)); + cards.add(new SetCardInfo("Indrik Stomphowler", 86, Rarity.UNCOMMON, mage.cards.i.IndrikStomphowler.class)); + cards.add(new SetCardInfo("Infernal Tutor", 46, Rarity.RARE, mage.cards.i.InfernalTutor.class)); + cards.add(new SetCardInfo("Isperia the Inscrutable", 114, Rarity.RARE, mage.cards.i.IsperiaTheInscrutable.class)); + cards.add(new SetCardInfo("Kill-Suit Cultist", 65, Rarity.COMMON, mage.cards.k.KillSuitCultist.class)); + cards.add(new SetCardInfo("Leafdrake Roost", 116, Rarity.UNCOMMON, mage.cards.l.LeafdrakeRoost.class)); + cards.add(new SetCardInfo("Loaming Shaman", 87, Rarity.RARE, mage.cards.l.LoamingShaman.class)); + cards.add(new SetCardInfo("Lyzolda, the Blood Witch", 117, Rarity.RARE, mage.cards.l.LyzoldaTheBloodWitch.class)); + cards.add(new SetCardInfo("Macabre Waltz", 47, Rarity.COMMON, mage.cards.m.MacabreWaltz.class)); + cards.add(new SetCardInfo("Magewright's Stone", 162, Rarity.UNCOMMON, mage.cards.m.MagewrightsStone.class)); + cards.add(new SetCardInfo("Might of the Nephilim", 88, Rarity.UNCOMMON, mage.cards.m.MightOfTheNephilim.class)); + cards.add(new SetCardInfo("Minister of Impediments", 144, Rarity.COMMON, mage.cards.m.MinisterOfImpediments.class)); + cards.add(new SetCardInfo("Mistral Charger", 13, Rarity.UNCOMMON, mage.cards.m.MistralCharger.class)); + cards.add(new SetCardInfo("Momir Vig, Simic Visionary", 118, Rarity.RARE, mage.cards.m.MomirVigSimicVisionary.class)); + cards.add(new SetCardInfo("Novijen, Heart of Progress", 175, Rarity.UNCOMMON, mage.cards.n.NovijenHeartOfProgress.class)); + cards.add(new SetCardInfo("Novijen Sages", 27, Rarity.RARE, mage.cards.n.NovijenSages.class)); + cards.add(new SetCardInfo("Ocular Halo", 28, Rarity.COMMON, mage.cards.o.OcularHalo.class)); + cards.add(new SetCardInfo("Odds // Ends", 153, Rarity.RARE, mage.cards.o.OddsEnds.class)); + cards.add(new SetCardInfo("Ogre Gatecrasher", 67, Rarity.COMMON, mage.cards.o.OgreGatecrasher.class)); + cards.add(new SetCardInfo("Omnibian", 119, Rarity.RARE, mage.cards.o.Omnibian.class)); + cards.add(new SetCardInfo("Overrule", 120, Rarity.COMMON, mage.cards.o.Overrule.class)); + cards.add(new SetCardInfo("Pain Magnification", 121, Rarity.UNCOMMON, mage.cards.p.PainMagnification.class)); + cards.add(new SetCardInfo("Paladin of Prahv", 14, Rarity.UNCOMMON, mage.cards.p.PaladinOfPrahv.class)); + cards.add(new SetCardInfo("Palliation Accord", 122, Rarity.UNCOMMON, mage.cards.p.PalliationAccord.class)); + cards.add(new SetCardInfo("Patagia Viper", 89, Rarity.UNCOMMON, mage.cards.p.PatagiaViper.class)); + cards.add(new SetCardInfo("Pillar of the Paruns", 176, Rarity.RARE, mage.cards.p.PillarOfTheParuns.class)); + cards.add(new SetCardInfo("Plaxcaster Frogling", 123, Rarity.UNCOMMON, mage.cards.p.PlaxcasterFrogling.class)); + cards.add(new SetCardInfo("Plaxmanta", 29, Rarity.UNCOMMON, mage.cards.p.Plaxmanta.class)); + cards.add(new SetCardInfo("Plumes of Peace", 124, Rarity.COMMON, mage.cards.p.PlumesOfPeace.class)); + cards.add(new SetCardInfo("Prahv, Spires of Order", 177, Rarity.UNCOMMON, mage.cards.p.PrahvSpiresOfOrder.class)); + cards.add(new SetCardInfo("Pride of the Clouds", 125, Rarity.RARE, mage.cards.p.PrideOfTheClouds.class)); + cards.add(new SetCardInfo("Proclamation of Rebirth", 15, Rarity.RARE, mage.cards.p.ProclamationOfRebirth.class)); + cards.add(new SetCardInfo("Proper Burial", 16, Rarity.RARE, mage.cards.p.ProperBurial.class)); + cards.add(new SetCardInfo("Protean Hulk", 90, Rarity.RARE, mage.cards.p.ProteanHulk.class)); + cards.add(new SetCardInfo("Psychic Possession", 30, Rarity.RARE, mage.cards.p.PsychicPossession.class)); + cards.add(new SetCardInfo("Psychotic Fury", 68, Rarity.COMMON, mage.cards.p.PsychoticFury.class)); + cards.add(new SetCardInfo("Pure // Simple", 154, Rarity.UNCOMMON, mage.cards.p.PureSimple.class)); + cards.add(new SetCardInfo("Ragamuffyn", 51, Rarity.UNCOMMON, mage.cards.r.Ragamuffyn.class)); + cards.add(new SetCardInfo("Rain of Gore", 126, Rarity.RARE, mage.cards.r.RainOfGore.class)); + cards.add(new SetCardInfo("Rakdos Carnarium", 178, Rarity.COMMON, mage.cards.r.RakdosCarnarium.class)); + cards.add(new SetCardInfo("Rakdos Guildmage", 145, Rarity.UNCOMMON, mage.cards.r.RakdosGuildmage.class)); + cards.add(new SetCardInfo("Rakdos Ickspitter", 128, Rarity.COMMON, mage.cards.r.RakdosIckspitter.class)); + cards.add(new SetCardInfo("Rakdos Pit Dragon", 69, Rarity.RARE, mage.cards.r.RakdosPitDragon.class)); + cards.add(new SetCardInfo("Rakdos Signet", 165, Rarity.COMMON, mage.cards.r.RakdosSignet.class)); + cards.add(new SetCardInfo("Rakdos the Defiler", 129, Rarity.RARE, mage.cards.r.RakdosTheDefiler.class)); + cards.add(new SetCardInfo("Ratcatcher", 52, Rarity.RARE, mage.cards.r.Ratcatcher.class)); + cards.add(new SetCardInfo("Research // Development", 155, Rarity.RARE, mage.cards.r.ResearchDevelopment.class)); + cards.add(new SetCardInfo("Riot Spikes", 146, Rarity.COMMON, mage.cards.r.RiotSpikes.class)); + cards.add(new SetCardInfo("Rise // Fall", 156, Rarity.UNCOMMON, mage.cards.r.RiseFall.class)); + cards.add(new SetCardInfo("Rix Maadi, Dungeon Palace", 179, Rarity.UNCOMMON, mage.cards.r.RixMaadiDungeonPalace.class)); + cards.add(new SetCardInfo("Sandstorm Eidolon", 70, Rarity.COMMON, mage.cards.s.SandstormEidolon.class)); + cards.add(new SetCardInfo("Seal of Doom", 53, Rarity.COMMON, mage.cards.s.SealOfDoom.class)); + cards.add(new SetCardInfo("Seal of Fire", 71, Rarity.COMMON, mage.cards.s.SealOfFire.class)); + cards.add(new SetCardInfo("Shielding Plax", 147, Rarity.COMMON, mage.cards.s.ShieldingPlax.class)); + cards.add(new SetCardInfo("Silkwing Scout", 31, Rarity.COMMON, mage.cards.s.SilkwingScout.class)); + cards.add(new SetCardInfo("Simic Basilisk", 91, Rarity.UNCOMMON, mage.cards.s.SimicBasilisk.class)); + cards.add(new SetCardInfo("Simic Growth Chamber", 180, Rarity.COMMON, mage.cards.s.SimicGrowthChamber.class)); + cards.add(new SetCardInfo("Simic Guildmage", 148, Rarity.UNCOMMON, mage.cards.s.SimicGuildmage.class)); + cards.add(new SetCardInfo("Simic Initiate", 92, Rarity.COMMON, mage.cards.s.SimicInitiate.class)); + cards.add(new SetCardInfo("Simic Ragworm", 93, Rarity.COMMON, mage.cards.s.SimicRagworm.class)); + cards.add(new SetCardInfo("Simic Signet", 166, Rarity.COMMON, mage.cards.s.SimicSignet.class)); + cards.add(new SetCardInfo("Simic Sky Swallower", 130, Rarity.RARE, mage.cards.s.SimicSkySwallower.class)); + cards.add(new SetCardInfo("Skullmead Cauldron", 167, Rarity.UNCOMMON, mage.cards.s.SkullmeadCauldron.class)); + cards.add(new SetCardInfo("Sky Hussar", 131, Rarity.UNCOMMON, mage.cards.s.SkyHussar.class)); + cards.add(new SetCardInfo("Skyscribing", 32, Rarity.UNCOMMON, mage.cards.s.Skyscribing.class)); + cards.add(new SetCardInfo("Slithering Shade", 55, Rarity.UNCOMMON, mage.cards.s.SlitheringShade.class)); + cards.add(new SetCardInfo("Soulsworn Jury", 17, Rarity.COMMON, mage.cards.s.SoulswornJury.class)); + cards.add(new SetCardInfo("Spell Snare", 33, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); + cards.add(new SetCardInfo("Sporeback Troll", 94, Rarity.COMMON, mage.cards.s.SporebackTroll.class)); + cards.add(new SetCardInfo("Sprouting Phytohydra", 95, Rarity.RARE, mage.cards.s.SproutingPhytohydra.class)); + cards.add(new SetCardInfo("Stalking Vengeance", 73, Rarity.RARE, mage.cards.s.StalkingVengeance.class)); + cards.add(new SetCardInfo("Steeling Stance", 18, Rarity.COMMON, mage.cards.s.SteelingStance.class)); + cards.add(new SetCardInfo("Stoic Ephemera", 19, Rarity.UNCOMMON, mage.cards.s.StoicEphemera.class)); + cards.add(new SetCardInfo("Stomp and Howl", 96, Rarity.UNCOMMON, mage.cards.s.StompAndHowl.class)); + cards.add(new SetCardInfo("Supply // Demand", 157, Rarity.UNCOMMON, mage.cards.s.SupplyDemand.class)); + cards.add(new SetCardInfo("Taste for Mayhem", 75, Rarity.COMMON, mage.cards.t.TasteForMayhem.class)); + cards.add(new SetCardInfo("Thrive", 98, Rarity.COMMON, mage.cards.t.Thrive.class)); + cards.add(new SetCardInfo("Tidespout Tyrant", 34, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); + cards.add(new SetCardInfo("Transguild Courier", 168, Rarity.UNCOMMON, mage.cards.t.TransguildCourier.class)); + cards.add(new SetCardInfo("Trial // Error", 158, Rarity.UNCOMMON, mage.cards.t.TrialError.class)); + cards.add(new SetCardInfo("Trygon Predator", 133, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class)); + cards.add(new SetCardInfo("Twinstrike", 134, Rarity.UNCOMMON, mage.cards.t.Twinstrike.class)); + cards.add(new SetCardInfo("Utopia Sprawl", 99, Rarity.COMMON, mage.cards.u.UtopiaSprawl.class)); + cards.add(new SetCardInfo("Utvara Scalper", 76, Rarity.COMMON, mage.cards.u.UtvaraScalper.class)); + cards.add(new SetCardInfo("Valor Made Real", 20, Rarity.COMMON, mage.cards.v.ValorMadeReal.class)); + cards.add(new SetCardInfo("Verdant Eidolon", 100, Rarity.COMMON, mage.cards.v.VerdantEidolon.class)); + cards.add(new SetCardInfo("Vesper Ghoul", 57, Rarity.COMMON, mage.cards.v.VesperGhoul.class)); + cards.add(new SetCardInfo("Vigean Graftmage", 35, Rarity.UNCOMMON, mage.cards.v.VigeanGraftmage.class)); + cards.add(new SetCardInfo("Vigean Hydropon", 135, Rarity.COMMON, mage.cards.v.VigeanHydropon.class)); + cards.add(new SetCardInfo("Vision Skeins", 36, Rarity.COMMON, mage.cards.v.VisionSkeins.class)); + cards.add(new SetCardInfo("Voidslime", 137, Rarity.RARE, mage.cards.v.Voidslime.class)); + cards.add(new SetCardInfo("Wakestone Gargoyle", 21, Rarity.RARE, mage.cards.w.WakestoneGargoyle.class)); + cards.add(new SetCardInfo("Walking Archive", 169, Rarity.RARE, mage.cards.w.WalkingArchive.class)); + cards.add(new SetCardInfo("Whiptail Moloch", 79, Rarity.COMMON, mage.cards.w.WhiptailMoloch.class)); + cards.add(new SetCardInfo("Windreaver", 138, Rarity.RARE, mage.cards.w.Windreaver.class)); + cards.add(new SetCardInfo("Wit's End", 58, Rarity.RARE, mage.cards.w.WitsEnd.class)); + cards.add(new SetCardInfo("Wrecking Ball", 139, Rarity.COMMON, mage.cards.w.WreckingBall.class)); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/restriction/CantAttackTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/restriction/CantAttackTest.java index 5ebd9205c41..f3a8cd4a9a7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/restriction/CantAttackTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/restriction/CantAttackTest.java @@ -40,8 +40,8 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class CantAttackTest extends CardTestPlayerBase { /** - * Tests "If all other elves get the Forestwalk ability and can't be blockt - * from creatures whose controler has a forest in game" + * Tests "If all other elves get the Forestwalk ability and can't be blocked + * from creatures whose controller has a forest in game" */ @Test public void testAttack() { @@ -250,4 +250,158 @@ public class CantAttackTest extends CardTestPlayerBase { assertGraveyardCount(playerA, eFirecraft, 1); assertPermanentCount(playerA, medomai, 1); } + + @Test + public void sphereOfSafetyPaidCostAllowsAttack() { + /* + Sphere of Safety {4}{W} + Enchantment + Creatures can't attack you or a planeswalker you control unless their controller pays {X} for each of those creatures, where X is the number of enchantments you control. + */ + String sphere = "Sphere of Safety"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, sphere); + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + + attack(1, playerA, memnite); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, sphere, 1); + assertLife(playerB, 19); // took the hit from memnite + assertTapped("Forest", true); // forest had to be tapped + } + + @Test + public void sphereOfSafetyCostNotPaid_NoAttackAllowed() { + /* + Sphere of Safety {4}{W} + Enchantment + Creatures can't attack you or a planeswalker you control unless their controller pays {X} for each of those creatures, where X is the number of enchantments you control. + */ + String sphere = "Sphere of Safety"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, sphere); + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + + attack(1, playerA, memnite); + setChoice(playerA, "No"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, sphere, 1); + assertLife(playerB, 20); // no damage went through, did not elect to pay + assertTapped("Forest", false); // forest not tapped + } + + @Test + public void collectiveResistanceCostPaid_AttackAllowed() + { + /* + Collective Restraint {3}{U} + Enchantment + Domain — Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control. + */ + String cRestraint = "Collective Restraint"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, cRestraint); + addCard(Zone.BATTLEFIELD, playerB, "Island"); // 1 basic land type = pay 1 to attack + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + + attack(1, playerA, memnite); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, cRestraint, 1); + assertLife(playerB, 19); // took the hit from memnite + assertTapped("Forest", true); // forest had to be tapped + } + + @Test + public void collectiveResistanceCostNotPaid_NoAttackAllowed() + { + /* + Collective Restraint {3}{U} + Enchantment + Domain — Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control. + */ + String cRestraint = "Collective Restraint"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, cRestraint); + addCard(Zone.BATTLEFIELD, playerB, "Island"); // 1 basic land type = pay 1 to attack + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + + attack(1, playerA, memnite); + setChoice(playerA, "No"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, cRestraint, 1); + assertLife(playerB, 20); // no damage went through, did not elect to pay + assertTapped("Forest", false); // forest not tapped + } + + @Test + public void ghostlyPrison_PaidCost_AllowsAttack() { + /* + Ghostly Prison {2}{W} + Enchantment + Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. + */ + String gPrison = "Ghostly Prison"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, gPrison); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + attack(1, playerA, memnite); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, gPrison, 1); + assertLife(playerB, 19); // took the hit from memnite + assertTappedCount("Forest", true, 2); // forests had to be tapped + } + + @Test + public void ghostlyPrison_CostNotPaid_NoAttackAllowed() { + /* + Ghostly Prison {2}{W} + Enchantment + Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. + */ + String gPrison = "Ghostly Prison"; + String memnite = "Memnite"; + + addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1 + addCard(Zone.BATTLEFIELD, playerB, gPrison); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + attack(1, playerA, memnite); + setChoice(playerA, "No"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, gPrison, 1); + assertLife(playerB, 20); // no damage went through, did not elect to pay + assertTapped("Forest", false); // no forests tapped + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/HalimarTidecallerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/HalimarTidecallerTest.java new file mode 100644 index 00000000000..2180d97fa7c --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/HalimarTidecallerTest.java @@ -0,0 +1,50 @@ +package org.mage.test.cards.single.bfz; + +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author escplan9 + */ +public class HalimarTidecallerTest extends CardTestPlayerBase { + + @Test + public void testMe() { + + /* + Halimar Tidecaller {2}{U} + Creature — Human Wizard Ally 2/3 + When Halimar Tidecaller enters the battlefield, you may return target card with awaken from your graveyard to your hand. + Land creatures you control have flying. + */ + String hTidecaller = "Halimar Tidecaller"; + + /* + Treetop Village + Land + Treetop Village enters the battlefield tapped. + {T}: Add Green to your mana pool. + {1}{G}: Treetop Village becomes a 3/3 green Ape creature with trample until end of turn. It's still a land. + */ + String tVillage = "Treetop Village"; + + addCard(Zone.BATTLEFIELD, playerA, hTidecaller); + addCard(Zone.BATTLEFIELD, playerA, tVillage); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G}:"); // activate tree-top + attack(1, playerA, tVillage); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 17); // 3 damage from tree-top + assertAbility(playerA, tVillage, FlyingAbility.getInstance(), true); + assertAbility(playerA, tVillage, TrampleAbility.getInstance(), true); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/DeclarationInStoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/DeclarationInStoneTest.java new file mode 100644 index 00000000000..355b9aabf0f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/DeclarationInStoneTest.java @@ -0,0 +1,75 @@ +package org.mage.test.cards.single.soi; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author escplan9 + */ +public class DeclarationInStoneTest extends CardTestPlayerBase { + + @Test + public void testExileNonToken_NameShared_ExilesMultiple() { + + /* + Declaration in Stone {1}{W} Sorcery + Exile target creature and all other creatures its controller controls with the same name as that creature. That player investigates for each nontoken creature exiled this way. + */ + String dStone = "Declaration in Stone"; + String memnite = "Memnite"; // {0} 1/1 + String hGiant = "Hill Giant"; // {3}{R} 3/3 + + addCard(Zone.BATTLEFIELD, playerB, memnite, 3); + addCard(Zone.BATTLEFIELD, playerB, hGiant); + addCard(Zone.HAND, playerA, dStone); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, dStone, memnite); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, dStone, 1); + assertPermanentCount(playerB, hGiant, 1); + assertPermanentCount(playerB, memnite, 0); + assertExileCount(playerB, memnite, 3); + assertPermanentCount(playerB, "Clue", 3); // 3 creatures exiled = 3 clues for them + } + + @Test + public void testExileToken_NameShared_ExilesMultipleNoCluesFromTokensExiled() { + + /* + Declaration in Stone {1}{W} Sorcery + Exile target creature and all other creatures its controller controls with the same name as that creature. That player investigates for each nontoken creature exiled this way. + */ + String dStone = "Declaration in Stone"; + + /* + Grave Titan {4}{B}{B} + Creature — Giant + Deathtouch + Whenever Grave Titan enters the battlefield or attacks, create two 2/2 black Zombie creature tokens. + */ + String gTitan = "Grave Titan"; + + addCard(Zone.HAND, playerA, gTitan, 1); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6); + addCard(Zone.HAND, playerB, dStone); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, gTitan); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, dStone, "Zombie"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, dStone, 1); + assertPermanentCount(playerA, gTitan, 1); + assertPermanentCount(playerA, "Zombie", 0); + assertPermanentCount(playerA, "Clue", 0); // tokens exiled do not generate clues + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java index 48c16da477e..cad17d724e8 100644 --- a/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects; +import java.util.Iterator; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; @@ -43,9 +44,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.players.Player; -import java.util.Iterator; -import java.util.List; - /** * * @author LevelX2 @@ -72,7 +70,6 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm protected final Cost cost; protected final ManaCosts manaCosts; - protected final RestrictType restrictType; public PayCostToAttackBlockEffectImpl(Duration duration, Outcome outcome, RestrictType restrictType) { @@ -149,7 +146,9 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm attackBlockManaTax.clearPaid(); if (attackBlockManaTax.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { - handlePhyrexianManaCosts(manaCosts, player, source, game); + + handlePhyrexianManaCosts(getManaCostToPay(event, source, game), player, source, game); + if (attackBlockManaTax instanceof ManaCostsImpl) { if (attackBlockManaTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; @@ -162,6 +161,9 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm } private void handlePhyrexianManaCosts(ManaCosts manaCosts, Player player, Ability source, Game game) { + + if (manaCosts == null) return; // nothing to be done without any mana costs. prevents NRE from occurring here + Iterator manaCostIterator = manaCosts.iterator(); Costs costs = new CostsImpl<>();