From 31d4be7a1cd0e7fa88c3cc08b6edae6a232fa7e1 Mon Sep 17 00:00:00 2001 From: Faxn Date: Thu, 28 Sep 2017 18:21:47 -0400 Subject: [PATCH 001/164] Momir Multiplayer Might just work. --- .../Mage.Game.MomirGame/pom.xml | 55 +++++++++ .../src/mage/game/MomirFreeForAllMatch.java | 55 +++++++++ .../src/mage/game/MomirFreeForAllType.java | 57 ++++++++++ .../src/mage/game/MomirGame.java | 105 ++++++++++++++++++ Mage.Server.Plugins/pom.xml | 1 + Mage.Server/config/config.xml | 1 + Mage.Server/pom.xml | 6 + 7 files changed, 280 insertions(+) create mode 100644 Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml create mode 100644 Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllMatch.java create mode 100644 Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllType.java create mode 100644 Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml new file mode 100644 index 0000000000..209ffd70c3 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + + + org.mage + mage-server-plugins + 1.4.26 + + + mage-game-momirfreeforall + jar + Mage Game Momir Basic Free for All + + + + ${project.groupId} + mage + ${project.version} + + + ${project.groupId} + mage-game-freeforall + ${project.version} + + + + + src + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + maven-resources-plugin + + UTF-8 + + + + + + mage-game-momir + + + + + diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllMatch.java b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllMatch.java new file mode 100644 index 0000000000..a46aa486ca --- /dev/null +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllMatch.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game; + +import mage.game.match.MatchImpl; +import mage.game.match.MatchOptions; + +/** + * + * @author nigelzor + */ +public class MomirFreeForAllMatch extends MatchImpl { + + public MomirFreeForAllMatch(MatchOptions options) { + super(options); + } + + @Override + public void startGame() throws GameException { + // Momir Vig, Simic Visionary gives +4 starting life + int startLife = 24; + + MomirGame game = new MomirGame(options.getAttackOption(), options.getRange(), options.getFreeMulligans(), startLife); + game.setStartMessage(this.createGameStartMessage()); + + this.initGame(game); + games.add(game); + } + +} diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllType.java b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllType.java new file mode 100644 index 0000000000..5eb6c30170 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirFreeForAllType.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game; + +import mage.game.match.MatchType; + +/** + * + * @author nigelzor + */ +public class MomirFreeForAllType extends MatchType { + + public MomirFreeForAllType() { + this.name = "Momir Basic Free For All"; + this.maxPlayers = 10; + this.minPlayers = 2; + this.numTeams = 0; + this.useAttackOption = true; + this.useRange = true; + this.sideboardingAllowed = false; + } + + protected MomirFreeForAllType(final MomirFreeForAllType matchType){ + super(matchType); + } + + @Override + public MomirFreeForAllType copy() { + return new MomirFreeForAllType(this); + } + +} diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java new file mode 100644 index 0000000000..5627da1695 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java @@ -0,0 +1,105 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.InfoEffect; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.constants.MultiplayerAttackOption; +import mage.constants.PhaseStep; +import mage.constants.RangeOfInfluence; +import mage.constants.Zone; +import mage.game.command.emblems.MomirEmblem; +import mage.game.match.MatchType; +import mage.game.turn.TurnMod; +import mage.players.Player; + + +/** + * + * @author nigelzor + */ +public class MomirGame extends FreeForAll { + + private int numPlayers; + + public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans, int startLife) { + super(attackOption, range, freeMulligans, startLife); + } + + public MomirGame(final MomirGame game) { + super(game); + } + + @Override + public MatchType getGameType() { + return new MomirFreeForAllType(); + } + + @Override + public int getNumPlayers() { + return numPlayers; + } + + @Override + protected void init(UUID choosingPlayerId) { + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Vanguard effects")); + for (UUID playerId : state.getPlayerList(startingPlayerId)) { + Player player = getPlayer(playerId); + if (player != null) { + CardInfo cardInfo = CardRepository.instance.findCard("Momir Vig, Simic Visionary"); + addEmblem(new MomirEmblem(), cardInfo.getCard(), playerId); + } + } + getState().addAbility(ability, null); + super.init(choosingPlayerId); + state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW)); + } + + @Override + public Set getOpponents(UUID playerId) { + Set opponents = new HashSet<>(); + for (UUID opponentId : this.getPlayer(playerId).getInRange()) { + if (!opponentId.equals(playerId)) { + opponents.add(opponentId); + } + } + return opponents; + } + + @Override + public MomirGame copy() { + return new MomirGame(this); + } + +} diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml index 4f23171181..6088bbe80d 100644 --- a/Mage.Server.Plugins/pom.xml +++ b/Mage.Server.Plugins/pom.xml @@ -21,6 +21,7 @@ Mage.Game.CommanderFreeForAll Mage.Game.FreeForAll Mage.Game.MomirDuel + Mage.Game.MomirGame Mage.Game.TinyLeadersDuel Mage.Game.CanadianHighlanderDuel Mage.Game.PennyDreadfulCommanderFreeForAll diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 877f1756e3..ba16d20cc3 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -77,6 +77,7 @@ + diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index eb547da404..364875c081 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -160,6 +160,12 @@ ${project.version} runtime + + ${project.groupId} + mage-game-momirfreeforall + ${project.version} + runtime + org.apache.shiro shiro-core From 3baabe2534f8a3637feb290475a5ad400f226dcd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 16:55:46 -0400 Subject: [PATCH 002/164] some text fixes --- Mage.Sets/src/mage/cards/b/Bequeathal.java | 4 ++-- Mage.Sets/src/mage/cards/c/ChillHaunting.java | 2 +- Mage.Sets/src/mage/cards/d/DecreeOfSilence.java | 12 ++++++------ Mage.Sets/src/mage/cards/e/EntropicSpecter.java | 4 ++-- Mage.Sets/src/mage/cards/m/MercurialKite.java | 2 +- Mage.Sets/src/mage/cards/m/MischievousQuanar.java | 8 ++++---- Mage.Sets/src/mage/cards/o/OneWithNature.java | 9 +++++---- Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java | 2 +- Mage.Sets/src/mage/cards/r/ReapingTheGraves.java | 5 ++--- Mage.Sets/src/mage/cards/r/ReapingTheRewards.java | 6 +++--- Mage.Sets/src/mage/cards/r/RecklessOgre.java | 4 ++-- Mage.Sets/src/mage/cards/r/RewardTheFaithful.java | 5 +++-- Mage.Sets/src/mage/cards/s/ScaldingSalamander.java | 2 +- Mage.Sets/src/mage/cards/s/SpikeCannibal.java | 4 ++-- Mage.Sets/src/mage/cards/s/SpikeRogue.java | 8 ++++---- Mage.Sets/src/mage/cards/s/SpikeWeaver.java | 8 ++++---- Mage.Sets/src/mage/cards/t/TorrentOfFire.java | 6 ++++-- Mage.Sets/src/mage/cards/v/VengefulDead.java | 8 ++++---- Mage.Sets/src/mage/cards/w/WelkinHawk.java | 9 ++++----- Mage/src/main/java/mage/abilities/AbilityImpl.java | 2 +- .../common/EndOfCombatTriggeredAbility.java | 7 +++---- .../abilities/effects/common/ExileAllEffect.java | 7 +++---- .../common/LookLibraryTopCardTargetPlayerEffect.java | 2 +- .../common/counter/AddCountersSourceEffect.java | 8 +++++++- .../effects/common/discard/DiscardTargetEffect.java | 2 +- .../java/mage/abilities/keyword/FlyingAbility.java | 9 ++++----- .../java/mage/abilities/keyword/ShroudAbility.java | 2 +- .../mage/abilities/keyword/VigilanceAbility.java | 5 ++--- 28 files changed, 78 insertions(+), 74 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/Bequeathal.java b/Mage.Sets/src/mage/cards/b/Bequeathal.java index 0243f77892..e1c6f12f92 100644 --- a/Mage.Sets/src/mage/cards/b/Bequeathal.java +++ b/Mage.Sets/src/mage/cards/b/Bequeathal.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; public class Bequeathal extends CardImpl { public Bequeathal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -59,7 +59,7 @@ public class Bequeathal extends CardImpl { this.addAbility(ability); // When enchanted creature dies, you draw two cards. - this.addAbility( new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(2), "enchanted creature")); + this.addAbility(new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(2).setText("you draw two cards"), "enchanted creature")); } public Bequeathal(final Bequeathal card) { diff --git a/Mage.Sets/src/mage/cards/c/ChillHaunting.java b/Mage.Sets/src/mage/cards/c/ChillHaunting.java index 4b678c0411..4a9dfd5fff 100644 --- a/Mage.Sets/src/mage/cards/c/ChillHaunting.java +++ b/Mage.Sets/src/mage/cards/c/ChillHaunting.java @@ -50,7 +50,7 @@ public class ChillHaunting extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); // As an additional cost to cast Chill Haunting, exile X creature cards from your graveyard. - this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"))); + this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"), true)); // Target creature gets -X/-X until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java b/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java index b8a5262544..2c641e7c7d 100644 --- a/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java +++ b/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java @@ -45,7 +45,7 @@ import mage.constants.CardType; import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.StaticFilters; +import mage.filter.FilterSpell; import mage.target.TargetSpell; /** @@ -55,19 +55,19 @@ import mage.target.TargetSpell; public class DecreeOfSilence extends CardImpl { public DecreeOfSilence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{6}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{6}{U}{U}"); // Whenever an opponent casts a spell, counter that spell and put a depletion counter on Decree of Silence. If there are three or more depletion counters on Decree of Silence, sacrifice it. Effect effect = new CounterTargetEffect(); effect.setText("counter that spell"); - Ability ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_SPELL, - false, SetTargetPointer.SPELL); + Ability ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, effect, new FilterSpell("a spell"), + false, SetTargetPointer.SPELL); effect = new AddCountersSourceEffect(CounterType.DEPLETION.createInstance()); effect.setText("and put a depletion counter on {this}."); ability.addEffect(effect); ability.addEffect(new ConditionalOneShotEffect(new SacrificeSourceEffect(), - new SourceHasCounterCondition(CounterType.DEPLETION, 3, Integer.MAX_VALUE), - " If there are three or more depletion counters on {this}, sacrifice it")); + new SourceHasCounterCondition(CounterType.DEPLETION, 3, Integer.MAX_VALUE), + " If there are three or more depletion counters on {this}, sacrifice it")); this.addAbility(ability); // Cycling {4}{U}{U} this.addAbility(new CyclingAbility(new ManaCostsImpl("{4}{U}{U}"))); diff --git a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java index 836cc8fd16..eb0cb15d73 100644 --- a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java +++ b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java @@ -52,7 +52,7 @@ import mage.players.Player; public class EntropicSpecter extends CardImpl { public EntropicSpecter(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.SPECTER); this.subtype.add(SubType.SPIRIT); @@ -105,7 +105,7 @@ class CardsInTargetPlayerHandCount implements DynamicValue { @Override public String getMessage() { - return "cards in chosen opponents hand"; + return "cards in the chosen player's hand"; } @Override diff --git a/Mage.Sets/src/mage/cards/m/MercurialKite.java b/Mage.Sets/src/mage/cards/m/MercurialKite.java index b36bc71d32..b20f7107ec 100644 --- a/Mage.Sets/src/mage/cards/m/MercurialKite.java +++ b/Mage.Sets/src/mage/cards/m/MercurialKite.java @@ -56,7 +56,7 @@ public class MercurialKite extends CardImpl { // Whenever Mercurial Kite deals combat damage to a creature, tap that creature. That creature doesn't untap during its controller's next untap step. Ability ability; ability = new DealsDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), true, false, true); - ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("and it")); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(". That creature")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MischievousQuanar.java b/Mage.Sets/src/mage/cards/m/MischievousQuanar.java index cb89d7fe41..646992201e 100644 --- a/Mage.Sets/src/mage/cards/m/MischievousQuanar.java +++ b/Mage.Sets/src/mage/cards/m/MischievousQuanar.java @@ -53,19 +53,19 @@ import mage.target.TargetSpell; public class MischievousQuanar extends CardImpl { public MischievousQuanar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); // {3}{U}{U}: Turn Mischievous Quanar face down. Effect effect = new BecomesFaceDownCreatureEffect(Duration.Custom, BecomesFaceDownCreatureEffect.FaceDownType.MANUAL); - effect.setText("Turn Michievous Quanar face down. (It becomes a 2/2 creature.)"); + effect.setText("Turn {this} face down. (It becomes a 2/2 creature.)"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}{U}{U}"))); - + // Morph {1}{U}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}{U}"))); - + // When Mischievous Quanar is turned face up, copy target instant or sorcery spell. You may choose new targets for that copy. Effect effect2 = new CopyTargetSpellEffect(); effect2.setText("copy target instant or sorcery spell. You may choose new targets for that copy"); diff --git a/Mage.Sets/src/mage/cards/o/OneWithNature.java b/Mage.Sets/src/mage/cards/o/OneWithNature.java index 55c0e36dab..6f4e7097f9 100644 --- a/Mage.Sets/src/mage/cards/o/OneWithNature.java +++ b/Mage.Sets/src/mage/cards/o/OneWithNature.java @@ -52,7 +52,7 @@ import java.util.UUID; public class OneWithNature extends CardImpl { public OneWithNature(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -61,12 +61,13 @@ public class OneWithNature extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.PutLandInPlay)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Whenever enchanted creature deals combat damage to a player, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. ability = new DealsDamageToAPlayerAttachedTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay) + .setText("you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library."), "enchanted creature", true, false, true, TargetController.ANY); - this.addAbility(ability); + this.addAbility(ability); } public OneWithNature(final OneWithNature card) { diff --git a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java index 45441eb9e5..4e19cb2918 100644 --- a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java +++ b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java @@ -45,7 +45,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RavenGuildInitiate extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("Bird you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird you control"); static { filter.add(new SubtypePredicate(SubType.BIRD)); diff --git a/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java b/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java index 03fcbeb245..070b57e686 100644 --- a/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java +++ b/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java @@ -43,12 +43,11 @@ import mage.target.common.TargetCardInYourGraveyard; public class ReapingTheGraves extends CardImpl { public ReapingTheGraves(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // Return target creature card from your graveyard to your hand. this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setText("Return target creature card from your graveyard to your hand.")); // Storm this.addAbility(new StormAbility()); } diff --git a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java index 848f6ca74b..f46924f5b5 100644 --- a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java +++ b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java @@ -44,11 +44,11 @@ import mage.target.common.TargetControlledPermanent; public class ReapingTheRewards extends CardImpl { public ReapingTheRewards(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Buyback-Sacrifice a land. - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent())))); - + this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + // You gain 2 life. this.getSpellAbility().addEffect(new GainLifeEffect(2)); } diff --git a/Mage.Sets/src/mage/cards/r/RecklessOgre.java b/Mage.Sets/src/mage/cards/r/RecklessOgre.java index b21dc15a7d..59d93a7e8c 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessOgre.java +++ b/Mage.Sets/src/mage/cards/r/RecklessOgre.java @@ -44,13 +44,13 @@ import mage.constants.Duration; public class RecklessOgre extends CardImpl { public RecklessOgre(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.OGRE); this.power = new MageInt(3); this.toughness = new MageInt(2); // Whenever Reckless Ogre attacks alone, it gets +3/+0 until end of turn. - this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(3, 0, Duration.EndOfTurn))); + this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(3, 0, Duration.EndOfTurn).setText("it gets +3/+0 until end of turn"))); } public RecklessOgre(final RecklessOgre card) { diff --git a/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java b/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java index a41add973c..46eafe8f82 100644 --- a/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java +++ b/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java @@ -42,10 +42,11 @@ import mage.target.TargetPlayer; public class RewardTheFaithful extends CardImpl { public RewardTheFaithful(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Any number of target players each gain life equal to the highest converted mana cost among permanents you control. - this.getSpellAbility().addEffect(new GainLifeTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new GainLifeTargetEffect(new HighestConvertedManaCostValue()) + .setText("Any number of target players each gain life equal to the highest converted mana cost among permanents you control.")); this.getSpellAbility().addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); } diff --git a/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java b/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java index dee50f94aa..093ec1376a 100644 --- a/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java +++ b/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java @@ -66,7 +66,7 @@ public class ScaldingSalamander extends CardImpl { // Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls. this.addAbility(new AttacksTriggeredAbility( new DamageAllEffect(1, filter), true, - "Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls" + "Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls." )); } diff --git a/Mage.Sets/src/mage/cards/s/SpikeCannibal.java b/Mage.Sets/src/mage/cards/s/SpikeCannibal.java index c87670061d..876717e641 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeCannibal.java +++ b/Mage.Sets/src/mage/cards/s/SpikeCannibal.java @@ -53,13 +53,13 @@ import mage.game.permanent.Permanent; public class SpikeCannibal extends CardImpl { public SpikeCannibal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Cannibal enters the battlefield with a +1/+1 counter on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), "Spike Cannibal enters the battlefield with a +1/+1 counter on it")); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), "with a +1/+1 counter on it")); // When Spike Cannibal enters the battlefield, move all +1/+1 counters from all creatures onto it. this.addAbility(new EntersBattlefieldTriggeredAbility(new SpikeCannibalEffect())); diff --git a/Mage.Sets/src/mage/cards/s/SpikeRogue.java b/Mage.Sets/src/mage/cards/s/SpikeRogue.java index b7a6efd2dd..a27148a327 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeRogue.java +++ b/Mage.Sets/src/mage/cards/s/SpikeRogue.java @@ -54,23 +54,23 @@ import mage.target.common.TargetCreaturePermanent; public class SpikeRogue extends CardImpl { public SpikeRogue(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Rogue enters the battlefield with two +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)))); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), "with two +1/+1 counters on it")); // {2}, Remove a +1/+1 counter from Spike Rogue: Put a +1/+1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // {2}, Remove a +1/+1 counter from a creature you control: Put a +1/+1 counter on Spike Rogue. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new GenericManaCost(2)); - ability2.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent(), true), CounterType.P1P1)); + ability2.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true), CounterType.P1P1)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/s/SpikeWeaver.java b/Mage.Sets/src/mage/cards/s/SpikeWeaver.java index 7c7f90cbdc..d30ff8cce9 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeWeaver.java +++ b/Mage.Sets/src/mage/cards/s/SpikeWeaver.java @@ -53,21 +53,21 @@ import mage.target.common.TargetCreaturePermanent; public class SpikeWeaver extends CardImpl { public SpikeWeaver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Weaver enters the battlefield with three +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)))); - + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it")); + // {2}, Remove a +1/+1 counter from Spike Weaver: Put a +1/+1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // {1}, Remove a +1/+1 counter from Spike Weaver: Prevent all combat damage that would be dealt this turn. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true), new GenericManaCost(1)); ability2.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); diff --git a/Mage.Sets/src/mage/cards/t/TorrentOfFire.java b/Mage.Sets/src/mage/cards/t/TorrentOfFire.java index d07918ce53..6f6501f595 100644 --- a/Mage.Sets/src/mage/cards/t/TorrentOfFire.java +++ b/Mage.Sets/src/mage/cards/t/TorrentOfFire.java @@ -42,10 +42,12 @@ import mage.target.common.TargetCreatureOrPlayer; public class TorrentOfFire extends CardImpl { public TorrentOfFire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}"); // Torrent of Fire deals damage equal to the highest converted mana cost among permanents you control to target creature or player. - this.getSpellAbility().addEffect(new DamageTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new DamageTargetEffect(new HighestConvertedManaCostValue()) + .setText("{this} deals damage to target creature or player equal to the highest converted mana cost among permanents you control.") + ); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/cards/v/VengefulDead.java b/Mage.Sets/src/mage/cards/v/VengefulDead.java index 5c2eec5918..863da2da6a 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulDead.java +++ b/Mage.Sets/src/mage/cards/v/VengefulDead.java @@ -43,15 +43,15 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author fireshoes */ public class VengefulDead extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another Zombie"); - + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie"); + static { filter.add(new SubtypePredicate(SubType.ZOMBIE)); } public VengefulDead(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.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/w/WelkinHawk.java b/Mage.Sets/src/mage/cards/w/WelkinHawk.java index 8996177ae0..81cb90cac0 100644 --- a/Mage.Sets/src/mage/cards/w/WelkinHawk.java +++ b/Mage.Sets/src/mage/cards/w/WelkinHawk.java @@ -44,9 +44,8 @@ import mage.target.common.TargetCardInLibrary; * * @author fireshoes */ - public class WelkinHawk extends CardImpl { - + private static final FilterCard filter = new FilterCard("card named Welkin Hawk"); static { @@ -54,16 +53,16 @@ public class WelkinHawk extends CardImpl { } public WelkinHawk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(1); this.toughness = new MageInt(1); // Flying this.addAbility(FlyingAbility.getInstance()); - + // When Welkin Hawk dies, you may search your library for a card named Welkin Hawk, reveal that card, put it into your hand, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 3fc2020dd7..8e52732e5d 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -773,7 +773,7 @@ public abstract class AbilityImpl implements Ability { } if (!costs.isEmpty()) { if (sbRule.length() > 0) { - sbRule.append(','); + sbRule.append(", "); } sbRule.append(costs.getText()); } diff --git a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java index cdff752da7..3c332a232b 100644 --- a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java @@ -15,7 +15,6 @@ import mage.game.events.GameEvent; * * @author LevelX2 */ - public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { public EndOfCombatTriggeredAbility(Effect effect, boolean optional) { @@ -35,7 +34,7 @@ public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.END_COMBAT_STEP_PRE; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { return true; @@ -43,6 +42,6 @@ public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "At the end of combat, " + super.getRule(); + return "At end of combat, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java index 5c076adc38..ec46d23210 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.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.abilities.effects.common; import java.util.List; @@ -52,6 +51,7 @@ public class ExileAllEffect extends OneShotEffect { public ExileAllEffect(FilterPermanent filter) { this(filter, null, null); } + public ExileAllEffect(FilterPermanent filter, UUID exileId, String exileZone) { super(Outcome.Exile); this.filter = filter; @@ -77,19 +77,18 @@ public class ExileAllEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent permanent: permanents) { + for (Permanent permanent : permanents) { controller.moveCardToExileWithInfo(permanent, exileId, exileZone, source.getSourceId(), game, Zone.BATTLEFIELD, true); } return true; } return false; - } private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Exile all ").append(filter.getMessage()); + sb.append("exile all ").append(filter.getMessage()); staticText = sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java index bf7c607f31..3081206ac6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java @@ -106,7 +106,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { sb.append(CardUtil.numberToText(amount)); sb.append(" cards "); } else { - sb.append(" card "); + sb.append("card "); } sb.append("of target player's library"); if (putToGraveyard) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 1f28040a73..9376340acf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -152,14 +152,20 @@ public class AddCountersSourceEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); sb.append("put "); + boolean plural = true; if (counter.getCount() > 1) { sb.append(CardUtil.numberToText(counter.getCount())).append(' '); } else if (amount.toString().equals("X") && amount.getMessage().isEmpty()) { sb.append("X "); } else { sb.append("a "); + plural = false; } - sb.append(counter.getName().toLowerCase()).append(" counter on {this}"); + sb.append(counter.getName().toLowerCase()).append(" counter"); + if (plural) { + sb.append('s'); + } + sb.append(" on {this}"); if (!amount.getMessage().isEmpty()) { sb.append(" for each ").append(amount.getMessage()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java index a053e6f256..4bf488649b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java @@ -108,7 +108,7 @@ public class DiscardTargetEffect extends OneShotEffect { } sb.append(" discards "); if (amount.toString().equals("1")) { - sb.append(" a card"); + sb.append("a card"); } else { sb.append(CardUtil.numberToText(amount.toString())).append(" cards"); } diff --git a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java index 86d243c675..1e0bf34cb1 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.abilities.Ability; @@ -46,7 +45,7 @@ import java.io.ObjectStreamException; */ public class FlyingAbility extends EvasionAbility implements MageSingleton { - private static final FlyingAbility instance = new FlyingAbility(); + private static final FlyingAbility instance = new FlyingAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -62,7 +61,7 @@ public class FlyingAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Flying"; + return "flying"; } @Override @@ -91,7 +90,7 @@ class FlyingEffect extends RestrictionEffect implements MageSingleton { public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { return blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId()) || blocker.getAbilities().containsKey(ReachAbility.getInstance().getId()) - || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype(SubType.DRAGON, game)) ; + || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype(SubType.DRAGON, game)); } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java b/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java index 53e32db450..556f9addb9 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java @@ -56,7 +56,7 @@ public class ShroudAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Shroud"; + return "shroud"; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java b/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java index a4d5f29d5a..13925a8ee3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.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.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class VigilanceAbility extends StaticAbility implements MageSingleton { - private static final VigilanceAbility instance = new VigilanceAbility(); + private static final VigilanceAbility instance = new VigilanceAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class VigilanceAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Vigilance"; + return "vigilance"; } @Override From bc2bfba02a9924cb83b6aa56439d37c740f44c13 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 18:28:22 -0400 Subject: [PATCH 003/164] more text fixes --- .../src/mage/cards/a/AgelessSentinels.java | 2 +- Mage.Sets/src/mage/cards/a/AlphaStatus.java | 2 +- Mage.Sets/src/mage/cards/a/AncientOoze.java | 16 +++++----- Mage.Sets/src/mage/cards/b/BlackCarriage.java | 10 +++---- Mage.Sets/src/mage/cards/b/BrownOuphe.java | 2 +- .../src/mage/cards/c/CabalConditioning.java | 6 ++-- .../mage/cards/c/ClergyOfTheHolyNimbus.java | 8 ++--- Mage.Sets/src/mage/cards/c/CoalitionFlag.java | 4 +-- .../src/mage/cards/d/DaughterOfAutumn.java | 1 + Mage.Sets/src/mage/cards/d/DivineLight.java | 6 ++-- Mage.Sets/src/mage/cards/d/DwarvenPatrol.java | 6 ++-- Mage.Sets/src/mage/cards/g/GreatDefender.java | 4 ++- Mage.Sets/src/mage/cards/i/IceCave.java | 15 +++++----- Mage.Sets/src/mage/cards/i/Illuminate.java | 14 ++++----- Mage.Sets/src/mage/cards/j/Jilt.java | 8 ++--- Mage.Sets/src/mage/cards/j/Jokulmorder.java | 12 ++++---- .../src/mage/cards/k/KarplusanMinotaur.java | 30 ++++++++----------- Mage.Sets/src/mage/cards/l/LastCaress.java | 6 ++-- .../src/mage/cards/m/MinotaurTactician.java | 16 +++++----- .../src/mage/cards/p/PhyrexianEtchings.java | 6 ++-- .../src/mage/cards/r/RimefeatherOwl.java | 2 +- Mage.Sets/src/mage/cards/r/RonomUnicorn.java | 7 ++--- Mage.Sets/src/mage/cards/r/Rust.java | 2 +- .../src/mage/cards/s/ShimmeringMirage.java | 4 +-- Mage.Sets/src/mage/cards/s/SurgingAether.java | 7 +++-- Mage.Sets/src/mage/cards/t/TranquilPath.java | 5 ++-- .../src/mage/cards/u/UnnaturalSelection.java | 2 +- .../common/CantBeRegeneratedSourceEffect.java | 2 +- .../effects/common/ExileSourceEffect.java | 2 +- .../RevealLibraryPutIntoHandEffect.java | 2 +- .../BecomesBasicLandTargetEffect.java | 2 +- ...BecomesChosenCreatureTypeTargetEffect.java | 2 +- .../continuous/BecomesColorTargetEffect.java | 20 +++++++------ .../abilities/keyword/ProtectionAbility.java | 3 +- .../mage/abilities/keyword/RippleAbility.java | 8 ++--- .../main/java/mage/filter/StaticFilters.java | 1 + .../filter/common/FilterBlockingCreature.java | 5 ++-- 37 files changed, 124 insertions(+), 126 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java index fe9bd4e47b..95e308c9f3 100644 --- a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java +++ b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java @@ -87,7 +87,7 @@ public class AgelessSentinels extends CardImpl { public AgelessSentinelsEffect() { super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); - staticText = "it becomes a Bird Giant, "; + staticText = "it becomes a Bird Giant,"; } public AgelessSentinelsEffect(final AgelessSentinelsEffect effect) { diff --git a/Mage.Sets/src/mage/cards/a/AlphaStatus.java b/Mage.Sets/src/mage/cards/a/AlphaStatus.java index 3e106f9fab..9701f4a523 100644 --- a/Mage.Sets/src/mage/cards/a/AlphaStatus.java +++ b/Mage.Sets/src/mage/cards/a/AlphaStatus.java @@ -109,6 +109,6 @@ class AlphaStatusDynamicValue implements DynamicValue { @Override public String getMessage() { - return "each other creature on the battlefield that shares a creature type with it"; + return "other creature on the battlefield that shares a creature type with it"; } } diff --git a/Mage.Sets/src/mage/cards/a/AncientOoze.java b/Mage.Sets/src/mage/cards/a/AncientOoze.java index b1d652fff1..e6b1542c56 100644 --- a/Mage.Sets/src/mage/cards/a/AncientOoze.java +++ b/Mage.Sets/src/mage/cards/a/AncientOoze.java @@ -52,15 +52,17 @@ import mage.game.permanent.Permanent; public class AncientOoze extends CardImpl { public AncientOoze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.OOZE); - this.color.setGreen(true); + this.color.setGreen(true); this.power = new MageInt(0); this.toughness = new MageInt(0); - // Ancient Ooze's power and toughness are each equal to the total converted mana cost of other creatures you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new AncientOozePowerToughnessValue(), Duration.EndOfGame))); + // Ancient Ooze's power and toughness are each equal to the total converted mana cost of other creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new AncientOozePowerToughnessValue(), Duration.EndOfGame) + .setText("{this}'s power and toughness are each equal to the total converted mana cost of other creatures you control.") + )); } public AncientOoze(final AncientOoze card) { @@ -74,12 +76,12 @@ public class AncientOoze extends CardImpl { } class AncientOozePowerToughnessValue implements DynamicValue { - + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { int value = 0; - for(Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), sourceAbility.getControllerId(), game)){ - if(creature != null && !sourceAbility.getSourceId().equals(creature.getId())){ + for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), sourceAbility.getControllerId(), game)) { + if (creature != null && !sourceAbility.getSourceId().equals(creature.getId())) { value += creature.getConvertedManaCost(); } } diff --git a/Mage.Sets/src/mage/cards/b/BlackCarriage.java b/Mage.Sets/src/mage/cards/b/BlackCarriage.java index 98e36a38c4..1c6908c9af 100644 --- a/Mage.Sets/src/mage/cards/b/BlackCarriage.java +++ b/Mage.Sets/src/mage/cards/b/BlackCarriage.java @@ -52,21 +52,21 @@ import mage.target.common.TargetControlledCreaturePermanent; public class BlackCarriage extends CardImpl { public BlackCarriage(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.HORSE); this.power = new MageInt(4); this.toughness = new MageInt(4); // Trample this.addAbility(TrampleAbility.getInstance()); - + // Black Carriage doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Sacrifice a creature: Untap Black Carriage. Activate this ability only during your upkeep. - this.addAbility(new ConditionalActivatedAbility(Zone.BATTLEFIELD, + this.addAbility(new ConditionalActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))), - new IsStepCondition(PhaseStep.UPKEEP), null)); + new IsStepCondition(PhaseStep.UPKEEP), "Sacrifice a creature: Untap {this}. Activate this ability only during your upkeep.")); } public BlackCarriage(final BlackCarriage card) { diff --git a/Mage.Sets/src/mage/cards/b/BrownOuphe.java b/Mage.Sets/src/mage/cards/b/BrownOuphe.java index 0e8014f032..1810831dd0 100644 --- a/Mage.Sets/src/mage/cards/b/BrownOuphe.java +++ b/Mage.Sets/src/mage/cards/b/BrownOuphe.java @@ -53,7 +53,7 @@ import java.util.UUID; */ public class BrownOuphe extends CardImpl { - private final static FilterStackObject filter = new FilterStackObject("ability from an artifact source"); + private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { filter.add(new ArtifactSourcePredicate()); diff --git a/Mage.Sets/src/mage/cards/c/CabalConditioning.java b/Mage.Sets/src/mage/cards/c/CabalConditioning.java index bd96b2cd0f..5ac53f18b1 100644 --- a/Mage.Sets/src/mage/cards/c/CabalConditioning.java +++ b/Mage.Sets/src/mage/cards/c/CabalConditioning.java @@ -42,10 +42,12 @@ import mage.target.TargetPlayer; public class CabalConditioning extends CardImpl { public CabalConditioning(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{B}"); // Any number of target players each discard a number of cards equal to the highest converted mana cost among permanents you control. - this.getSpellAbility().addEffect(new DiscardTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new DiscardTargetEffect(new HighestConvertedManaCostValue()) + .setText("Any number of target players each discard a number of cards equal to the highest converted mana cost among permanents you control.") + ); this.getSpellAbility().addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); } diff --git a/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java b/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java index f8c2be4edd..5022878c6f 100644 --- a/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java +++ b/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java @@ -53,7 +53,7 @@ import mage.game.permanent.Permanent; public class ClergyOfTheHolyNimbus extends CardImpl { public ClergyOfTheHolyNimbus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); @@ -61,7 +61,7 @@ public class ClergyOfTheHolyNimbus extends CardImpl { // If Clergy of the Holy Nimbus would be destroyed, regenerate it. this.addAbility(new SimpleStaticAbility(Zone.ALL, new ClergyOfTheHolyNimbusReplacementEffect())); - + // {1}: Clergy of the Holy Nimbus can't be regenerated this turn. Only any opponent may activate this ability. this.addAbility(new ActivateOnlyByOpponentActivatedAbility(Zone.BATTLEFIELD, new CantBeRegeneratedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}"))); } @@ -90,7 +90,7 @@ class ClergyOfTheHolyNimbusReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent ClergyOfTheHolyNimbus = game.getPermanent(event.getTargetId()); - if (ClergyOfTheHolyNimbus != null + if (ClergyOfTheHolyNimbus != null && event.getAmount() == 0) { // 1=noRegen if (ClergyOfTheHolyNimbus.regenerate(source.getSourceId(), game)) { game.informPlayers(source.getSourceObject(game).getName() + " has been regenerated."); @@ -116,4 +116,4 @@ class ClergyOfTheHolyNimbusReplacementEffect extends ReplacementEffectImpl { return new ClergyOfTheHolyNimbusReplacementEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index 811512b53e..a5e996cd2d 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -45,7 +45,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetControlledCreaturePermanent; /** * @@ -59,7 +59,7 @@ public class CoalitionFlag extends CardImpl { this.subtype.add(SubType.AURA); // Enchant creature you control - TargetPermanent auraTarget = new TargetCreaturePermanent(); + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); diff --git a/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java b/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java index 07fa354c4a..464864afe5 100644 --- a/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java +++ b/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java @@ -71,6 +71,7 @@ public class DaughterOfAutumn extends CardImpl { // {W}: The next 1 damage that would be dealt to target white creature this turn is dealt to Daughter of Autumn instead. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DaughterOfAutumnPreventDamageTargetEffect(Duration.EndOfTurn, 1), new ManaCostsImpl("{W}")); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); } public DaughterOfAutumn(final DaughterOfAutumn card) { diff --git a/Mage.Sets/src/mage/cards/d/DivineLight.java b/Mage.Sets/src/mage/cards/d/DivineLight.java index 3035f362f8..ca3e4380ec 100644 --- a/Mage.Sets/src/mage/cards/d/DivineLight.java +++ b/Mage.Sets/src/mage/cards/d/DivineLight.java @@ -50,10 +50,12 @@ public class DivineLight extends CardImpl { } public DivineLight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Prevent all damage that would be dealt this turn to creatures you control. - this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter)); + this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter) + .setText("Prevent all damage that would be dealt this turn to creatures you control.") + ); } public DivineLight(final DivineLight card) { diff --git a/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java b/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java index 41403091af..9cb25e7bf9 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java @@ -46,18 +46,18 @@ import mage.filter.predicate.mageobject.ColorPredicate; /** * * @author LoneFox - + * */ public class DwarvenPatrol extends CardImpl { - private static final FilterSpell filter = new FilterSpell("nonred spell"); + private static final FilterSpell filter = new FilterSpell("a nonred spell"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.RED))); } public DwarvenPatrol(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.DWARF); this.power = new MageInt(4); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/g/GreatDefender.java b/Mage.Sets/src/mage/cards/g/GreatDefender.java index d7c8a83240..101c127b17 100644 --- a/Mage.Sets/src/mage/cards/g/GreatDefender.java +++ b/Mage.Sets/src/mage/cards/g/GreatDefender.java @@ -48,7 +48,9 @@ public class GreatDefender extends CardImpl { // Target creature gets +0/+X until end of turn, where X is its converted mana cost. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true) + .setText("Target creature gets +0/+X until end of turn, where X is its converted mana cost.") + ); } public GreatDefender(final GreatDefender card) { diff --git a/Mage.Sets/src/mage/cards/i/IceCave.java b/Mage.Sets/src/mage/cards/i/IceCave.java index 4a8234f99a..188f79f42b 100644 --- a/Mage.Sets/src/mage/cards/i/IceCave.java +++ b/Mage.Sets/src/mage/cards/i/IceCave.java @@ -52,11 +52,10 @@ import mage.players.Player; public class IceCave extends CardImpl { public IceCave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); // Whenever a player casts a spell, any other player may pay that spell's mana cost. If a player does, counter the spell. (Mana cost includes color.) - this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new IceCaveEffect(), StaticFilters.FILTER_SPELL, false, SetTargetPointer.SPELL)); + this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new IceCaveEffect(), StaticFilters.FILTER_A_SPELL, false, SetTargetPointer.SPELL)); } public IceCave(final IceCave card) { @@ -90,17 +89,17 @@ class IceCaveEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Spell spell = (Spell) game.getStack().getStackObject(targetPointer.getFirst(game, source)); - if(sourcePermanent != null && spell != null && controller != null) { + if (sourcePermanent != null && spell != null && controller != null) { Player spellController = game.getPlayer(spell.getControllerId()); Cost cost = new ManaCostsImpl(spell.getSpellAbility().getManaCosts().getText()); - if(spellController != null) { + if (spellController != null) { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - if(player != null && player != spellController) { + if (player != null && player != spellController) { cost.clearPaid(); - if(cost.canPay(source, source.getSourceId(), player.getId(), game) + if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(outcome, "Pay " + cost.getText() + " to counter " + spell.getIdName() + '?', source, game)) { - if(cost.pay(source, game, source.getSourceId(), playerId, false, null)) { + if (cost.pay(source, game, source.getSourceId(), playerId, false, null)) { game.informPlayers(player.getLogName() + " pays" + cost.getText() + " to counter " + spell.getIdName() + '.'); game.getStack().counter(spell.getId(), source.getSourceId(), game); return true; diff --git a/Mage.Sets/src/mage/cards/i/Illuminate.java b/Mage.Sets/src/mage/cards/i/Illuminate.java index a357d8f9a4..9ee484a69a 100644 --- a/Mage.Sets/src/mage/cards/i/Illuminate.java +++ b/Mage.Sets/src/mage/cards/i/Illuminate.java @@ -47,7 +47,7 @@ import mage.target.common.TargetCreaturePermanent; public class Illuminate extends CardImpl { public Illuminate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); // Kicker {2}{R} and/or {3}{U} KickerAbility kickerAbility = new KickerAbility("{2}{R}"); @@ -57,13 +57,13 @@ public class Illuminate extends CardImpl { this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue())); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetControllerEffect(new ManacostVariableValue()), - new KickedCostCondition("{2}{R}"), - "If {this} was kicked with its {2}{R} kicker, it deals X damage to that creature's controller.")); + new DamageTargetControllerEffect(new ManacostVariableValue()), + new KickedCostCondition("{2}{R}"), + "If {this} was kicked with its {2}{R} kicker, it deals X damage to that creature's controller.")); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DrawCardSourceControllerEffect(new ManacostVariableValue()), - new KickedCostCondition("{3}{U}"), - "If {this} was kicked with its {3}{U} kicker, you draw X cards.")); + new DrawCardSourceControllerEffect(new ManacostVariableValue()), + new KickedCostCondition("{3}{U}"), + " If {this} was kicked with its {3}{U} kicker, you draw X cards.")); } diff --git a/Mage.Sets/src/mage/cards/j/Jilt.java b/Mage.Sets/src/mage/cards/j/Jilt.java index 799208d43d..2f3d30c68e 100644 --- a/Mage.Sets/src/mage/cards/j/Jilt.java +++ b/Mage.Sets/src/mage/cards/j/Jilt.java @@ -53,11 +53,11 @@ import mage.target.targetpointer.SecondTargetPointer; public class Jilt extends CardImpl { public Jilt(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Kicker {1}{R} this.addAbility(new KickerAbility("{1}{R}")); - + // Return target creature to its owner's hand. If Jilt was kicked, it deals 2 damage to another target creature. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); Effect effect = new ConditionalOneShotEffect( @@ -66,11 +66,11 @@ public class Jilt extends CardImpl { "If {this} was kicked, it deals 2 damage to another target creature"); effect.setTargetPointer(new SecondTargetPointer()); this.getSpellAbility().addEffect(effect); - Target target = new TargetCreaturePermanent(new FilterCreaturePermanent("Target Creature: returned to Hand")); + Target target = new TargetCreaturePermanent(); target.setTargetTag(1); this.getSpellAbility().addTarget(target); } - + @Override public void adjustTargets(Ability ability, Game game) { if (ability instanceof SpellAbility && KickedCondition.instance.apply(game, ability)) { diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 87ce51cb02..3a785aa071 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -59,26 +59,26 @@ import java.util.UUID; public class Jokulmorder extends CardImpl { public Jokulmorder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}{U}"); this.subtype.add(SubType.LEVIATHAN); this.power = new MageInt(12); this.toughness = new MageInt(12); // Trample this.addAbility(TrampleAbility.getInstance()); - + // Jokulmorder enters the battlefield tapped. this.addAbility(new EntersBattlefieldTappedAbility()); - + // When Jokulmorder enters the battlefield, sacrifice it unless you sacrifice five lands. Effect effect = new SacrificeSourceUnlessPaysEffect( new SacrificeTargetCost(new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("five lands"), true))); effect.setText("sacrifice it unless you sacrifice five lands"); this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false)); - + // Jokulmorder doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Whenever you play an Island, you may untap Jokulmorder. this.addAbility(new JokulmorderTriggeredAbility()); } @@ -122,6 +122,6 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When you play an Island, you may untap {this}"; + return "Whenever you play an Island, you may untap {this}"; } } diff --git a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java index 8d21319da3..a244cd23b1 100644 --- a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java +++ b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java @@ -32,20 +32,15 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; -import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.CumulativeUpkeepAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; -import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -60,7 +55,7 @@ import mage.target.common.TargetOpponent; public class KarplusanMinotaur extends CardImpl { public KarplusanMinotaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.MINOTAUR); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(3); @@ -68,7 +63,7 @@ public class KarplusanMinotaur extends CardImpl { // Cumulative upkeep-Flip a coin. this.addAbility(new CumulativeUpkeepAbility(new KarplusanMinotaurCost())); - + // Whenever you win a coin flip, Karplusan Minotaur deals 1 damage to target creature or player. Ability abilityWin = new KarplusanMinotaurFlipWinTriggeredAbility(); abilityWin.addTarget(new TargetCreatureOrPlayer()); @@ -80,23 +75,22 @@ public class KarplusanMinotaur extends CardImpl { abilityLose.addTarget(new TargetCreatureOrPlayer()); this.addAbility(abilityLose); } - + @Override public void adjustTargets(Ability ability, Game game) { if (ability instanceof KarplusanMinotaurFlipLoseTriggeredAbility) { Player controller = game.getPlayer(ability.getControllerId()); - if(controller != null) { + if (controller != null) { UUID opponentId = null; - if(game.getOpponents(controller.getId()).size() > 1) { + if (game.getOpponents(controller.getId()).size() > 1) { Target target = new TargetOpponent(true); - if(controller.chooseTarget(Outcome.Neutral, target, ability, game)) { + if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) { opponentId = target.getFirstTarget(); } - } - else { + } else { opponentId = game.getOpponents(controller.getId()).iterator().next(); } - if(opponentId != null) { + if (opponentId != null) { ability.getTargets().get(0).setTargetController(opponentId); } } @@ -171,12 +165,12 @@ class KarplusanMinotaurFlipLoseTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you lose a coin flip, {this} deals 1 damage to target creature or player of an opponent's choice"; + return "Whenever you lose a coin flip, {this} deals 1 damage to target creature or player of an opponent's choice."; } } class KarplusanMinotaurCost extends CostImpl { - + KarplusanMinotaurCost() { this.text = "Flip a coin"; } @@ -188,7 +182,7 @@ class KarplusanMinotaurCost extends CostImpl { controller.flipCoin(game); this.paid = true; return true; - } + } return false; } @@ -202,7 +196,7 @@ class KarplusanMinotaurCost extends CostImpl { } return false; } - + @Override public KarplusanMinotaurCost copy() { return new KarplusanMinotaurCost(); diff --git a/Mage.Sets/src/mage/cards/l/LastCaress.java b/Mage.Sets/src/mage/cards/l/LastCaress.java index 3bc5473e34..e4652239ec 100644 --- a/Mage.Sets/src/mage/cards/l/LastCaress.java +++ b/Mage.Sets/src/mage/cards/l/LastCaress.java @@ -43,12 +43,12 @@ import mage.target.TargetPlayer; public class LastCaress extends CardImpl { public LastCaress(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); this.getSpellAbility().addEffect(new LoseLifeTargetEffect(1)); this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new GainLifeEffect(1)); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new GainLifeEffect(1).setText("and you gain 1 life")); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public LastCaress(final LastCaress card) { diff --git a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java index 27413e44db..c3e1cfbbe5 100644 --- a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java +++ b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java @@ -52,33 +52,33 @@ import java.util.UUID; * @author fireshoes */ public class MinotaurTactician extends CardImpl { - + private static final FilterControlledCreaturePermanent filterWhite = new FilterControlledCreaturePermanent(); private static final FilterControlledCreaturePermanent filterBlue = new FilterControlledCreaturePermanent(); - + static { filterWhite.add(new ColorPredicate(ObjectColor.WHITE)); filterBlue.add(new ColorPredicate(ObjectColor.BLUE)); } - + static final private String ruleWhite = "{this} gets +1/+1 as long as you control another white creature"; - - static final private String ruleBlue = "{this} gets +1/+1 as long as you control another white creature"; + + static final private String ruleBlue = "{this} gets +1/+1 as long as you control another blue creature"; public MinotaurTactician(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.MINOTAUR); this.power = new MageInt(1); this.toughness = new MageInt(1); // Haste this.addAbility(HasteAbility.getInstance()); - + // Minotaur Tactician gets +1/+1 as long as you control a white creature. Condition conditionWhite = new PermanentsOnTheBattlefieldCondition(filterWhite); Effect effectWhite = new ConditionalContinuousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), conditionWhite, ruleWhite); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effectWhite)); - + // Minotaur Tactician gets +1/+1 as long as you control a blue creature. Condition conditionBlue = new PermanentsOnTheBattlefieldCondition(filterBlue); Effect effectBlue = new ConditionalContinuousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), conditionBlue, ruleBlue); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java index 7734e59a99..bbf7e70191 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java @@ -28,11 +28,9 @@ package mage.cards.p; import java.util.UUID; -import mage.MageInt; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -59,7 +57,9 @@ public class PhyrexianEtchings extends CardImpl { this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.AGE)), false)); // When Phyrexian Etchings is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)))); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) + .setText("When {this} is put into a graveyard from the battlefield, you lose 2 life for each age counter on it") + )); } public PhyrexianEtchings(final PhyrexianEtchings card) { diff --git a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java index 9e89292b85..2b6e660201 100644 --- a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java +++ b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java @@ -135,6 +135,6 @@ class RimefeatherOwlEffect extends ContinuousEffectImpl { @Override public String getText(Mode mode) { - return "All nonland permanents are legendary"; + return "Permanents with ice counters on them are snow."; } } diff --git a/Mage.Sets/src/mage/cards/r/RonomUnicorn.java b/Mage.Sets/src/mage/cards/r/RonomUnicorn.java index bfcfb18f58..fe12934ca4 100644 --- a/Mage.Sets/src/mage/cards/r/RonomUnicorn.java +++ b/Mage.Sets/src/mage/cards/r/RonomUnicorn.java @@ -37,10 +37,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; import java.util.UUID; +import mage.target.common.TargetEnchantmentPermanent; /** * @@ -49,14 +48,14 @@ import java.util.UUID; public class RonomUnicorn extends CardImpl { public RonomUnicorn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.UNICORN); this.power = new MageInt(2); this.toughness = new MageInt(2); // Sacrifice Ronom Unicorn: Destroy target enchantment. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new SacrificeSourceCost()); - ability.addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); + ability.addTarget(new TargetEnchantmentPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Rust.java b/Mage.Sets/src/mage/cards/r/Rust.java index c1f5f4edc9..21dd121bf9 100644 --- a/Mage.Sets/src/mage/cards/r/Rust.java +++ b/Mage.Sets/src/mage/cards/r/Rust.java @@ -46,7 +46,7 @@ import mage.target.common.TargetActivatedOrTriggeredAbility; */ public class Rust extends CardImpl { - private final static FilterStackObject filter = new FilterStackObject("ability from an artifact source"); + private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { filter.add(new ArtifactSourcePredicate()); diff --git a/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java b/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java index 273b7bcb0f..47761a07bd 100644 --- a/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java +++ b/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java @@ -43,13 +43,13 @@ import mage.target.common.TargetLandPermanent; public class ShimmeringMirage extends CardImpl { public ShimmeringMirage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Target land becomes the basic land type of your choice until end of turn. this.getSpellAbility().addEffect(new BecomesBasicLandTargetEffect(Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetLandPermanent()); // Draw a card. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public ShimmeringMirage(final ShimmeringMirage card) { diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index bb9a0b3a5f..1db14c65ce 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -42,13 +42,14 @@ import mage.target.TargetPermanent; public class SurgingAether extends CardImpl { public SurgingAether(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); - // Ripple 4 - this.addAbility(new RippleAbility(4)); // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent()); + + // Ripple 4 + this.addAbility(new RippleAbility(4)); } public SurgingAether(final SurgingAether card) { diff --git a/Mage.Sets/src/mage/cards/t/TranquilPath.java b/Mage.Sets/src/mage/cards/t/TranquilPath.java index de90b5056b..04d214cd1e 100644 --- a/Mage.Sets/src/mage/cards/t/TranquilPath.java +++ b/Mage.Sets/src/mage/cards/t/TranquilPath.java @@ -42,13 +42,12 @@ import mage.filter.common.FilterEnchantmentPermanent; public class TranquilPath extends CardImpl { public TranquilPath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}"); // Destroy all enchantments. this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterEnchantmentPermanent("enchantments"))); // Draw a card. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public TranquilPath(final TranquilPath card) { diff --git a/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java b/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java index d069036dbf..aabc4cf8ff 100644 --- a/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java +++ b/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java @@ -45,7 +45,7 @@ import mage.target.common.TargetCreaturePermanent; public class UnnaturalSelection extends CardImpl { public UnnaturalSelection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); // {1}: Choose a creature type other than Wall. Target creature becomes that type until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesChosenCreatureTypeTargetEffect(true), new GenericManaCost(1)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java index 5d21c6e346..ad1aca5584 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java @@ -78,7 +78,7 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect return staticText; } StringBuilder sb = new StringBuilder(); - sb.append(" {this} can't be regenerated"); + sb.append("{this} can't be regenerated"); if (!duration.toString().isEmpty()) { sb.append(' '); if (duration == Duration.EndOfTurn) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java index 60efb497e9..455d3a5466 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java @@ -57,7 +57,7 @@ public class ExileSourceEffect extends OneShotEffect { */ public ExileSourceEffect(boolean toUniqueExileZone) { super(Outcome.Exile); - staticText = "Exile {this}"; + staticText = "exile {this}"; this.toUniqueExileZone = toUniqueExileZone; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java index 5d8965fde1..d0b5710466 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java @@ -117,7 +117,7 @@ public class RevealLibraryPutIntoHandEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("Reveal the top "); + StringBuilder sb = new StringBuilder("reveal the top "); sb.append(CardUtil.numberToText(amountCards.toString())).append(" cards of your library. Put all "); sb.append(filter.getMessage()); sb.append(" revealed this way into your hand and the rest "); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java index e843082305..4d0bb0703e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java @@ -191,7 +191,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl { private String setText() { StringBuilder sb = new StringBuilder(); if (chooseLandType) { - sb.append("Target land becomes the basic land type of your choice "); + sb.append("Target land becomes the basic land type of your choice"); } else { sb.append("Target land becomes a "); int i = 1; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index 6a21fcf093..d97d8f9ea9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -26,7 +26,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { super(Outcome.BoostCreature); this.nonWall = nonWall; if(nonWall) { - staticText = "choose a creature type other than wall, target creature's type becomes that type until end of turn"; + staticText = "choose a creature type other than wall. Target creature becomes that type until end of turn"; } else { staticText = "target creature becomes the creature type of your choice until end of turn"; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java index abf36d2d3a..c437a9404f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java @@ -52,12 +52,13 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { /** * Set the color of a spell or permanent - * - * @param duration + * + * @param duration */ public BecomesColorTargetEffect(Duration duration) { this(null, duration, null); } + public BecomesColorTargetEffect(ObjectColor setColor, Duration duration) { this(setColor, duration, null); } @@ -78,7 +79,7 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return; - } + } if (setColor == null) { ChoiceColor choice = new ChoiceColor(); while (!choice.isChosen()) { @@ -95,9 +96,8 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { if (!game.isSimulation()) { game.informPlayers(controller.getLogName() + " has chosen the color: " + setColor.toString()); } - } - - + } + super.init(source, game); //To change body of generated methods, choose Tools | Templates. } @@ -109,11 +109,11 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { } if (setColor != null) { boolean objectFound = false; - for (UUID targetId :targetPointer.getTargets(game, source)) { + for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject targetObject = game.getObject(targetId); if (targetObject != null) { objectFound = true; - targetObject.getColor(game).setColor(setColor); + targetObject.getColor(game).setColor(setColor); } } if (!objectFound && this.getDuration() == Duration.Custom) { @@ -143,7 +143,9 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { } else { sb.append(setColor.getDescription()); } - sb.append(' ').append(duration.toString()); + if (!duration.toString().equals("")) { + sb.append(' ').append(duration.toString()); + } return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java index 1e8c5adc2b..46471af292 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java @@ -32,7 +32,6 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.StaticAbility; import mage.cards.Card; -import mage.constants.CardType; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterCard; @@ -90,7 +89,7 @@ public class ProtectionAbility extends StaticAbility { @Override public String getRule() { - return "Protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); + return "protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); } public boolean canTarget(MageObject source, Game game) { diff --git a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java index dde3a57961..cf70a57336 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java @@ -56,13 +56,11 @@ public class RippleAbility extends TriggeredAbilityImpl { return new RippleAbility(this); } - @Override public String getRule() { - return "Ripple " + rippleNumber + " (When you cast this spell, you may reveal the top " + CardUtil.numberToText(rippleNumber) + " cards of your library. You may cast any revealed cards with the same name as this spell without paying their mana costs. Put the rest on the bottom of your library.)"; + return "ripple " + rippleNumber + " (When you cast this spell, you may reveal the top " + CardUtil.numberToText(rippleNumber) + " cards of your library. You may cast any revealed cards with the same name as this spell without paying their mana costs. Put the rest on the bottom of your library.)"; } - } class RippleEffect extends OneShotEffect { @@ -84,13 +82,12 @@ class RippleEffect extends OneShotEffect { return new RippleEffect(this); } - @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null) { - if (!player.chooseUse(Outcome.Neutral, "Reveal " + rippleNumber + " cards from the top of your library?", source, game)){ + if (!player.chooseUse(Outcome.Neutral, "Reveal " + rippleNumber + " cards from the top of your library?", source, game)) { return true; //fizzle } // reveal to/**/p cards from library @@ -123,4 +120,3 @@ class RippleEffect extends OneShotEffect { } } - diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 42676a1b12..60c7d931a3 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -69,6 +69,7 @@ public final class StaticFilters { = (FilterSpell) new FilterSpell("noncreature spell").add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); public static final FilterSpell FILTER_SPELL = new FilterSpell(); + public static final FilterSpell FILTER_A_SPELL = new FilterSpell("a spell"); public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELL = new FilterSpell("instant or sorcery spell"); public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELLS = new FilterSpell("instant or sorcery spells"); diff --git a/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java b/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java index 7e6aa11769..896517c0bf 100644 --- a/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java +++ b/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java @@ -24,8 +24,7 @@ * 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.filter.common; import mage.filter.predicate.permanent.BlockingPredicate; @@ -37,7 +36,7 @@ import mage.filter.predicate.permanent.BlockingPredicate; public class FilterBlockingCreature extends FilterCreaturePermanent { public FilterBlockingCreature() { - this("Blocking creature"); + this("blocking creature"); } public FilterBlockingCreature(String name) { From 00755356502810ccab90198c39fdc0e0cd2e1a7f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 22:00:06 -0400 Subject: [PATCH 004/164] so many text fixes --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 2 +- .../src/mage/cards/b/BellowingAegisaur.java | 2 +- .../src/mage/cards/c/CaptivatingCrew.java | 2 +- .../src/mage/cards/d/DarienKingOfKjeldor.java | 7 ++++--- Mage.Sets/src/mage/cards/d/DralnusPet.java | 4 ++-- .../src/mage/cards/d/DreamcallerSiren.java | 2 +- .../src/mage/cards/d/DroverOfTheMighty.java | 2 +- .../src/mage/cards/f/FathomFleetCaptain.java | 2 +- .../src/mage/cards/f/FreyalisesRadiance.java | 2 +- Mage.Sets/src/mage/cards/g/GaeasMight.java | 5 +++-- .../src/mage/cards/h/HierophantsChalice.java | 2 +- .../mage/cards/h/HuatliDinosaurKnight.java | 4 +++- .../mage/cards/j/JaceIngeniousMindMage.java | 6 +++--- Mage.Sets/src/mage/cards/j/JacesSentinel.java | 2 +- Mage.Sets/src/mage/cards/j/Jokulmorder.java | 2 +- .../src/mage/cards/k/KrovikanWhispers.java | 7 +++---- .../src/mage/cards/l/LightningStorm.java | 4 ++-- .../src/mage/cards/l/LookoutsDispersal.java | 2 +- .../src/mage/cards/m/MakeshiftMunitions.java | 2 +- .../src/mage/cards/m/MaliciousAdvice.java | 6 +++--- .../src/mage/cards/m/MaraudingLooter.java | 2 +- .../src/mage/cards/m/MarchOfTheDrowned.java | 3 +-- Mage.Sets/src/mage/cards/m/MercurialKite.java | 4 ++-- .../src/mage/cards/m/MinotaurTactician.java | 4 ++-- .../src/mage/cards/p/PhyrexianEtchings.java | 2 +- .../src/mage/cards/p/PhyrexianTyranny.java | 2 +- .../mage/cards/p/PriestOfTheWakeningSun.java | 2 +- Mage.Sets/src/mage/cards/r/RaidersWake.java | 2 +- .../src/mage/cards/r/RavenGuildInitiate.java | 2 +- Mage.Sets/src/mage/cards/r/RazingSnidd.java | 6 +++--- Mage.Sets/src/mage/cards/r/RegisaurAlpha.java | 2 +- Mage.Sets/src/mage/cards/r/RevelInRiches.java | 2 +- Mage.Sets/src/mage/cards/r/RiggingRunner.java | 2 +- .../src/mage/cards/r/RimefeatherOwl.java | 7 ++++++- Mage.Sets/src/mage/cards/r/RuthlessKnave.java | 2 +- Mage.Sets/src/mage/cards/s/SamitePilgrim.java | 4 ++-- Mage.Sets/src/mage/cards/s/SanctumSeeker.java | 2 +- .../src/mage/cards/s/ShipwreckLooter.java | 2 +- Mage.Sets/src/mage/cards/s/SirensRuse.java | 2 +- .../src/mage/cards/s/SkyshipWeatherlight.java | 6 +++--- .../src/mage/cards/s/SnappingSailback.java | 2 +- Mage.Sets/src/mage/cards/s/SpellSwindle.java | 2 +- .../src/mage/cards/s/StarOfExtinction.java | 2 +- .../src/mage/cards/s/SunbirdsInvocation.java | 10 +++++++++ Mage.Sets/src/mage/cards/s/Sunscour.java | 7 ++++--- Mage.Sets/src/mage/cards/s/SurgingAether.java | 6 +++--- Mage.Sets/src/mage/cards/t/TempestCaller.java | 2 +- Mage.Sets/src/mage/cards/u/UrzasGuilt.java | 5 ++--- .../src/mage/cards/v/VanquishersBanner.java | 2 +- .../src/mage/cards/v/VeldraneOfSengir.java | 6 +++--- .../src/mage/cards/v/VerdantSunsAvatar.java | 4 ++-- .../src/mage/cards/v/VraskaRelicSeeker.java | 2 +- .../src/mage/cards/w/WakerOfTheWilds.java | 10 +++++++-- .../src/mage/cards/w/WaterspoutElemental.java | 2 +- .../abilities/common/CantBlockAbility.java | 2 +- .../condition/common/RaidCondition.java | 5 ++++- .../common/CantBeRegeneratedSourceEffect.java | 1 - .../common/LookLibraryControllerEffect.java | 2 +- ...PreventAllDamageByAllPermanentsEffect.java | 18 ++++++++++++---- .../common/PreventDamageToSourceEffect.java | 8 ++++++- .../TapAllTargetPlayerControlsEffect.java | 9 ++++---- .../combat/CantBlockAttachedEffect.java | 5 ++++- ...BecomesChosenCreatureTypeTargetEffect.java | 2 +- .../continuous/BecomesCreatureAllEffect.java | 3 +-- .../GainAbilityControlledSpellsEffect.java | 2 +- .../common/counter/AddCountersAllEffect.java | 3 ++- ...SearchLibraryGraveyardPutInHandEffect.java | 2 +- .../abilities/keyword/DeathtouchAbility.java | 7 ++----- .../mage/abilities/keyword/FearAbility.java | 10 ++++----- .../keyword/IndestructibleAbility.java | 21 +++++++++---------- 70 files changed, 163 insertions(+), 126 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index 5b92f7cd1f..cd291187e8 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -56,7 +56,7 @@ import java.util.*; */ public class AdmiralBeckettBrass extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other Pirates you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Pirates you control"); private static final FilterNonlandPermanent filter2 = new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"); static { diff --git a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java index 7c2db5f657..e7dbc3daa4 100644 --- a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java +++ b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java @@ -49,7 +49,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class BellowingAegisaur extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each other creature you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature you control"); static { filter.add(new ControllerPredicate(TargetController.YOU)); diff --git a/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java b/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java index 5e90f4283d..ae87461a4f 100644 --- a/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java +++ b/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java @@ -54,7 +54,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class CaptivatingCrew extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("target creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); diff --git a/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java b/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java index 5aa34573f3..3581920ec0 100644 --- a/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java +++ b/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java @@ -53,7 +53,7 @@ import mage.players.Player; public class DarienKingOfKjeldor extends CardImpl { public DarienKingOfKjeldor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -74,6 +74,7 @@ public class DarienKingOfKjeldor extends CardImpl { return new DarienKingOfKjeldor(this); } } + class DarienKingOfKjeldorTriggeredAbility extends TriggeredAbilityImpl { public DarienKingOfKjeldorTriggeredAbility() { @@ -105,7 +106,7 @@ class DarienKingOfKjeldorTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you are dealt damage, you may create that many 1/1 white Soldier creature tokens."; + return "Whenever you're dealt damage, you may create that many 1/1 white Soldier creature tokens."; } } @@ -133,4 +134,4 @@ class DarienKingOfKjeldorEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DralnusPet.java b/Mage.Sets/src/mage/cards/d/DralnusPet.java index 267078de93..8627591833 100644 --- a/Mage.Sets/src/mage/cards/d/DralnusPet.java +++ b/Mage.Sets/src/mage/cards/d/DralnusPet.java @@ -65,7 +65,7 @@ import mage.players.Player; public class DralnusPet extends CardImpl { public DralnusPet(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.SHAPESHIFTER); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -77,7 +77,7 @@ public class DralnusPet extends CardImpl { this.addAbility(new KickerAbility(kickerCosts)); // If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost. Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.instance, - "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost", ""); + "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java b/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java index 5677be80ed..67709860a0 100644 --- a/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java +++ b/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java @@ -84,7 +84,7 @@ public class DreamcallerSiren extends CardImpl { ability.addTarget(new TargetNonlandPermanent(0, 2, false)); this.addAbility(new ConditionalTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(filter), - "when {this} enters the battlefield, if you control another Pirate, tap up to two nonland permanents.")); + "when {this} enters the battlefield, if you control another Pirate, tap up to two target nonland permanents.")); } public DreamcallerSiren(final DreamcallerSiren card) { diff --git a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java index a9b0bb1bb6..43a6e62840 100644 --- a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java +++ b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java @@ -46,7 +46,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class DroverOfTheMighty extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("a Dinosaur"); + private static final FilterPermanent filter = new FilterPermanent("Dinosaur"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java index 72f6e09eae..9d7913136a 100644 --- a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java @@ -76,7 +76,7 @@ public class FathomFleetCaptain extends CardImpl { this.addAbility(new ConditionalTriggeredAbility( new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new PirateToken()), new GenericManaCost(2)), false), new PermanentsOnTheBattlefieldCondition(filter), - "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace")); + "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, create a 2/2 black Pirate creature token with menace")); } public FathomFleetCaptain(final FathomFleetCaptain card) { diff --git a/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java b/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java index f1beb8ac1e..ab44a4e85f 100644 --- a/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java +++ b/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java @@ -48,7 +48,7 @@ import mage.filter.predicate.mageobject.SupertypePredicate; */ public class FreyalisesRadiance extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(); + private static final FilterPermanent filter = new FilterPermanent("snow permanents"); static { filter.add(new SupertypePredicate(SuperType.SNOW)); diff --git a/Mage.Sets/src/mage/cards/g/GaeasMight.java b/Mage.Sets/src/mage/cards/g/GaeasMight.java index ad18c3dc5e..52daaeeabc 100644 --- a/Mage.Sets/src/mage/cards/g/GaeasMight.java +++ b/Mage.Sets/src/mage/cards/g/GaeasMight.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; @@ -43,12 +44,12 @@ import mage.target.common.TargetCreaturePermanent; public class GaeasMight extends CardImpl { public GaeasMight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); // Domain - Target creature gets +1/+1 until end of turn for each basic land type among lands you control. this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(), new DomainValue(), Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public GaeasMight(final GaeasMight card) { diff --git a/Mage.Sets/src/mage/cards/h/HierophantsChalice.java b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java index 7773026a68..73e175fd7c 100644 --- a/Mage.Sets/src/mage/cards/h/HierophantsChalice.java +++ b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java @@ -50,7 +50,7 @@ public class HierophantsChalice extends CardImpl { // When Hierophant's Chalice enters the battlefield, target opponent loses 1 life and you gain 1 life. Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(1), false); - ability.addEffect(new GainLifeEffect(1)); + ability.addEffect(new GainLifeEffect(1).setText("and you gain one life.")); Target target = new TargetOpponent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java b/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java index a7f28c381b..593d385681 100644 --- a/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java +++ b/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java @@ -74,7 +74,9 @@ public class HuatliDinosaurKnight extends CardImpl { this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +2: Put two +1/+1 counters on up to one target Dinosaur you control. - Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2); + Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)) + .setText("Put two +1/+1 counters on up to one target Dinosaur you control."), 2 + ); ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java index cfc7cfeb04..5d8fdb57f0 100644 --- a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java +++ b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java @@ -40,7 +40,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.SuperType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; +import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; /** @@ -61,11 +61,11 @@ public class JaceIngeniousMindMage extends CardImpl { this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1)); // +1: Untap all creatures you control. - this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(FILTER_PERMANENT_CREATURES), 1)); + this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURES), 1)); // -9: Gain control of up to three target creatures. Ability ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.Custom), -9); - ability.addTarget(new TargetCreaturePermanent(0, 3)); + ability.addTarget(new TargetCreaturePermanent(0, 3, StaticFilters.FILTER_PERMANENT_CREATURES, false)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JacesSentinel.java b/Mage.Sets/src/mage/cards/j/JacesSentinel.java index a9288ece7d..5d27ac6b60 100644 --- a/Mage.Sets/src/mage/cards/j/JacesSentinel.java +++ b/Mage.Sets/src/mage/cards/j/JacesSentinel.java @@ -77,7 +77,7 @@ public class JacesSentinel extends CardImpl { ability.addEffect(new ConditionalContinuousEffect( new CantBeBlockedSourceEffect(), new PermanentsOnTheBattlefieldCondition(filter), - "and has can't be blocked")); + "and can't be blocked")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 3a785aa071..99c8ba7525 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -122,6 +122,6 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you play an Island, you may untap {this}"; + return "Whenever you play an Island, you may untap {this}."; } } diff --git a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java index e454889dc4..06287397b1 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java @@ -28,7 +28,6 @@ package mage.cards.k; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; @@ -36,7 +35,6 @@ import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.costs.OrCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -76,7 +74,9 @@ public class KrovikanWhispers extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); // When Krovikan Whispers is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)))); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) + .setText("you lose 2 life for each age counter on it.") + )); } public KrovikanWhispers(final KrovikanWhispers card) { @@ -88,4 +88,3 @@ public class KrovikanWhispers extends CardImpl { return new KrovikanWhispers(this); } } - diff --git a/Mage.Sets/src/mage/cards/l/LightningStorm.java b/Mage.Sets/src/mage/cards/l/LightningStorm.java index 9c856fcada..c69e97fc88 100644 --- a/Mage.Sets/src/mage/cards/l/LightningStorm.java +++ b/Mage.Sets/src/mage/cards/l/LightningStorm.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class LightningStorm extends CardImpl { public LightningStorm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{R}"); // Lightning Storm deals X damage to target creature or player, where X is 3 plus the number of charge counters on it. Effect effect = new DamageTargetEffect(new LightningStormCountCondition(CounterType.CHARGE)); @@ -67,7 +67,7 @@ public class LightningStorm extends CardImpl { // Discard a land card: Put two charge counters on Lightning Storm. You may choose a new target for it. Any player may activate this ability but only if Lightning Storm is on the stack. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.STACK, new LightningStormAddCounterEffect(), - new DiscardTargetCost(new TargetCardInHand(new FilterLandCard()))); + new DiscardTargetCost(new TargetCardInHand(new FilterLandCard("a land card")))); ability.setMayActivate(TargetController.ANY); ability.addEffect(new InfoEffect("Any player may activate this ability but only if {this} is on the stack")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java index 556e32d4fd..2aa8d97464 100644 --- a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java +++ b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java @@ -49,7 +49,7 @@ import mage.target.TargetSpell; */ public class LookoutsDispersal extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Pirate"); static { filter.add(new SubtypePredicate(SubType.PIRATE)); diff --git a/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java b/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java index ca6c60abd1..2be6c83d59 100644 --- a/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java +++ b/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java @@ -49,7 +49,7 @@ import mage.target.common.TargetCreatureOrPlayer; */ public class MakeshiftMunitions extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature"); static { filter.add(Predicates.or( diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java index a9d044d72e..05479e1007 100644 --- a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java +++ b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java @@ -59,18 +59,18 @@ public class MaliciousAdvice extends CardImpl { } public MaliciousAdvice(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}{B}"); // Tap X target artifacts, creatures, and/or lands. You lose X life. Effect effect = new TapTargetEffect(); - effect.setText("Tap X target artifacts, creatures, and/or lands"); + effect.setText("X target artifacts, creatures, and/or lands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue())); } @Override public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { + if (ability instanceof SpellAbility) { ability.getTargets().clear(); ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter)); } diff --git a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java index c87a6297a6..609f05cdab 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java @@ -61,7 +61,7 @@ public class MaraudingLooter extends CardImpl { RaidCondition.instance, "Raid — At the beginning of your end step, " + "if you attacked with a creature this turn, " - + "you may draw a card. If you do, discard a card"); + + "you may draw a card. If you do, discard a card."); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java index 393917cb02..cd3f5d8513 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java @@ -30,7 +30,6 @@ package mage.cards.m; import java.util.UUID; import mage.abilities.Mode; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; -import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -57,7 +56,7 @@ public class MarchOfTheDrowned extends CardImpl { // Choose one — // &bull; Return target creature card from your graveyard to your hand. - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); // &bull; Return two target Pirate cards from your graveyard to your hand. Mode mode = new Mode(); diff --git a/Mage.Sets/src/mage/cards/m/MercurialKite.java b/Mage.Sets/src/mage/cards/m/MercurialKite.java index b20f7107ec..c359ce3197 100644 --- a/Mage.Sets/src/mage/cards/m/MercurialKite.java +++ b/Mage.Sets/src/mage/cards/m/MercurialKite.java @@ -46,7 +46,7 @@ import mage.constants.SubType; public class MercurialKite extends CardImpl { public MercurialKite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -56,7 +56,7 @@ public class MercurialKite extends CardImpl { // Whenever Mercurial Kite deals combat damage to a creature, tap that creature. That creature doesn't untap during its controller's next untap step. Ability ability; ability = new DealsDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), true, false, true); - ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(". That creature")); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("That creature")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java index c3e1cfbbe5..b9203d8288 100644 --- a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java +++ b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java @@ -61,9 +61,9 @@ public class MinotaurTactician extends CardImpl { filterBlue.add(new ColorPredicate(ObjectColor.BLUE)); } - static final private String ruleWhite = "{this} gets +1/+1 as long as you control another white creature"; + static final private String ruleWhite = "{this} gets +1/+1 as long as you control a white creature"; - static final private String ruleBlue = "{this} gets +1/+1 as long as you control another blue creature"; + static final private String ruleBlue = "{this} gets +1/+1 as long as you control a blue creature"; public MinotaurTactician(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java index bbf7e70191..7c1aa54950 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java @@ -58,7 +58,7 @@ public class PhyrexianEtchings extends CardImpl { // When Phyrexian Etchings is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) - .setText("When {this} is put into a graveyard from the battlefield, you lose 2 life for each age counter on it") + .setText("you lose 2 life for each age counter on it") )); } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java index 92d11254b4..4816a99a9e 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java @@ -100,7 +100,7 @@ class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}"; + return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}."; } } diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java index 7e40ff5721..6abcebba75 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -59,7 +59,7 @@ import mage.target.common.TargetCardInLibrary; */ public class PriestOfTheWakeningSun extends CardImpl { - private static final FilterCard filter = new FilterCard("a Dinosaur card"); + private static final FilterCard filter = new FilterCard("Dinosaur card"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/r/RaidersWake.java b/Mage.Sets/src/mage/cards/r/RaidersWake.java index 8ac022dbdb..0cfd603bf1 100644 --- a/Mage.Sets/src/mage/cards/r/RaidersWake.java +++ b/Mage.Sets/src/mage/cards/r/RaidersWake.java @@ -58,7 +58,7 @@ public class RaidersWake extends CardImpl { // Raid — At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card. Ability ability = new ConditionalTriggeredAbility( new BeginningOfEndStepTriggeredAbility(new DiscardTargetEffect(1), TargetController.YOU, false), RaidCondition.instance, - "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card"); + "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card."); ability.addTarget(new TargetOpponent()); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java index 4e19cb2918..5269c61f26 100644 --- a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java +++ b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java @@ -45,7 +45,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RavenGuildInitiate extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird"); static { filter.add(new SubtypePredicate(SubType.BIRD)); diff --git a/Mage.Sets/src/mage/cards/r/RazingSnidd.java b/Mage.Sets/src/mage/cards/r/RazingSnidd.java index f0aff98ea6..6e66ea6cc6 100644 --- a/Mage.Sets/src/mage/cards/r/RazingSnidd.java +++ b/Mage.Sets/src/mage/cards/r/RazingSnidd.java @@ -45,7 +45,7 @@ import mage.filter.predicate.mageobject.ColorPredicate; /** * * @author LoneFox - + * */ public class RazingSnidd extends CardImpl { @@ -56,7 +56,7 @@ public class RazingSnidd extends CardImpl { } public RazingSnidd(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -64,7 +64,7 @@ public class RazingSnidd extends CardImpl { // When Razing Snidd enters the battlefield, return a black or red creature you control to its owner's hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter), false)); // When Razing Snidd enters the battlefield, each player sacrifices a land. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeAllEffect(1, new FilterControlledLandPermanent("a land")), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeAllEffect(1, new FilterControlledLandPermanent("land")), false)); } public RazingSnidd(final RazingSnidd card) { diff --git a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java index e73c5e301f..fb603c77eb 100644 --- a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java +++ b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java @@ -52,7 +52,7 @@ import mage.game.permanent.token.DinosaurToken; */ public class RegisaurAlpha extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("other Dinosaurss you control"); + private static final FilterPermanent filter = new FilterPermanent("Dinosaurs"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/r/RevelInRiches.java b/Mage.Sets/src/mage/cards/r/RevelInRiches.java index 2fde790bda..3e757cb225 100644 --- a/Mage.Sets/src/mage/cards/r/RevelInRiches.java +++ b/Mage.Sets/src/mage/cards/r/RevelInRiches.java @@ -53,7 +53,7 @@ import mage.game.permanent.token.TreasureToken; */ public class RevelInRiches extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls"); private static final FilterPermanent filter2 = new FilterPermanent("Treasures"); static { diff --git a/Mage.Sets/src/mage/cards/r/RiggingRunner.java b/Mage.Sets/src/mage/cards/r/RiggingRunner.java index 9b6576fa95..b60adefa57 100644 --- a/Mage.Sets/src/mage/cards/r/RiggingRunner.java +++ b/Mage.Sets/src/mage/cards/r/RiggingRunner.java @@ -60,7 +60,7 @@ public class RiggingRunner extends CardImpl { // Raid — Rigging Runner enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.instance, - "Raid — {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "Raid — {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java index 2b6e660201..0ffb468b39 100644 --- a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java +++ b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java @@ -87,7 +87,12 @@ public class RimefeatherOwl extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter2), Duration.EndOfGame))); // {1}{snow}: Put an ice counter on target permanent. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.ICE.createInstance()), new ManaCostsImpl("{1}{S}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new AddCountersTargetEffect(CounterType.ICE.createInstance()) + .setText("Put an ice counter on target permanent."), + new ManaCostsImpl("{1}{S}") + ); ability.addTarget(new TargetPermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java index c78724c8d2..96f7b85fda 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java @@ -53,7 +53,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RuthlessKnave extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("three three Treasures"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("three Treasures"); static { filter.add(new SubtypePredicate(SubType.TREASURE)); diff --git a/Mage.Sets/src/mage/cards/s/SamitePilgrim.java b/Mage.Sets/src/mage/cards/s/SamitePilgrim.java index ab148f89a2..8aa8e03e3f 100644 --- a/Mage.Sets/src/mage/cards/s/SamitePilgrim.java +++ b/Mage.Sets/src/mage/cards/s/SamitePilgrim.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; public class SamitePilgrim extends CardImpl { public SamitePilgrim(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); @@ -57,6 +57,7 @@ public class SamitePilgrim extends CardImpl { // Domain - {T}: Prevent the next X damage that would be dealt to target creature this turn, where X is the number of basic land types among lands you control. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SamitePilgrimPreventDamageToTargetEffect(), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } @@ -72,7 +73,6 @@ public class SamitePilgrim extends CardImpl { class SamitePilgrimPreventDamageToTargetEffect extends PreventionEffectImpl { - public SamitePilgrimPreventDamageToTargetEffect() { super(Duration.EndOfTurn, Integer.MAX_VALUE, false, true); staticText = "Prevent the next X damage that would be dealt to target creature this turn, where X is the number of basic land types among lands you control."; diff --git a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java index ec8e8d81f6..cc1f8076e9 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java @@ -47,7 +47,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class SanctumSeeker extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Vampire you control attacks"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Vampire you control"); static { filter.add(new SubtypePredicate(SubType.VAMPIRE)); diff --git a/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java index 0a8d7e92a7..dc6f2eb24b 100644 --- a/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java +++ b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java @@ -58,7 +58,7 @@ public class ShipwreckLooter extends CardImpl { Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1, true)), RaidCondition.instance, - "Raid - When {this} enters the battlefield,if you attacked with a creature this turn, you may draw a card. If you do, discard a card."); + "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, you may draw a card. If you do, discard a card."); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/SirensRuse.java b/Mage.Sets/src/mage/cards/s/SirensRuse.java index 58ec90f304..f9a040d090 100644 --- a/Mage.Sets/src/mage/cards/s/SirensRuse.java +++ b/Mage.Sets/src/mage/cards/s/SirensRuse.java @@ -69,7 +69,7 @@ class SirensRuseEffect extends ExileTargetForSourceEffect { SirensRuseEffect() { super(); - this.staticText = "Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card."; + this.staticText = "Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card."; } SirensRuseEffect(final SirensRuseEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java b/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java index 53dd9426f8..6ee53ae9fd 100644 --- a/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java +++ b/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java @@ -37,7 +37,7 @@ import mage.util.CardUtil; public class SkyshipWeatherlight extends CardImpl { public SkyshipWeatherlight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); addSuperType(SuperType.LEGENDARY); // When Skyship Weatherlight enters the battlefield, search your library for any number of artifact and/or creature cards and exile them. Then shuffle your library. @@ -73,7 +73,7 @@ class SkyshipWeatherlightEffect extends SearchEffect { public SkyshipWeatherlightEffect() { super(new TargetCardInLibrary(0, Integer.MAX_VALUE, filter), Outcome.Neutral); - this.staticText = "search your library for any number of artifact and/or creature cards and remove them from the game. Then shuffle your library"; + this.staticText = "search your library for any number of artifact and/or creature cards and exile them. Then shuffle your library"; } @@ -114,7 +114,7 @@ class SkyshipWeatherlightEffect2 extends OneShotEffect { public SkyshipWeatherlightEffect2() { super(Outcome.ReturnToHand); - this.staticText = "Choose a card at random that was removed from the game with {this}. Put that card into your hand"; + this.staticText = "Choose a card at random that was exiled with {this}. Put that card into its owner's hand"; } public SkyshipWeatherlightEffect2(final SkyshipWeatherlightEffect2 effect) { diff --git a/Mage.Sets/src/mage/cards/s/SnappingSailback.java b/Mage.Sets/src/mage/cards/s/SnappingSailback.java index 7a7d1468d6..2fc3f7f494 100644 --- a/Mage.Sets/src/mage/cards/s/SnappingSailback.java +++ b/Mage.Sets/src/mage/cards/s/SnappingSailback.java @@ -58,7 +58,7 @@ public class SnappingSailback extends CardImpl { // Enrage — Whenever Snapping Sailback is dealt damage, put a +1/+1 counter on it. this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)) - .setText("put a +1/+1 counter on it"), false)); + .setText("put a +1/+1 counter on it"), false, true)); } public SnappingSailback(final SnappingSailback card) { diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java index 6745cc8009..ff0a1baae8 100644 --- a/Mage.Sets/src/mage/cards/s/SpellSwindle.java +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -69,7 +69,7 @@ class SpellSwindleEffect extends OneShotEffect { public SpellSwindleEffect() { super(Outcome.Detriment); staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " - + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool"; + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool\""; } public SpellSwindleEffect(final SpellSwindleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/StarOfExtinction.java b/Mage.Sets/src/mage/cards/s/StarOfExtinction.java index 1fdb4a3469..15e6c31a9a 100644 --- a/Mage.Sets/src/mage/cards/s/StarOfExtinction.java +++ b/Mage.Sets/src/mage/cards/s/StarOfExtinction.java @@ -47,7 +47,7 @@ public class StarOfExtinction extends CardImpl { // Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker. this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DamageAllEffect(20, new FilterCreatureOrPlaneswalkerPermanent("each creature and each planeswalker"))); + this.getSpellAbility().addEffect(new DamageAllEffect(20, new FilterCreatureOrPlaneswalkerPermanent("creature and each planeswalker"))); this.getSpellAbility().addTarget(new TargetLandPermanent()); } diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 0b934660f8..815955a089 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -105,6 +105,16 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi public SunbirdsInvocationTriggeredAbility copy() { return new SunbirdsInvocationTriggeredAbility(this); } + + @Override + public String getRule() { + return "Whenever you cast a spell from your hand, " + + "reveal the top X cards of your library, " + + "where X is that spell's converted mana cost. " + + "You may cast a card revealed this way with " + + "converted mana cost X or less without paying its mana cost." + + " Put the rest on the bottom of your library in a random order."; + } } class SunbirdsInvocationEffect extends OneShotEffect { diff --git a/Mage.Sets/src/mage/cards/s/Sunscour.java b/Mage.Sets/src/mage/cards/s/Sunscour.java index 7649c08e97..aca679b76b 100644 --- a/Mage.Sets/src/mage/cards/s/Sunscour.java +++ b/Mage.Sets/src/mage/cards/s/Sunscour.java @@ -36,7 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.FilterCard; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCardInHand; @@ -47,18 +47,19 @@ import mage.target.common.TargetCardInHand; public class Sunscour extends CardImpl { private static final FilterCard filter = new FilterCard("two white cards"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); } public Sunscour(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}{W}"); // You may exile two white cards from your hand rather than pay Sunscour's mana cost. this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(2, filter)))); // Destroy all creatures. - this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterCreaturePermanent())); + this.getSpellAbility().addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES)); } public Sunscour(final Sunscour card) { diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index 1db14c65ce..ccb530ace5 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -44,12 +44,12 @@ public class SurgingAether extends CardImpl { public SurgingAether(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); + // Ripple 4 + this.addAbility(new RippleAbility(4)); + // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent()); - - // Ripple 4 - this.addAbility(new RippleAbility(4)); } public SurgingAether(final SurgingAether card) { diff --git a/Mage.Sets/src/mage/cards/t/TempestCaller.java b/Mage.Sets/src/mage/cards/t/TempestCaller.java index 94ee292caa..7910dfa185 100644 --- a/Mage.Sets/src/mage/cards/t/TempestCaller.java +++ b/Mage.Sets/src/mage/cards/t/TempestCaller.java @@ -54,7 +54,7 @@ public class TempestCaller extends CardImpl { this.toughness = new MageInt(3); // When Tempest Caller enters the battlefield, tap all creatures target opponent controls. - Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures target opponent controls"))); + Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures"))); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/u/UrzasGuilt.java b/Mage.Sets/src/mage/cards/u/UrzasGuilt.java index 76400716c3..a3224df09e 100644 --- a/Mage.Sets/src/mage/cards/u/UrzasGuilt.java +++ b/Mage.Sets/src/mage/cards/u/UrzasGuilt.java @@ -43,13 +43,12 @@ import mage.constants.CardType; public class UrzasGuilt extends CardImpl { public UrzasGuilt(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{B}"); // Each player draws two cards, then discards three cards, then loses 4 life. this.getSpellAbility().addEffect(new DrawCardAllEffect(2)); Effect effect = new DiscardEachPlayerEffect(3, false); - effect.setText("then discards three cards"); + effect.setText("then discards three cards,"); this.getSpellAbility().addEffect(effect); effect = new LoseLifeAllPlayersEffect(4); effect.setText("then loses 4 life"); diff --git a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java index 105e7c99ff..58af23ab79 100644 --- a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java +++ b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java @@ -128,6 +128,6 @@ class DrawCardIfCreatureTypeAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you cast a creature spell of the chosen type, draw a card"; + return "Whenever you cast a creature spell of the chosen type, draw a card."; } } diff --git a/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java b/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java index 056e7011d6..f50e6011d4 100644 --- a/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java +++ b/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java @@ -50,7 +50,7 @@ import mage.constants.Zone; public class VeldraneOfSengir extends CardImpl { public VeldraneOfSengir(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); @@ -58,8 +58,8 @@ public class VeldraneOfSengir extends CardImpl { this.toughness = new MageInt(5); // {1}{B}{B}: Veldrane of Sengir gets -3/-0 and gains forestwalk until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-3, -0, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}{B}")); - ability.addEffect(new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-3, -0, Duration.EndOfTurn).setText("{this} gets -3/-0"), new ManaCostsImpl("{1}{B}{B}")); + ability.addEffect(new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn).setText("and gains forestwalk until end of turn")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java index 7a75f45fd1..c930ee1887 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java +++ b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java @@ -59,7 +59,7 @@ public class VerdantSunsAvatar extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(5); - // When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness. + // Whenever Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness. this.addAbility(new VerdantSunsAvatarTriggeredAbility()); } @@ -104,7 +104,7 @@ class VerdantSunsAvatarTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When {this} or another creature enters the battlefield under your control, " + super.getRule(); + return "Whenever {this} or another creature enters the battlefield under your control, " + super.getRule(); } @Override diff --git a/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java index 4795a2c12f..0ca53b9549 100644 --- a/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java +++ b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java @@ -90,7 +90,7 @@ class VraskaRelicSeekerDestroyEffect extends OneShotEffect { VraskaRelicSeekerDestroyEffect() { super(Outcome.Benefit); - this.staticText = "Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with \"{T}, Sacrfice this artifact. Add one mana of any color to your mana pool.\""; + this.staticText = "Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with \"{T}, Sacrifice this artifact. Add one mana of any color to your mana pool.\""; } VraskaRelicSeekerDestroyEffect(final VraskaRelicSeekerDestroyEffect effect) { diff --git a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java index f9cbcd3f23..ab1ff75772 100644 --- a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java +++ b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java @@ -62,8 +62,14 @@ public class WakerOfTheWilds extends CardImpl { this.toughness = new MageInt(3); // {X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste that's still a land. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new ManacostVariableValue()), new ManaCostsImpl("{X}{G}{G}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new AddCountersTargetEffect( + CounterType.P1P1.createInstance(0), + new ManacostVariableValue() + ).setText("Put X +1/+1 counters on target land you control."), + new ManaCostsImpl("{X}{G}{G}") + ); Effect effect = new BecomesCreatureTargetEffect(new WallOfResurgenceToken(), false, true, Duration.Custom); effect.setText("That land becomes a 0/0 Elemental creature with haste. It's still a land"); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java b/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java index 2317a14d4e..f8abdd8272 100644 --- a/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java +++ b/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java @@ -69,7 +69,7 @@ public class WaterspoutElemental extends CardImpl { EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandFromBattlefieldAllEffect(filter)); ability.addEffect(new SkipNextTurnSourceEffect()); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.instance, - "When {this} enters the battlefield, if it was kicked, return all other creatures to their owners' hands and you skip your next turn")); + "When {this} enters the battlefield, if it was kicked, return all other creatures to their owners' hands and you skip your next turn.")); } public WaterspoutElemental(final WaterspoutElemental card) { diff --git a/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java b/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java index 0e00876367..409af297ef 100644 --- a/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java +++ b/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java @@ -47,7 +47,7 @@ public class CantBlockAbility extends SimpleStaticAbility { @Override public String getRule() { - return "{this} can't block"; + return "{this} can't block."; } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java b/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java index 72856c0629..f71ad50471 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.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.abilities.condition.common; import mage.abilities.Ability; @@ -45,4 +44,8 @@ public enum RaidCondition implements Condition { PlayerAttackedWatcher watcher = (PlayerAttackedWatcher) game.getState().getWatchers().get(PlayerAttackedWatcher.class.getSimpleName()); return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) > 0; } + + public String toString() { + return "if you attacked with a creature this turn"; + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java index ad1aca5584..f1b8a2238f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java @@ -80,7 +80,6 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect StringBuilder sb = new StringBuilder(); sb.append("{this} can't be regenerated"); if (!duration.toString().isEmpty()) { - sb.append(' '); if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java index 4b53c47eaf..42bd8e092f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java @@ -243,7 +243,7 @@ public class LookLibraryControllerEffect extends OneShotEffect { sb.append(" cards "); } - sb.append("of your Library"); + sb.append("of your library"); if (numberLook == 0) { sb.append(", where {X} is the number of cards ").append(numberOfCards.getMessage()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java index cee08029fb..13948eef4d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -98,10 +99,19 @@ public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl sb.append("combat "); } sb.append("damage "); - sb.append(duration.toString()); - if (filter != null) { - sb.append(" dealt by "); - sb.append(filter.getMessage()); + if (duration == EndOfTurn) { + if (filter != null) { + sb.append(filter.getMessage()); + sb.append(" would deal this turn"); + } else { + sb.append("that would be dealt this turn"); + } + } else { + sb.append(duration.toString()); + if (filter != null) { + sb.append(" dealt by "); + sb.append(filter.getMessage()); + } } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java index e4a0e40806..c1f0ade074 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.game.Game; import mage.game.events.GameEvent; @@ -74,7 +75,12 @@ public class PreventDamageToSourceEffect extends PreventionEffectImpl { } else { sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to "); } - sb.append("{source} ").append(duration.toString()); + sb.append("{source} "); + if (duration == EndOfTurn) { + sb.append("this turn"); + } else { + sb.append(duration.toString()); + } return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java index 0ad564a721..cca02db55a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.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.abilities.effects.common; import java.util.List; @@ -60,10 +59,10 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(targetPointer.getFirst(game, source)); - if(player != null) { + if (player != null) { filter.add(new ControllerIdPredicate(player.getId())); List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for(Permanent p : permanents) { + for (Permanent p : permanents) { p.tap(game); } return true; @@ -78,9 +77,9 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { @Override public String getText(Mode mode) { - if(staticText != null && !staticText.isEmpty()) { + if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "tap all " + filter.getMessage() + " target player controls"; + return "tap all " + filter.getMessage() + " target " + mode.getTargets().get(0).getMessage() + " controls"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index 76a23da819..1283cc5972 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; import mage.constants.AttachmentType; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -61,7 +62,9 @@ public class CantBlockAttachedEffect extends RestrictionEffect { if (!filter.getMessage().equals("creature")) { sb.append(' ').append(filter.getMessage()); } - if (!duration.toString().isEmpty()) { + if (duration == EndOfTurn) { + sb.append("this turn"); + } else if (!duration.toString().isEmpty()) { sb.append(' ').append(duration.toString()); } staticText = sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index d97d8f9ea9..dde5970a68 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -26,7 +26,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { super(Outcome.BoostCreature); this.nonWall = nonWall; if(nonWall) { - staticText = "choose a creature type other than wall. Target creature becomes that type until end of turn"; + staticText = "choose a creature type other than Wall. Target creature becomes that type until end of turn"; } else { staticText = "target creature becomes the creature type of your choice until end of turn"; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java index f6f796c25f..d78d9a26ef 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java @@ -138,7 +138,6 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { if (duration.toString() != null && !duration.toString().isEmpty()) { sb.append(duration.toString()).append(", "); } - sb.append("all "); sb.append(filter.getMessage()); if (duration.toString() != null && duration.toString().isEmpty()) { sb.append(" are "); @@ -147,7 +146,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { } sb.append(token.getDescription()); if (type != null && !type.isEmpty()) { - sb.append(". They are still ").append(type); + sb.append(". They're still ").append(type); } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java index 59ea028475..4fb3d05810 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java @@ -53,7 +53,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.ability = ability; this.filter = filter; - staticText = filter.getMessage() + " you cast have " + ability.getRule(); + staticText = filter.getMessage() + " you cast have " + ability.getRule() + '.'; } public GainAbilityControlledSpellsEffect(final GainAbilityControlledSpellsEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java index 3bc9ba0e98..b896c2b950 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java @@ -36,6 +36,7 @@ import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.util.CardUtil; /** * @@ -82,7 +83,7 @@ public class AddCountersAllEffect extends OneShotEffect { StringBuilder sb = new StringBuilder(); sb.append("put "); if (counter.getCount() > 1) { - sb.append(Integer.toString(counter.getCount())).append(' ').append(counter.getName().toLowerCase()).append(" counters on each "); + sb.append(CardUtil.numberToText(counter.getCount(), "a")).append(' ').append(counter.getName().toLowerCase()).append(" counters on each "); } else { sb.append("a ").append(counter.getName().toLowerCase()).append(" counter on each "); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java index f540608e80..137a384bf1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java @@ -57,7 +57,7 @@ public class SearchLibraryGraveyardPutInHandEffect extends OneShotEffect { super(Outcome.Benefit); this.filter = filter; this.forceToSearchBoth = forceToSearchBoth; - staticText = "search your library and" + (forceToSearchBoth ? "" : "/or ") + " graveyard for a card named " + filter.getMessage() + staticText = "search your library and" + (forceToSearchBoth ? "" : "/or") + " graveyard for a card named " + filter.getMessage() + ", reveal it, and put it into your hand. " + (forceToSearchBoth ? "Then shuffle your library" : "If you search your library this way, shuffle it"); } diff --git a/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java b/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java index 514a4e3370..b746561a41 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.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.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class DeathtouchAbility extends StaticAbility implements MageSingleton { - private static final DeathtouchAbility instance = new DeathtouchAbility(); + private static final DeathtouchAbility instance = new DeathtouchAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class DeathtouchAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Deathtouch (Any amount of damage this deals to a creature is enough to destroy it.)"; + return "deathtouch"; } @Override @@ -64,6 +63,4 @@ public class DeathtouchAbility extends StaticAbility implements MageSingleton { return instance; } - - } diff --git a/Mage/src/main/java/mage/abilities/keyword/FearAbility.java b/Mage/src/main/java/mage/abilities/keyword/FearAbility.java index e730552c9d..939b05cfab 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FearAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FearAbility.java @@ -24,11 +24,9 @@ * 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.abilities.keyword; -import mage.constants.CardType; import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.EvasionAbility; @@ -45,7 +43,7 @@ import java.io.ObjectStreamException; */ public class FearAbility extends EvasionAbility implements MageSingleton { - private static final FearAbility instance = new FearAbility(); + private static final FearAbility instance = new FearAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -61,7 +59,7 @@ public class FearAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Fear"; + return "fear"; } @Override @@ -102,4 +100,4 @@ class FearEffect extends RestrictionEffect implements MageSingleton { return new FearEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java b/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java index d5a09f1629..70d7008032 100644 --- a/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java @@ -32,15 +32,15 @@ import mage.constants.Zone; import mage.abilities.StaticAbility; /** - * OLD RULES: - * 700.4. If a permanent is indestructible, rules and effects can't destroy it. (See rule 701.6, "Destroy.") - * Such permanents are not destroyed by lethal damage, and they ignore the lethal-damage state-based action - * (see rule 704.5g). Rules or effects may cause an indestructible permanent to be sacrificed, put into a - * graveyard, or exiled. # + * OLD RULES: 700.4. If a permanent is indestructible, rules and effects can't + * destroy it. (See rule 701.6, "Destroy.") Such permanents are not destroyed by + * lethal damage, and they ignore the lethal-damage state-based action (see rule + * 704.5g). Rules or effects may cause an indestructible permanent to be + * sacrificed, put into a graveyard, or exiled. # * - * 700.4a Although the text "[This permanent] is indestructible" is an ability, actually being - * indestructible is neither an ability nor a characteristic. It's just something that's true - * about a permanent. + * 700.4a Although the text "[This permanent] is indestructible" is an ability, + * actually being indestructible is neither an ability nor a characteristic. + * It's just something that's true about a permanent. * * NEW RULES * @@ -48,10 +48,9 @@ import mage.abilities.StaticAbility; * * * - * + * * @author BetaSteward_at_googlemail.com */ - public class IndestructibleAbility extends StaticAbility { private static final IndestructibleAbility instance; @@ -79,7 +78,7 @@ public class IndestructibleAbility extends StaticAbility { @Override public String getRule() { - return "Indestructible"; + return "indestructible"; } } From 14107b3d55b81477384ca8750f15a11e5fa1dcd4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 11:02:36 -0400 Subject: [PATCH 005/164] 2 text 2 fixrious --- .../src/mage/cards/a/AlliedStrategies.java | 5 +- .../src/mage/cards/a/AtalyaSamiteMaster.java | 4 +- .../src/mage/cards/a/AuramancersGuise.java | 2 +- .../src/mage/cards/b/BlackManaBattery.java | 3 +- .../src/mage/cards/b/BlueManaBattery.java | 2 +- .../src/mage/cards/b/BraidsConjurerAdept.java | 6 +- .../src/mage/cards/c/CollapsingBorders.java | 4 +- .../src/mage/cards/c/CollectiveRestraint.java | 5 +- Mage.Sets/src/mage/cards/c/Confound.java | 4 +- Mage.Sets/src/mage/cards/d/Detritivore.java | 5 +- Mage.Sets/src/mage/cards/e/EnergyTap.java | 8 +-- Mage.Sets/src/mage/cards/e/EvasiveAction.java | 4 +- Mage.Sets/src/mage/cards/e/ExoticCurse.java | 9 ++- Mage.Sets/src/mage/cards/f/FatalFrenzy.java | 10 ++- .../src/mage/cards/f/FirebrandRanger.java | 8 +-- Mage.Sets/src/mage/cards/g/GateSmasher.java | 4 +- Mage.Sets/src/mage/cards/g/GhituFire.java | 5 +- .../src/mage/cards/g/GleamOfAuthority.java | 19 +++--- Mage.Sets/src/mage/cards/g/GohamDjinn.java | 5 ++ .../src/mage/cards/g/GreaterStoneSpirit.java | 12 ++-- .../src/mage/cards/g/GreenManaBattery.java | 2 +- .../src/mage/cards/h/HedonistsTrove.java | 4 +- .../src/mage/cards/h/HerdchaserDragon.java | 12 ++-- Mage.Sets/src/mage/cards/i/IllusoryGains.java | 4 +- .../src/mage/cards/k/KangeeAerieKeeper.java | 18 +++--- Mage.Sets/src/mage/cards/k/KavuScout.java | 8 ++- Mage.Sets/src/mage/cards/k/KrovikanMist.java | 14 ++-- Mage.Sets/src/mage/cards/l/LoseCalm.java | 6 +- .../mage/cards/m/MagusOfTheTabernacle.java | 2 +- Mage.Sets/src/mage/cards/m/MidnightCharm.java | 4 +- Mage.Sets/src/mage/cards/m/MirrorMockery.java | 4 +- Mage.Sets/src/mage/cards/n/NullProfusion.java | 31 +++++---- .../src/mage/cards/o/OjutaiExemplars.java | 14 ++-- .../src/mage/cards/o/OrderedMigration.java | 2 + Mage.Sets/src/mage/cards/o/Overload.java | 64 ++++++++++++------- Mage.Sets/src/mage/cards/o/Ovinize.java | 9 ++- .../src/mage/cards/p/PoulticeSliver.java | 2 +- Mage.Sets/src/mage/cards/p/PowerArmor.java | 4 +- .../src/mage/cards/p/PrisonBarricade.java | 14 ++-- Mage.Sets/src/mage/cards/p/Probe.java | 12 ++-- Mage.Sets/src/mage/cards/p/Prohibit.java | 64 +++++++++++-------- Mage.Sets/src/mage/cards/p/PyreZombie.java | 6 +- .../src/mage/cards/q/QuicksilverDagger.java | 11 ++-- .../src/mage/cards/q/QuirionTrailblazer.java | 5 +- .../src/mage/cards/r/RedManaBattery.java | 2 +- .../src/mage/cards/r/RewardsOfDiversity.java | 4 +- .../src/mage/cards/r/RisenExecutioner.java | 30 ++++----- Mage.Sets/src/mage/cards/r/RoilingHorror.java | 8 ++- .../src/mage/cards/s/SaprolingSymbiosis.java | 5 +- .../src/mage/cards/s/SarkhanUnbroken.java | 2 +- Mage.Sets/src/mage/cards/s/SawtoothLoon.java | 4 +- Mage.Sets/src/mage/cards/s/ScaleBlessing.java | 2 +- .../src/mage/cards/s/ScaleguardSentinels.java | 4 +- Mage.Sets/src/mage/cards/s/ScorchingLava.java | 5 +- Mage.Sets/src/mage/cards/s/SeersVision.java | 4 +- .../src/mage/cards/s/ServantOfTheScale.java | 10 +-- .../src/mage/cards/s/ShieldhideDragon.java | 12 ++-- .../mage/cards/s/SightOfTheScalelords.java | 6 +- Mage.Sets/src/mage/cards/s/StormriderRig.java | 14 ++-- .../src/mage/cards/s/StormscapeMaster.java | 6 +- .../src/mage/cards/s/StormwingDragon.java | 12 ++-- .../src/mage/cards/s/SulfurElemental.java | 13 ++-- .../src/mage/cards/t/TemporalDistortion.java | 2 +- .../src/mage/cards/t/ThunderscapeMaster.java | 4 +- .../src/mage/cards/u/UrborgSkeleton.java | 14 ++-- .../src/mage/cards/v/VodalianMerchant.java | 6 +- .../src/mage/cards/w/WhiteManaBattery.java | 2 +- Mage/src/main/java/mage/Mana.java | 18 +++--- ...yMoreToCastAsThoughtItHadFlashAbility.java | 2 +- .../common/CardsInHandCondition.java | 3 +- .../AddConditionalManaOfAnyColorEffect.java | 7 +- .../common/CastSourceTriggeredAbility.java | 7 +- .../common/CounterUnlessPaysEffect.java | 2 +- .../effects/common/GetEmblemEffect.java | 20 +++++- .../effects/common/NameACardEffect.java | 17 ++--- .../common/UntapAllThatAttackedEffect.java | 2 +- .../CantBeBlockedByAllTargetEffect.java | 4 +- .../continuous/BoostEnchantedEffect.java | 2 +- .../search/SearchLibraryPutInPlayEffect.java | 5 +- .../effects/keyword/BolsterEffect.java | 2 +- .../mage/abilities/keyword/DashAbility.java | 1 + .../mage/abilities/keyword/ReachAbility.java | 7 +- .../abilities/keyword/SuspendAbility.java | 2 +- 83 files changed, 412 insertions(+), 300 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java index 7d1009bad9..517210b49b 100644 --- a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java +++ b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.target.TargetPlayer; @@ -42,11 +43,13 @@ import mage.target.TargetPlayer; public class AlliedStrategies extends CardImpl { public AlliedStrategies(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}"); // Domain - Target player draws a card for each basic land type among lands he or she controls. this.getSpellAbility().addEffect(new DrawCardTargetEffect(new DomainValue(true))); this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); + } public AlliedStrategies(final AlliedStrategies card) { diff --git a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java index 474945b89a..8a62d61886 100644 --- a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java +++ b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java @@ -68,7 +68,7 @@ public class AtalyaSamiteMaster extends CardImpl { // {X}, {tap}: Choose one - Prevent the next X damage that would be dealt to target creature this turn; or you gain X life. Spend only white mana on X. PreventDamageToTargetEffect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue()); - effect.setText("Prevent the next X damage that would be dealt to target creature this turn"); + effect.setText("Prevent the next X damage that would be dealt to target creature this turn. Spend only white mana on X."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); ability.addCost(new TapSourceCost()); @@ -81,7 +81,7 @@ public class AtalyaSamiteMaster extends CardImpl { // or you gain X life Mode mode = new Mode(); - mode.getEffects().add(new GainLifeEffect(new ManacostVariableValue())); + mode.getEffects().add(new GainLifeEffect(new ManacostVariableValue()).setText("You gain X life. Spend only white mana on X.")); ability.addMode(mode); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/AuramancersGuise.java b/Mage.Sets/src/mage/cards/a/AuramancersGuise.java index 7ccaf66d28..7bb76dcc1f 100644 --- a/Mage.Sets/src/mage/cards/a/AuramancersGuise.java +++ b/Mage.Sets/src/mage/cards/a/AuramancersGuise.java @@ -70,7 +70,7 @@ public class AuramancersGuise extends CardImpl { BoostEnchantedEffect effect = new BoostEnchantedEffect(ptBoost, ptBoost, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +2/+2 for each Aura attached to it"); SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); - ability2.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); + ability2.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA).setText("and has vigilance")); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java index 8e6449f4d1..412775a234 100644 --- a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java @@ -53,7 +53,6 @@ public class BlackManaBattery extends CardImpl { public BlackManaBattery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); - // {2}, {tap}: Put a charge counter on Black Mana Battery. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance(1)), new GenericManaCost(2)); @@ -68,7 +67,7 @@ public class BlackManaBattery extends CardImpl { "Add {B} to your mana pool, then add {B} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java index 410b81cb00..6883996517 100644 --- a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java @@ -67,7 +67,7 @@ public class BlueManaBattery extends CardImpl { "Add {U} to your mana pool, then add {U} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java index 950894450f..0f1050c875 100644 --- a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java +++ b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java @@ -47,8 +47,8 @@ import mage.filter.predicate.mageobject.CardTypePredicate; */ public class BraidsConjurerAdept extends CardImpl { - private static final FilterCard filter = new FilterCard("artifact, creature, or land card") -; + private static final FilterCard filter = new FilterCard("an artifact, creature, or land card"); + static { filter.add(Predicates.or( new CardTypePredicate(CardType.ARTIFACT), @@ -57,7 +57,7 @@ public class BraidsConjurerAdept extends CardImpl { } public BraidsConjurerAdept(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN, SubType.WIZARD); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java index b99b7dfd7f..c273b3e7b8 100644 --- a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java +++ b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java @@ -36,6 +36,7 @@ import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.TargetController; @@ -47,7 +48,7 @@ import mage.constants.TargetController; public class CollapsingBorders extends CardImpl { public CollapsingBorders(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); // Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands he or she controls. Then Collapsing Borders deals 3 damage to him or her. Effect effect = new GainLifeTargetEffect(new DomainValue(true)); @@ -56,6 +57,7 @@ public class CollapsingBorders extends CardImpl { effect = new DamageTargetEffect(3); effect.setText("Then {this} deals 3 damage to him or her."); ability.addEffect(effect); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java index a956c84595..d2b60309a0 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java @@ -36,6 +36,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.combat.CantAttackYouUnlessPayManaAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Zone; import mage.game.Game; @@ -51,7 +52,9 @@ public class CollectiveRestraint extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); // 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 you control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CollectiveRestraintPayManaToAttackAllEffect())); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new CollectiveRestraintPayManaToAttackAllEffect()); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/Confound.java b/Mage.Sets/src/mage/cards/c/Confound.java index 38575e88dc..3675f891f2 100644 --- a/Mage.Sets/src/mage/cards/c/Confound.java +++ b/Mage.Sets/src/mage/cards/c/Confound.java @@ -44,14 +44,14 @@ import mage.target.TargetSpell; */ public class Confound extends CardImpl { - private final static FilterSpell filter = new FilterSpell("spell that targets one or more creatures"); + private final static FilterSpell filter = new FilterSpell("spell that targets a creature"); static { filter.add(new TargetsPermanentPredicate(new FilterCreaturePermanent())); } public Confound(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Counter target spell that targets one or more creatures. this.getSpellAbility().addEffect(new CounterTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/d/Detritivore.java b/Mage.Sets/src/mage/cards/d/Detritivore.java index 4be1d1f684..1865dfd752 100644 --- a/Mage.Sets/src/mage/cards/d/Detritivore.java +++ b/Mage.Sets/src/mage/cards/d/Detritivore.java @@ -63,7 +63,7 @@ import mage.target.common.TargetNonBasicLandPermanent; public class Detritivore extends CardImpl { public Detritivore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.LHURGOYF); this.power = new MageInt(0); @@ -132,7 +132,6 @@ class NonBasicLandsInOpponentsGraveyards implements DynamicValue { filter.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); } - @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { int amount = 0; @@ -162,6 +161,6 @@ class NonBasicLandsInOpponentsGraveyards implements DynamicValue { @Override public String getMessage() { - return "the number of nonbasic land cards in your opponents' graveyards"; + return "nonbasic land cards in your opponents' graveyards"; } } diff --git a/Mage.Sets/src/mage/cards/e/EnergyTap.java b/Mage.Sets/src/mage/cards/e/EnergyTap.java index 2eab464759..3012505d16 100644 --- a/Mage.Sets/src/mage/cards/e/EnergyTap.java +++ b/Mage.Sets/src/mage/cards/e/EnergyTap.java @@ -56,9 +56,9 @@ public class EnergyTap extends CardImpl { } public EnergyTap(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}"); - // Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost. + // Tap target untapped creature you control. If you do, add an amount of {C} to your mana pool equal to that creature's converted mana cost. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(filter)); this.getSpellAbility().addEffect(new EnergyTapEffect()); } @@ -77,7 +77,7 @@ class EnergyTapEffect extends OneShotEffect { EnergyTapEffect() { super(Outcome.PutManaInPool); - this.staticText = "Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost"; + this.staticText = "Tap target untapped creature you control. If you do, add an amount of {C} to your mana pool equal to that creature's converted mana cost"; } EnergyTapEffect(final EnergyTapEffect effect) { @@ -106,4 +106,4 @@ class EnergyTapEffect extends OneShotEffect { } return applied; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/e/EvasiveAction.java b/Mage.Sets/src/mage/cards/e/EvasiveAction.java index f271c86d6d..87773fdc23 100644 --- a/Mage.Sets/src/mage/cards/e/EvasiveAction.java +++ b/Mage.Sets/src/mage/cards/e/EvasiveAction.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.target.TargetSpell; @@ -42,11 +43,12 @@ import mage.target.TargetSpell; public class EvasiveAction extends CardImpl { public EvasiveAction(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Domain - Counter target spell unless its controller pays {1} for each basic land type among lands you control. this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new DomainValue())); this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public EvasiveAction(final EvasiveAction card) { diff --git a/Mage.Sets/src/mage/cards/e/ExoticCurse.java b/Mage.Sets/src/mage/cards/e/ExoticCurse.java index f1adf3fee9..34c231b9bb 100644 --- a/Mage.Sets/src/mage/cards/e/ExoticCurse.java +++ b/Mage.Sets/src/mage/cards/e/ExoticCurse.java @@ -28,6 +28,7 @@ package mage.cards.e; import java.util.UUID; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.DomainValue; @@ -37,6 +38,7 @@ import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -51,7 +53,7 @@ import mage.target.TargetPermanent; public class ExoticCurse extends CardImpl { public ExoticCurse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -62,8 +64,9 @@ public class ExoticCurse extends CardImpl { // Domain - Enchanted creature gets -1/-1 for each basic land type among lands you control. DynamicValue unboost = new SignInversionDynamicValue(new DomainValue()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new BoostEnchantedEffect(unboost, unboost, Duration.WhileOnBattlefield))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(unboost, unboost, Duration.WhileOnBattlefield)); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public ExoticCurse(final ExoticCurse card) { diff --git a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java index 08ab764a29..2794d52a20 100644 --- a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java +++ b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java @@ -55,11 +55,15 @@ import mage.target.targetpointer.FixedTarget; public class FatalFrenzy extends CardImpl { public FatalFrenzy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // Until end of turn, target creature you control gains trample and gets +X/+0, where X is its power. Sacrifice it at the beginning of the next end step. - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) + .setText("Until end of turn, target creature you control gains trample") + ); + this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true) + .setText("and gets +X/+0, where X is its power.") + ); this.getSpellAbility().addEffect(new FatalFrenzyEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java index 4ea4f8bcf6..3c335a7fd5 100644 --- a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java +++ b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCardInHand; public class FirebrandRanger extends CardImpl { public FirebrandRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); @@ -80,7 +80,7 @@ public class FirebrandRanger extends CardImpl { } class PutLandOnBattlefieldEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("basic land card"); static { @@ -91,7 +91,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { public PutLandOnBattlefieldEffect() { super(Outcome.PutLandInPlay); - this.staticText = "put a basic land card from your hand onto the battlefield"; + this.staticText = "you may put a basic land card from your hand onto the battlefield"; } public PutLandOnBattlefieldEffect(final PutLandOnBattlefieldEffect effect) { @@ -120,4 +120,4 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GateSmasher.java b/Mage.Sets/src/mage/cards/g/GateSmasher.java index 4b16473ea6..f8b0b896bc 100644 --- a/Mage.Sets/src/mage/cards/g/GateSmasher.java +++ b/Mage.Sets/src/mage/cards/g/GateSmasher.java @@ -56,14 +56,14 @@ import mage.target.common.TargetControlledCreaturePermanent; */ public class GateSmasher extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with 3 or more power"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with toughness 4 or greater"); static { filter.add(new ToughnessPredicate(ComparisonType.MORE_THAN, 3)); } public GateSmasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); Target target = new TargetControlledCreaturePermanent(1, 1, filter, false); diff --git a/Mage.Sets/src/mage/cards/g/GhituFire.java b/Mage.Sets/src/mage/cards/g/GhituFire.java index ff3fe2b8fe..833cf73397 100644 --- a/Mage.Sets/src/mage/cards/g/GhituFire.java +++ b/Mage.Sets/src/mage/cards/g/GhituFire.java @@ -42,18 +42,19 @@ import mage.target.common.TargetCreatureOrPlayer; /** * * @author LoneFox - + * */ public class GhituFire extends CardImpl { public GhituFire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); Effect effect = new DamageTargetEffect(new ManacostVariableValue()); // You may cast Ghitu Fire as though it had flash if you pay {2} more to cast it. Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl("{2}")); ability.addEffect(effect); ability.addTarget(new TargetCreatureOrPlayer()); + ability.setRuleAtTheTop(true); this.addAbility(ability); // Ghitu Fire deals X damage to target creature or player. this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java index 75f1d0d912..82f91c5ec9 100644 --- a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java +++ b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCreaturePermanent; public class GleamOfAuthority extends CardImpl { public GleamOfAuthority(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -67,16 +67,17 @@ public class GleamOfAuthority extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control DynamicValue amount = new CountersOnControlledCount(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); + // Enchanted creature has vigilance and "{W}, {T}: Bloster 1." - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA))); - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BolsterEffect(1), new ManaCostsImpl("{W}")); - ability.addCost(new TapSourceCost()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BolsterEffect(1), new ManaCostsImpl("{W}")); + gainedAbility.addCost(new TapSourceCost()); + ability.addEffect(new GainAbilityAttachedEffect(ability, AttachmentType.AURA).setText("and \"{W}, {T}: Bloster 1.\"")); + this.addAbility(ability); } public GleamOfAuthority(final GleamOfAuthority card) { @@ -92,7 +93,7 @@ public class GleamOfAuthority extends CardImpl { class CountersOnControlledCount implements DynamicValue { static FilterCreaturePermanent filter = new FilterCreaturePermanent(); - + public CountersOnControlledCount() { } diff --git a/Mage.Sets/src/mage/cards/g/GohamDjinn.java b/Mage.Sets/src/mage/cards/g/GohamDjinn.java index 5267094237..412d5d98d8 100644 --- a/Mage.Sets/src/mage/cards/g/GohamDjinn.java +++ b/Mage.Sets/src/mage/cards/g/GohamDjinn.java @@ -30,9 +30,12 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.ObjectColor; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.MostCommonColorCondition; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.RegenerateSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -55,6 +58,8 @@ public class GohamDjinn extends CardImpl { this.toughness = new MageInt(5); // {1}{B}: Regenerate Goham Djinn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{B}"))); + // Goham Djinn gets -2/-2 as long as black is the most common color among all permanents or is tied for most common. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(-2, -2, Duration.WhileOnBattlefield), diff --git a/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java b/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java index 1f3702f52a..a9a59aefb1 100644 --- a/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java +++ b/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java @@ -54,14 +54,15 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class GreaterStoneSpirit extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying"); + static { filter.add(new AbilityPredicate(FlyingAbility.class)); } public GreaterStoneSpirit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(4); @@ -69,10 +70,13 @@ public class GreaterStoneSpirit extends CardImpl { // Greater Stone Spirit can't be blocked by creatures with flying. this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); - + // {2}{R}: Until end of turn, target creature gets +0/+2 and gains "{R}: This creature gets +1/+0 until end of turn." Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")); + new BoostSourceEffect(1, 0, Duration.EndOfTurn) + .setText("until end of turn, target creature gets +0/+2"), + new ManaCostsImpl("{R}") + ); Effect effect = new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn); effect.setText("and gains \"{R}: This creature gets +1/+0 until end of turn.\""); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(0, 2, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}")); diff --git a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java index 7a407edcc5..0e273c06e0 100644 --- a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java +++ b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java @@ -67,7 +67,7 @@ public class GreenManaBattery extends CardImpl { "Add {G} to your mana pool, then add {G} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java index a024d4458a..44aa5b482b 100644 --- a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java +++ b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java @@ -54,7 +54,7 @@ import java.util.UUID; public class HedonistsTrove extends CardImpl { public HedonistsTrove(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{B}{B}"); // When Hedonist's Trove enters the battlefield, exile all cards from target opponent's graveyard. Ability ability = new EntersBattlefieldTriggeredAbility(new HedonistsTroveExileEffect()); @@ -115,7 +115,7 @@ class HedonistsTrovePlayLandEffect extends AsThoughEffectImpl { public HedonistsTrovePlayLandEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "You may play land cards exiled by {this}"; + staticText = "You may play land cards exiled with {this}"; } public HedonistsTrovePlayLandEffect(final HedonistsTrovePlayLandEffect effect) { diff --git a/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java b/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java index 5e3579d710..a5c7b8ceda 100644 --- a/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java +++ b/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class HerdchaserDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class HerdchaserDragon extends CardImpl { } public HerdchaserDragon(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.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // Trample this.addAbility(TrampleAbility.getInstance()); - + // Megamorph {5}{G}{G} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{G}{G}"), true)); - + // When Herdchaser Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/i/IllusoryGains.java b/Mage.Sets/src/mage/cards/i/IllusoryGains.java index 74c227de3b..d2b7f01df0 100644 --- a/Mage.Sets/src/mage/cards/i/IllusoryGains.java +++ b/Mage.Sets/src/mage/cards/i/IllusoryGains.java @@ -65,7 +65,7 @@ public class IllusoryGains extends CardImpl { } public IllusoryGains(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -80,7 +80,7 @@ public class IllusoryGains extends CardImpl { // Whenever a creature enters the battlefield under an opponent's control, attach Illusory Gains to that creature. this.addAbility(new EntersBattlefieldAllTriggeredAbility( - Zone.BATTLEFIELD, new IllusoryGainsEffect(), filter, false, SetTargetPointer.PERMANENT, "Whenever a creature enters the battlefield under an opponent's control, you attach Illusory Gains to that creature.")); + Zone.BATTLEFIELD, new IllusoryGainsEffect(), filter, false, SetTargetPointer.PERMANENT, "Whenever a creature enters the battlefield under an opponent's control, attach Illusory Gains to that creature.")); } public IllusoryGains(final IllusoryGains card) { diff --git a/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java b/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java index 7dea607f9c..6c2bf15440 100644 --- a/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java +++ b/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java @@ -57,16 +57,16 @@ import mage.game.Game; * @author emerald000 */ public class KangeeAerieKeeper extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Bird creatures"); - + static { filter.add(new SubtypePredicate(SubType.BIRD)); filter.add(new AnotherPredicate()); } public KangeeAerieKeeper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.BIRD); this.subtype.add(SubType.WIZARD); @@ -75,15 +75,15 @@ public class KangeeAerieKeeper extends CardImpl { this.toughness = new MageInt(2); // Kicker {X}{2} - this.addAbility(new KickerAbility("{X}{2}")); - + this.addAbility(new KickerAbility("{2}{X}")); + // Flying this.addAbility(FlyingAbility.getInstance()); - + // When Kangee, Aerie Keeper enters the battlefield, if it was kicked, put X feather counters on it. TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.FEATHER.createInstance(), new KangeeAerieKeeperGetKickerXValue(), true)); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.instance, "When {this} enters the battlefield, if it was kicked, put X feather counters on it.")); - + // Other Bird creatures get +1/+1 for each feather counter on Kangee, Aerie Keeper. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(new CountersSourceCount(CounterType.FEATHER), new CountersSourceCount(CounterType.FEATHER), Duration.WhileOnBattlefield, filter, true, "Other Bird creatures get +1/+1 for each feather counter on {this}."))); } @@ -108,7 +108,7 @@ class KangeeAerieKeeperGetKickerXValue implements DynamicValue { int count = 0; Card card = game.getCard(source.getSourceId()); if (card != null) { - for (Ability ability: card.getAbilities()) { + for (Ability ability : card.getAbilities()) { if (ability instanceof KickerAbility) { count += ((KickerAbility) ability).getXManaValue(); } @@ -131,4 +131,4 @@ class KangeeAerieKeeperGetKickerXValue implements DynamicValue { public String getMessage() { return "X"; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/k/KavuScout.java b/Mage.Sets/src/mage/cards/k/KavuScout.java index f8bcb743a3..f9a94eadcc 100644 --- a/Mage.Sets/src/mage/cards/k/KavuScout.java +++ b/Mage.Sets/src/mage/cards/k/KavuScout.java @@ -29,12 +29,14 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -47,7 +49,7 @@ import mage.constants.Zone; public class KavuScout extends CardImpl { public KavuScout(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.KAVU); this.subtype.add(SubType.SCOUT); @@ -55,7 +57,9 @@ public class KavuScout extends CardImpl { this.toughness = new MageInt(2); // Domain - Kavu Scout gets +1/+0 for each basic land type among lands you control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new DomainValue(), new StaticValue(0), Duration.WhileOnBattlefield))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new DomainValue(), new StaticValue(0), Duration.WhileOnBattlefield)); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public KavuScout(final KavuScout card) { diff --git a/Mage.Sets/src/mage/cards/k/KrovikanMist.java b/Mage.Sets/src/mage/cards/k/KrovikanMist.java index 3cd681609c..e937c2d8db 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanMist.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanMist.java @@ -39,7 +39,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; /** @@ -47,15 +47,15 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author LevelX2 */ public class KrovikanMist extends CardImpl { - - private static final FilterControlledPermanent controlledIllusionsFilter = new FilterControlledPermanent("Illusions you control"); - + + private static final FilterPermanent illusionsFilter = new FilterPermanent("Illusions on the battlefield"); + static { - controlledIllusionsFilter.add(new SubtypePredicate(SubType.ILLUSION)); + illusionsFilter.add(new SubtypePredicate(SubType.ILLUSION)); } public KrovikanMist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.ILLUSION); this.power = new MageInt(0); @@ -65,7 +65,7 @@ public class KrovikanMist extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Krovikan Mist's power and toughness are each equal to the number of Illusions on the battlefield. this.addAbility(new SimpleStaticAbility(Zone.ALL, - new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(controlledIllusionsFilter), Duration.EndOfGame))); + new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(illusionsFilter), Duration.EndOfGame))); } diff --git a/Mage.Sets/src/mage/cards/l/LoseCalm.java b/Mage.Sets/src/mage/cards/l/LoseCalm.java index 7891c5c802..d64891833c 100644 --- a/Mage.Sets/src/mage/cards/l/LoseCalm.java +++ b/Mage.Sets/src/mage/cards/l/LoseCalm.java @@ -47,17 +47,17 @@ import mage.target.common.TargetCreaturePermanent; public class LoseCalm extends CardImpl { public LoseCalm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Gain control of target creature until end of turn. Untap that creature. It gains haste and menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); Effect effect = new UntapTargetEffect(); effect.setText("Untap that creature"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "It gains haste until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "It gains haste")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); effect = new GainAbilityTargetEffect(new MenaceAbility(), Duration.EndOfTurn); - effect.setText("and menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) "); + effect.setText("and menace until end of turn"); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java b/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java index a85772a723..0fdd344d1e 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java @@ -50,7 +50,7 @@ import mage.filter.StaticFilters; */ public class MagusOfTheTabernacle extends CardImpl { - static private final String rule = "All creatures have \"At the beginning of your upkeep, sacrifice this creature unless you pay {1}\""; + static private final String rule = "All creatures have \"At the beginning of your upkeep, sacrifice this creature unless you pay {1}.\""; public MagusOfTheTabernacle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); diff --git a/Mage.Sets/src/mage/cards/m/MidnightCharm.java b/Mage.Sets/src/mage/cards/m/MidnightCharm.java index 10b4c3e693..f4e9be58d9 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightCharm.java +++ b/Mage.Sets/src/mage/cards/m/MidnightCharm.java @@ -47,11 +47,11 @@ import mage.target.common.TargetCreaturePermanent; public class MidnightCharm extends CardImpl { public MidnightCharm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Choose one - Midnight Charm deals 1 damage to target creature and you gain 1 life; or target creature gains first strike until end of turn; or tap target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(1)); - this.getSpellAbility().addEffect(new GainLifeEffect(1)); + this.getSpellAbility().addEffect(new GainLifeEffect(1).setText("and you gain 1 life")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); Mode mode = new Mode(); mode.getEffects().add(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/m/MirrorMockery.java b/Mage.Sets/src/mage/cards/m/MirrorMockery.java index f4c4534942..b0572190fb 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMockery.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMockery.java @@ -55,7 +55,7 @@ import mage.target.targetpointer.FixedTarget; public class MirrorMockery extends CardImpl { public MirrorMockery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -83,7 +83,7 @@ class MirrorMockeryEffect extends OneShotEffect { public MirrorMockeryEffect() { super(Outcome.Benefit); - this.staticText = "you may create a token that's a copy of that creature. Exile that token at the end of combat"; + this.staticText = "you may create a token that's a copy of that creature. Exile that token at end of combat"; } public MirrorMockeryEffect(final MirrorMockeryEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NullProfusion.java b/Mage.Sets/src/mage/cards/n/NullProfusion.java index acfa8a026a..d319c62a11 100644 --- a/Mage.Sets/src/mage/cards/n/NullProfusion.java +++ b/Mage.Sets/src/mage/cards/n/NullProfusion.java @@ -30,6 +30,7 @@ package mage.cards.n; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.SkipDrawStepEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; @@ -38,6 +39,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -50,16 +52,23 @@ import mage.game.events.GameEvent.EventType; public class NullProfusion extends CardImpl { public NullProfusion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}"); // Skip your draw step. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect())); + // Whenever you play a card, draw a card. this.addAbility(new NullProfusionTriggeredAbility()); - + // Your maximum hand size is two. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MaximumHandSizeControllerEffect(2, Duration.WhileOnBattlefield, HandSizeModification.SET))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new MaximumHandSizeControllerEffect( + new StaticValue(2), + Duration.WhileOnBattlefield, + HandSizeModification.SET, + TargetController.YOU + ) + )); } public NullProfusion(final NullProfusion card) { @@ -73,15 +82,15 @@ public class NullProfusion extends CardImpl { } class NullProfusionTriggeredAbility extends TriggeredAbilityImpl { - + NullProfusionTriggeredAbility() { super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); } - + NullProfusionTriggeredAbility(final NullProfusionTriggeredAbility ability) { super(ability); } - + @Override public NullProfusionTriggeredAbility copy() { return new NullProfusionTriggeredAbility(this); @@ -91,14 +100,14 @@ class NullProfusionTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == EventType.SPELL_CAST || event.getType() == EventType.LAND_PLAYED; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { return event.getPlayerId().equals(this.getControllerId()); } - + @Override public String getRule() { return "Whenever you play a card, draw a card."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java b/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java index 74717e6e7c..49a334ddfd 100644 --- a/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java +++ b/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class OjutaiExemplars extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("a noncreature spell"); static { @@ -66,7 +66,7 @@ public class OjutaiExemplars extends CardImpl { } public OjutaiExemplars(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.MONK); this.power = new MageInt(4); @@ -75,22 +75,22 @@ public class OjutaiExemplars extends CardImpl { // Whenever you cast a noncreature spell, choose one - Tap target creature; Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filter, false); ability.addTarget(new TargetCreaturePermanent()); - + // Ojutai Exemplars gain first strike and lifelink until end of turn; Mode mode = new Mode(); Effect effect = new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); effect.setText("{this} gains first strike"); mode.getEffects().add(effect); Effect effect2 = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); - effect2.setText("and lifelink"); + effect2.setText("and lifelink until end of turn"); mode.getEffects().add(effect2); ability.addMode(mode); - + // or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control. mode = new Mode(); mode.getEffects().add(new OjutaiExemplarsEffect()); ability.addMode(mode); - + this.addAbility(ability); } @@ -133,4 +133,4 @@ class OjutaiExemplarsEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OrderedMigration.java b/Mage.Sets/src/mage/cards/o/OrderedMigration.java index 179b6d6e62..ee18b8acf7 100644 --- a/Mage.Sets/src/mage/cards/o/OrderedMigration.java +++ b/Mage.Sets/src/mage/cards/o/OrderedMigration.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.CreateTokenEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.game.permanent.token.OrderedMigrationBirdToken; @@ -47,6 +48,7 @@ public class OrderedMigration extends CardImpl { // Domain - Create a 1/1 blue Bird creature token with flying for each basic land type among lands you control. this.getSpellAbility().addEffect(new CreateTokenEffect(new OrderedMigrationBirdToken(), new DomainValue())); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public OrderedMigration(final OrderedMigration card) { diff --git a/Mage.Sets/src/mage/cards/o/Overload.java b/Mage.Sets/src/mage/cards/o/Overload.java index 3913a90d2e..6e956bb8f7 100644 --- a/Mage.Sets/src/mage/cards/o/Overload.java +++ b/Mage.Sets/src/mage/cards/o/Overload.java @@ -29,17 +29,17 @@ package mage.cards.o; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetArtifactPermanent; /** @@ -48,32 +48,15 @@ import mage.target.common.TargetArtifactPermanent; */ public class Overload extends CardImpl { - private static final FilterArtifactPermanent filter2 = new FilterArtifactPermanent("artifact if its converted mana cost is 2 or less"); - private static final FilterArtifactPermanent filter5 = new FilterArtifactPermanent("artifact if its converted mana cost is 5 or less"); - - static { - filter2.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); - filter5.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 5)); - } - public Overload(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); // Kicker {2} this.addAbility(new KickerAbility("{2}")); + // Destroy target artifact if its converted mana cost is 2 or less. If Overload was kicked, destroy that artifact if its converted mana cost is 5 or less instead. this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addTarget(new TargetArtifactPermanent(filter5)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { - if(!KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - ability.getTargets().add(new TargetArtifactPermanent(filter2)); - } - } + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); } public Overload(final Overload card) { @@ -85,3 +68,36 @@ public class Overload extends CardImpl { return new Overload(this); } } + +class OverloadEffect extends OneShotEffect { + + OverloadEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target artifact if its converted mana cost is 2 or less. If {this} was kicked, destroy that artifact if its converted mana cost is 5 or less instead."; + } + + OverloadEffect(final OverloadEffect effect) { + super(effect); + } + + @Override + public OverloadEffect copy() { + return new OverloadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent targetArtifact = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + if (targetArtifact != null) { + int cmc = targetArtifact.getConvertedManaCost(); + if (cmc <= 2 || (KickedCondition.instance.apply(game, source) && cmc <= 5)) { + targetArtifact.destroy(source.getSourceId(), game, false); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/o/Ovinize.java b/Mage.Sets/src/mage/cards/o/Ovinize.java index a69bc20af0..6c9af1d7dc 100644 --- a/Mage.Sets/src/mage/cards/o/Ovinize.java +++ b/Mage.Sets/src/mage/cards/o/Ovinize.java @@ -40,16 +40,19 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class Ovinize extends CardImpl { public Ovinize(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Target creature loses all abilities and becomes 0/1 until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().addEffect( + new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) + .setText("Until end of turn, target creature loses all abilities") + ); Effect effect = new SetPowerToughnessTargetEffect(0, 1, Duration.EndOfTurn); effect.setText("and has base power and toughness 0/1"); this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/p/PoulticeSliver.java b/Mage.Sets/src/mage/cards/p/PoulticeSliver.java index 4d7cf354c9..079aab0ce4 100644 --- a/Mage.Sets/src/mage/cards/p/PoulticeSliver.java +++ b/Mage.Sets/src/mage/cards/p/PoulticeSliver.java @@ -66,7 +66,7 @@ public class PoulticeSliver extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, - "Slivers have \"{2}, {T}: Regenerate target Sliver.\""))); + "All Slivers have \"{2}, {T}: Regenerate target Sliver.\""))); } public PoulticeSliver(final PoulticeSliver card) { diff --git a/Mage.Sets/src/mage/cards/p/PowerArmor.java b/Mage.Sets/src/mage/cards/p/PowerArmor.java index 11fce7c8ca..ae96023b0f 100644 --- a/Mage.Sets/src/mage/cards/p/PowerArmor.java +++ b/Mage.Sets/src/mage/cards/p/PowerArmor.java @@ -36,6 +36,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; @@ -48,13 +49,14 @@ import mage.target.common.TargetCreaturePermanent; public class PowerArmor extends CardImpl { public PowerArmor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Domain - {3}, {tap}: Target creature gets +1/+1 until end of turn for each basic land type among lands you control. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect( new DomainValue(), new DomainValue(), Duration.EndOfTurn), new TapSourceCost()); ability.addCost(new ManaCostsImpl("{3}")); ability.addTarget(new TargetCreaturePermanent()); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PrisonBarricade.java b/Mage.Sets/src/mage/cards/p/PrisonBarricade.java index c5f63fd01a..1e9e12b7c3 100644 --- a/Mage.Sets/src/mage/cards/p/PrisonBarricade.java +++ b/Mage.Sets/src/mage/cards/p/PrisonBarricade.java @@ -46,26 +46,28 @@ import mage.counters.CounterType; /** * * @author LoneFox - + * */ public class PrisonBarricade extends CardImpl { public PrisonBarricade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.WALL); this.power = new MageInt(1); this.toughness = new MageInt(3); - // Defender - this.addAbility(DefenderAbility.getInstance()); // Kicker {1}{W} this.addAbility(new KickerAbility("{1}{W}")); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + // If Prison Barricade was kicked, it enters the battlefield with a +1/+1 counter on it and with "Prison Barricade can attack as though it didn't have defender." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.instance, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); + KickedCondition.instance, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield)); this.addAbility(ability); - } + } public PrisonBarricade(final PrisonBarricade card) { super(card); diff --git a/Mage.Sets/src/mage/cards/p/Probe.java b/Mage.Sets/src/mage/cards/p/Probe.java index 9430f0c0da..35f7b37351 100644 --- a/Mage.Sets/src/mage/cards/p/Probe.java +++ b/Mage.Sets/src/mage/cards/p/Probe.java @@ -48,17 +48,17 @@ import mage.target.TargetPlayer; public class Probe extends CardImpl { public Probe(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Kicker {1}{B} this.addAbility(new KickerAbility("{1}{B}")); // Draw three cards, then discard two cards. - this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(3,2)); + this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(3, 2)); // If Probe was kicked, target player discards two cards. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DiscardTargetEffect(2), - KickedCondition.instance, - "If {this} was kicked, target player discards two cards")); + new DiscardTargetEffect(2), + KickedCondition.instance, + "

If {this} was kicked, target player discards two cards")); } @Override @@ -70,7 +70,7 @@ public class Probe extends CardImpl { } } } - + public Probe(final Probe card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/p/Prohibit.java b/Mage.Sets/src/mage/cards/p/Prohibit.java index f7d8641138..1fe9390078 100644 --- a/Mage.Sets/src/mage/cards/p/Prohibit.java +++ b/Mage.Sets/src/mage/cards/p/Prohibit.java @@ -29,17 +29,17 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.filter.FilterSpell; -import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.constants.Outcome; import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; import mage.target.TargetSpell; /** @@ -48,34 +48,15 @@ import mage.target.TargetSpell; */ public class Prohibit extends CardImpl { - private static final FilterSpell filter2 = new FilterSpell("spell if its converted mana cost is 2 or less"); - private static final FilterSpell filter4 = new FilterSpell("spell if its converted mana cost is 4 or less"); - - static { - filter2.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); - filter4.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 5)); - } - public Prohibit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Kicker {2} this.addAbility(new KickerAbility("{2}")); // Counter target spell if its converted mana cost is 2 or less. If Prohibit was kicked, counter that spell if its converted mana cost is 4 or less instead. this.getSpellAbility().addEffect(new CounterTargetEffect()); - this.getSpellAbility().addTarget(new TargetSpell(filter4)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - if (!KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - ability.getTargets().add(new TargetSpell(filter2)); - } - } + this.getSpellAbility().addTarget(new TargetSpell()); } public Prohibit(final Prohibit card) { @@ -87,3 +68,36 @@ public class Prohibit extends CardImpl { return new Prohibit(this); } } + +class OverloadEffect extends OneShotEffect { + + OverloadEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Counter target spell if its converted mana cost is 2 or less. If {this} was kicked, counter that spell if its converted mana cost is 4 or less instead."; + } + + OverloadEffect(final OverloadEffect effect) { + super(effect); + } + + @Override + public OverloadEffect copy() { + return new OverloadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Spell targetSpell = game.getSpell(this.getTargetPointer().getFirst(game, source)); + if (targetSpell != null) { + int cmc = targetSpell.getConvertedManaCost(); + if (cmc <= 2 || (KickedCondition.instance.apply(game, source) && cmc <= 4)) { + targetSpell.counter(source.getSourceId(), game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PyreZombie.java b/Mage.Sets/src/mage/cards/p/PyreZombie.java index 86200277be..7dc0441124 100644 --- a/Mage.Sets/src/mage/cards/p/PyreZombie.java +++ b/Mage.Sets/src/mage/cards/p/PyreZombie.java @@ -52,15 +52,15 @@ import mage.target.common.TargetCreatureOrPlayer; public class PyreZombie extends CardImpl { public PyreZombie(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(2); this.toughness = new MageInt(1); // At the beginning of your upkeep, if Pyre Zombie is in your graveyard, you may pay {1}{B}{B}. If you do, return Pyre Zombie to your hand. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, - new DoIfCostPaid(new ReturnToHandSourceEffect(), new ManaCostsImpl("{1}{B}{B}")), - TargetController.YOU, false)); + new DoIfCostPaid(new ReturnToHandSourceEffect().setText("return {this} to your hand"), new ManaCostsImpl("{1}{B}{B}")), + TargetController.YOU, false)); // {1}{R}{R}, Sacrifice Pyre Zombie: Pyre Zombie deals 2 damage to target creature or player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl("{1}{R}{R}")); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java b/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java index 7904d92d3a..9da954dd66 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java @@ -41,6 +41,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; @@ -55,22 +56,24 @@ import mage.target.common.TargetCreaturePermanent; public class QuicksilverDagger extends CardImpl { public QuicksilverDagger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{R}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature has "{tap}: This creature deals 1 damage to target player. You draw a card." Ability gainAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); gainAbility.addTarget(new TargetPlayer()); gainAbility.addEffect(new DrawCardSourceControllerEffect(1)); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainAbility, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityAttachedEffect(gainAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, + "Enchanted creature has \"{tap}: This creature deals 1 damage to target player. You draw a card.\"") + )); } public QuicksilverDagger(final QuicksilverDagger card) { diff --git a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java index 24d7e351d2..ee26c88734 100644 --- a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java +++ b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java @@ -36,7 +36,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterBasicLandCard; import mage.target.common.TargetCardInLibrary; /** @@ -46,14 +45,14 @@ import mage.target.common.TargetCardInLibrary; public class QuirionTrailblazer extends CardImpl { public QuirionTrailblazer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SCOUT); this.power = new MageInt(1); this.toughness = new MageInt(2); // When Quirion Trailblazer enters the battlefield, you may search your library for a basic land card and put that card onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); } public QuirionTrailblazer(final QuirionTrailblazer card) { diff --git a/Mage.Sets/src/mage/cards/r/RedManaBattery.java b/Mage.Sets/src/mage/cards/r/RedManaBattery.java index 2b6fbe11d0..224f287c21 100644 --- a/Mage.Sets/src/mage/cards/r/RedManaBattery.java +++ b/Mage.Sets/src/mage/cards/r/RedManaBattery.java @@ -67,7 +67,7 @@ public class RedManaBattery extends CardImpl { "Add {R} to your mana pool, then add {R} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java b/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java index bfda5d16f0..48c4854bb8 100644 --- a/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java +++ b/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java @@ -44,7 +44,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class RewardsOfDiversity extends CardImpl { - private static final FilterSpell filter = new FilterSpell("multicolored spell"); + private static final FilterSpell filter = new FilterSpell("a multicolored spell"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); @@ -52,7 +52,7 @@ public class RewardsOfDiversity extends CardImpl { } public RewardsOfDiversity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Whenever an opponent casts a multicolored spell, you gain 4 life. this.addAbility(new SpellCastOpponentTriggeredAbility(new GainLifeEffect(4), filter, false)); diff --git a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java index 75ab550c54..0b5dcc205c 100644 --- a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java +++ b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java @@ -53,15 +53,15 @@ import mage.util.CardUtil; * @author LevelX2 */ public class RisenExecutioner extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie creatures"); - + static { filter.add(new SubtypePredicate(SubType.ZOMBIE)); } - + public RisenExecutioner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(4); @@ -69,16 +69,16 @@ public class RisenExecutioner extends CardImpl { // Risen Executioner can't block. this.addAbility(new CantBlockAbility()); - + // Other Zombie creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); - + // You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard. // TODO: cost increase does not happen if Risen Executioner is cast grom graveyard because of other effects Ability ability = new SimpleStaticAbility(Zone.ALL, new RisenExecutionerCastEffect()); ability.addEffect(new RisenExecutionerCostIncreasingEffect()); this.addAbility(ability); - + } public RisenExecutioner(final RisenExecutioner card) { @@ -92,10 +92,10 @@ public class RisenExecutioner extends CardImpl { } class RisenExecutionerCastEffect extends AsThoughEffectImpl { - + RisenExecutionerCastEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit); - staticText = "You may cast {this} from your graveyard"; + staticText = "You may cast {this} from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard"; } RisenExecutionerCastEffect(final RisenExecutionerCastEffect effect) { @@ -116,8 +116,8 @@ class RisenExecutionerCastEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); - if (card != null - && card.getOwnerId().equals(affectedControllerId) + if (card != null + && card.getOwnerId().equals(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { return true; } @@ -129,14 +129,14 @@ class RisenExecutionerCastEffect extends AsThoughEffectImpl { class RisenExecutionerCostIncreasingEffect extends CostModificationEffectImpl { protected static final FilterCreatureCard filter = new FilterCreatureCard(); - + static { filter.add(new AnotherCardPredicate()); } - - RisenExecutionerCostIncreasingEffect () { + + RisenExecutionerCostIncreasingEffect() { super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.INCREASE_COST); - staticText = "if you pay {1} more to cast it for each other creature card in your graveyard"; + staticText = ""; } RisenExecutionerCostIncreasingEffect(final RisenExecutionerCostIncreasingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/r/RoilingHorror.java b/Mage.Sets/src/mage/cards/r/RoilingHorror.java index fe6d3c8f91..dcb8b43196 100644 --- a/Mage.Sets/src/mage/cards/r/RoilingHorror.java +++ b/Mage.Sets/src/mage/cards/r/RoilingHorror.java @@ -59,18 +59,20 @@ import mage.target.TargetPlayer; public class RoilingHorror extends CardImpl { public RoilingHorror(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.HORROR); this.power = new MageInt(0); this.toughness = new MageInt(0); // Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new RoilingHorrorDynamicValue(), Duration.EndOfGame))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new RoilingHorrorDynamicValue(), Duration.EndOfGame) + .setText("{this}'s power and toughness are each equal to your life total minus the life total of an opponent with the most life.") + )); // Suspend X-{X}{B}{B}{B}. X can't be 0. this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl("{B}{B}{B}"), this, true)); - + // Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. this.addAbility(new RoilingHorrorTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java b/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java index 77c70ea0e2..e15ba49ae2 100644 --- a/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java +++ b/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java @@ -43,17 +43,18 @@ import mage.game.permanent.token.SaprolingToken; /** * * @author LoneFox - + * */ public class SaprolingSymbiosis extends CardImpl { public SaprolingSymbiosis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); Effect effect = new CreateTokenEffect(new SaprolingToken(), new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent())); // You may cast Saproling Symbiosis as though it had flash if you pay {2} more to cast it. Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl("{2}")); ability.addEffect(effect); + ability.setRuleAtTheTop(true); this.addAbility(ability); // Create a 1/1 green Saproling creature token for each creature you control. this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java index be4e25985e..48a642f9b1 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCardInLibrary; */ public class SarkhanUnbroken extends CardImpl { - private static final FilterCard dragonFilter = new FilterCard("Dragon creature card"); + private static final FilterCard dragonFilter = new FilterCard("Dragon creature cards"); static { dragonFilter.add(new SubtypePredicate(SubType.DRAGON)); diff --git a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java index ba3e595729..27ab1c640a 100644 --- a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java +++ b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java @@ -65,7 +65,7 @@ public class SawtoothLoon extends CardImpl { } public SawtoothLoon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -94,7 +94,7 @@ class SawtoothLoonEffect extends OneShotEffect { public SawtoothLoonEffect() { super(Outcome.DrawCard); - this.staticText = "Draw two cards, then put two cards from your hand on the bottom of your library"; + this.staticText = "draw two cards, then put two cards from your hand on the bottom of your library"; } public SawtoothLoonEffect(final SawtoothLoonEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java index e354df9011..c1d7edba64 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java +++ b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java @@ -81,7 +81,7 @@ class ScaleBlessingEffect extends OneShotEffect { public ScaleBlessingEffect() { super(Outcome.Benefit); - this.staticText = ", then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. "; + this.staticText = ", then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. (To bolster 1, choose a creature with the least toughness among creatures you control and put +1/+1 counter on it.)"; } public ScaleBlessingEffect(final ScaleBlessingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java index 03828716ff..c0a19bac1d 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java +++ b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java @@ -62,7 +62,7 @@ public class ScaleguardSentinels extends CardImpl { } public ScaleguardSentinels(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); @@ -74,7 +74,7 @@ public class ScaleguardSentinels extends CardImpl { // Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), ScaleguardSentinelsCondition.instance, - "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}", ""), + "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}.", ""), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/ScorchingLava.java b/Mage.Sets/src/mage/cards/s/ScorchingLava.java index 51bb207a58..3ce722d731 100644 --- a/Mage.Sets/src/mage/cards/s/ScorchingLava.java +++ b/Mage.Sets/src/mage/cards/s/ScorchingLava.java @@ -65,8 +65,9 @@ public class ScorchingLava extends CardImpl { this.getSpellAbility().addEffect(new ConditionalContinuousRuleModifyingEffect( new CantRegenerateTargetEffect(Duration.EndOfTurn, "that creature"), new LockedInCondition(KickedCondition.instance))); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - (OneShotEffect) new ExileTargetIfDiesEffect().setText("and if it would die this turn, exile it instead"), - new LockedInCondition(KickedCondition.instance))); + new ExileTargetIfDiesEffect(), + new LockedInCondition(KickedCondition.instance) + ).setText("and if it would die this turn, exile it instead")); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/cards/s/SeersVision.java b/Mage.Sets/src/mage/cards/s/SeersVision.java index 389d362363..c4f694f0f7 100644 --- a/Mage.Sets/src/mage/cards/s/SeersVision.java +++ b/Mage.Sets/src/mage/cards/s/SeersVision.java @@ -48,12 +48,12 @@ import mage.target.TargetPlayer; public class SeersVision extends CardImpl { public SeersVision(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}"); // Your opponents play with their hands revealed. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithHandRevealedEffect(TargetController.OPPONENT))); // Sacrifice Seer's Vision: Look at target player's hand and choose a card from it. That player discards that card. Activate this ability only any time you could cast a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardCardYouChooseTargetEffect(), new SacrificeSourceCost()); + Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardCardYouChooseTargetEffect(TargetController.ANY), new SacrificeSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java b/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java index b4c2ffd74b..f8e235f3db 100644 --- a/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java +++ b/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java @@ -55,7 +55,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class ServantOfTheScale extends CardImpl { public ServantOfTheScale(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(0); @@ -63,7 +63,7 @@ public class ServantOfTheScale extends CardImpl { // Servant of the Scale enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - "with a +1/+1 counters on it")); + "with a +1/+1 counter on it")); // When Servant of the Scale dies, put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counter on Servant of the Scale. Ability ability = new DiesTriggeredAbility(new ServantOfTheScaleEffect(), false); @@ -85,7 +85,7 @@ class ServantOfTheScaleEffect extends OneShotEffect { public ServantOfTheScaleEffect() { super(Outcome.BoostCreature); - this.staticText = "put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counter on {this}"; + this.staticText = "put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counters on {this}"; } public ServantOfTheScaleEffect(final ServantOfTheScaleEffect effect) { @@ -101,8 +101,8 @@ class ServantOfTheScaleEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (sourcePermanent != null && controller != null && - (sourcePermanent.getZoneChangeCounter(game) == source.getSourceObjectZoneChangeCounter() // Token + if (sourcePermanent != null && controller != null + && (sourcePermanent.getZoneChangeCounter(game) == source.getSourceObjectZoneChangeCounter() // Token || sourcePermanent.getZoneChangeCounter(game) + 1 == source.getSourceObjectZoneChangeCounter())) { // PermanentCard int amount = sourcePermanent.getCounters(game).getCount(CounterType.P1P1); if (amount > 0) { diff --git a/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java b/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java index 4a855a92b6..329a6620be 100644 --- a/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java +++ b/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class ShieldhideDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class ShieldhideDragon extends CardImpl { } public ShieldhideDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // Lifelink this.addAbility(LifelinkAbility.getInstance()); - + // Megamorph {5}{W}{W} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{W}{W}"), true)); - + // When Shieldhide Dragon is turned face up, put a +1/+1 counter on each other Dragon you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java b/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java index 1ddb95a8b7..77fbf8d6b7 100644 --- a/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java +++ b/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java @@ -59,11 +59,11 @@ public class SightOfTheScalelords extends CardImpl { } public SightOfTheScalelords(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); // At the beginning of combat on your turn, creature you control with toughness 4 or greater get +2/+2 and gain vigilance until end of turn. - Effect effect = new BoostControlledEffect(2,2,Duration.EndOfTurn, filter, false); - effect.setText("creature you control with toughness 4 or greater get +2/+2"); + Effect effect = new BoostControlledEffect(2, 2, Duration.EndOfTurn, filter, false); + effect.setText("creatures you control with toughness 4 or greater get +2/+2"); Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, false, false); effect = new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, filter); effect.setText("and gain vigilance until end of turn"); diff --git a/Mage.Sets/src/mage/cards/s/StormriderRig.java b/Mage.Sets/src/mage/cards/s/StormriderRig.java index 1257360455..740d3e3025 100644 --- a/Mage.Sets/src/mage/cards/s/StormriderRig.java +++ b/Mage.Sets/src/mage/cards/s/StormriderRig.java @@ -50,20 +50,20 @@ import mage.filter.common.FilterControlledCreaturePermanent; public class StormriderRig extends CardImpl { public StormriderRig(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); + // Whenever a creature enters the battlefield under your control, you may attach Stormrider Rig to it. this.addAbility(new EntersBattlefieldAllTriggeredAbility( Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), - new FilterControlledCreaturePermanent(), true, SetTargetPointer.PERMANENT, null, true)); - + new FilterControlledCreaturePermanent("a creature"), true, SetTargetPointer.PERMANENT, null, true)); + // Equip {2} - this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); - + this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); + } public StormriderRig(final StormriderRig card) { diff --git a/Mage.Sets/src/mage/cards/s/StormscapeMaster.java b/Mage.Sets/src/mage/cards/s/StormscapeMaster.java index fa30ec1d16..2fc0a0097e 100644 --- a/Mage.Sets/src/mage/cards/s/StormscapeMaster.java +++ b/Mage.Sets/src/mage/cards/s/StormscapeMaster.java @@ -49,12 +49,12 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class StormscapeMaster extends CardImpl { public StormscapeMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(2); @@ -70,7 +70,7 @@ public class StormscapeMaster extends CardImpl { // {B}{B}, {T}: Target player loses 2 life and you gain 2 life. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2), new ManaCostsImpl("{B}{B}")); - ability.addEffect(new GainLifeEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/StormwingDragon.java b/Mage.Sets/src/mage/cards/s/StormwingDragon.java index e16ba6e75f..daae80e3be 100644 --- a/Mage.Sets/src/mage/cards/s/StormwingDragon.java +++ b/Mage.Sets/src/mage/cards/s/StormwingDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class StormwingDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class StormwingDragon extends CardImpl { } public StormwingDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // First strike this.addAbility(FirstStrikeAbility.getInstance()); - + // Megamorph {5}{R}{R} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{R}{R}"), true)); - + // When Stormwing Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SulfurElemental.java b/Mage.Sets/src/mage/cards/s/SulfurElemental.java index a43214d4a4..741e04f513 100644 --- a/Mage.Sets/src/mage/cards/s/SulfurElemental.java +++ b/Mage.Sets/src/mage/cards/s/SulfurElemental.java @@ -48,25 +48,28 @@ import mage.filter.predicate.mageobject.ColorPredicate; * @author LevelX2 */ public class SulfurElemental extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creatures"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); } public SulfurElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(3); this.toughness = new MageInt(2); - // Flash - this.addAbility(FlashAbility.getInstance()); // Split second this.addAbility(new SplitSecondAbility()); + + // Flash + this.addAbility(FlashAbility.getInstance()); + // White creatures get +1/-1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,-1, Duration.WhileOnBattlefield, filter, false))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, -1, Duration.WhileOnBattlefield, filter, false))); } public SulfurElemental(final SulfurElemental card) { diff --git a/Mage.Sets/src/mage/cards/t/TemporalDistortion.java b/Mage.Sets/src/mage/cards/t/TemporalDistortion.java index 1a18ec7e82..302059905e 100644 --- a/Mage.Sets/src/mage/cards/t/TemporalDistortion.java +++ b/Mage.Sets/src/mage/cards/t/TemporalDistortion.java @@ -57,7 +57,7 @@ import mage.game.permanent.Permanent; */ public class TemporalDistortion extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("creature or land"); + private static final FilterPermanent filter = new FilterPermanent("a creature or land"); private static final FilterPermanent filter2 = new FilterPermanent("permanents with hourglass counters on them"); static { diff --git a/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java b/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java index b6f623d1f2..f7e84c7e1a 100644 --- a/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java +++ b/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java @@ -51,7 +51,7 @@ import mage.target.TargetPlayer; public class ThunderscapeMaster extends CardImpl { public ThunderscapeMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -60,7 +60,7 @@ public class ThunderscapeMaster extends CardImpl { // {B}{B}, {tap}: Target player loses 2 life and you gain 2 life. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2), new ManaCostsImpl("{B}{B}")); - ability.addEffect(new GainLifeEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java b/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java index 8a00564be4..2ce0b055bd 100644 --- a/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java +++ b/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java @@ -24,7 +24,7 @@ * 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.u; import java.util.UUID; @@ -45,15 +45,15 @@ import mage.constants.Zone; import mage.counters.CounterType; /** -* -* @author LevelX2 -*/ + * + * @author LevelX2 + */ public class UrborgSkeleton extends CardImpl { - private static final String staticText = "If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it"; + private static final String staticText = "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it."; public UrborgSkeleton(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.SKELETON); this.power = new MageInt(0); @@ -68,7 +68,7 @@ public class UrborgSkeleton extends CardImpl { // If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it. Ability ability = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.instance, staticText,""); + KickedCondition.instance, staticText, ""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VodalianMerchant.java b/Mage.Sets/src/mage/cards/v/VodalianMerchant.java index 448e135a9d..c63300fd07 100644 --- a/Mage.Sets/src/mage/cards/v/VodalianMerchant.java +++ b/Mage.Sets/src/mage/cards/v/VodalianMerchant.java @@ -29,7 +29,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -43,13 +43,13 @@ import mage.constants.SubType; public class VodalianMerchant extends CardImpl { public VodalianMerchant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.MERFOLK); this.power = new MageInt(1); this.toughness = new MageInt(2); // When Vodalian Merchant enters the battlefield, draw a card, then discard a card. - this.addAbility(new EntersBattlefieldAbility(new DrawDiscardControllerEffect(1, 1, false))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1, false))); } public VodalianMerchant(final VodalianMerchant card) { diff --git a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java index fada4c7f92..9e78d925f2 100644 --- a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java +++ b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java @@ -67,7 +67,7 @@ public class WhiteManaBattery extends CardImpl { "Add {W} to your mana pool, then add {W} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index 9c8e54dd50..5e4ea50e9a 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -480,21 +480,21 @@ public class Mana implements Comparable, Serializable, Copyable { for (int i = 0; i < colorless; i++) { sbMana.append("{C}"); } + for (int i = 0; i < white; i++) { + sbMana.append("{W}"); + } + for (int i = 0; i < blue; i++) { + sbMana.append("{U}"); + } + for (int i = 0; i < black; i++) { + sbMana.append("{B}"); + } for (int i = 0; i < red; i++) { sbMana.append("{R}"); } for (int i = 0; i < green; i++) { sbMana.append("{G}"); } - for (int i = 0; i < blue; i++) { - sbMana.append("{U}"); - } - for (int i = 0; i < white; i++) { - sbMana.append("{W}"); - } - for (int i = 0; i < black; i++) { - sbMana.append("{B}"); - } for (int i = 0; i < any; i++) { sbMana.append("{Any}"); } diff --git a/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java b/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java index 599b1a2d81..3faa62f5c4 100644 --- a/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java @@ -26,7 +26,7 @@ public class PayMoreToCastAsThoughtItHadFlashAbility extends SpellAbility { super(card.getSpellAbility().getManaCosts().copy(), card.getName() + " as though it had flash", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); this.costsToAdd = costsToAdd; this.timing = TimingRule.INSTANT; - + this.ruleAtTheTop = true; CardUtil.increaseCost(this, costsToAdd); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java b/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java index 9025cf0af4..e434c86002 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java @@ -45,7 +45,6 @@ import mage.util.CardUtil; */ public class CardsInHandCondition implements Condition { - private Condition condition; private ComparisonType type; private int count; @@ -114,7 +113,7 @@ public class CardsInHandCondition implements Condition { @Override public String toString() { int workCount = count; - StringBuilder sb = new StringBuilder("if "); + StringBuilder sb = new StringBuilder("if"); switch (targetController) { case YOU: sb.append(" you have"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java index 2da6d5747f..14803dfc47 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java @@ -35,6 +35,7 @@ import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.choices.ChoiceColor; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; /** * @author noxx @@ -59,8 +60,10 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { this.manaBuilder = manaBuilder; this.oneChoice = oneChoice; // - staticText = "Add " + amount + " mana of " - + (oneChoice ? "any one color" : "in any combination of colors") + staticText = "Add " + + (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "") + + " mana " + + (oneChoice ? "of any one color" : "in any combination of colors") + " to your mana pool. " + manaBuilder.getRule(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java b/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java index f1c4c1d3a5..97a11cd3e7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java @@ -46,11 +46,12 @@ public class CastSourceTriggeredAbility extends TriggeredAbilityImpl { public CastSourceTriggeredAbility(Effect effect) { this(effect, false); } - + public CastSourceTriggeredAbility(Effect effect, boolean optional) { super(Zone.STACK, effect, optional); + this.ruleAtTheTop = true; } - + public CastSourceTriggeredAbility(final CastSourceTriggeredAbility ability) { super(ability); } @@ -70,7 +71,7 @@ public class CastSourceTriggeredAbility extends TriggeredAbilityImpl { if (event.getSourceId().equals(this.getSourceId())) { MageObject spellObject = game.getObject(sourceId); if (spellObject != null && (spellObject instanceof Spell)) { - Spell spell = (Spell)spellObject; + Spell spell = (Spell) spellObject; if (spell.getSpellAbility() != null) { for (Effect effect : getEffects()) { effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java index a409e5b1fd..d0cdc8fdf2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java @@ -113,7 +113,7 @@ public class CounterUnlessPaysEffect extends OneShotEffect { if (mode.getTargets().isEmpty()) { sb.append("counter it"); } else { - sb.append("Counter target ").append(mode.getTargets().get(0).getTargetName()); + sb.append("counter target ").append(mode.getTargets().get(0).getTargetName()); } sb.append(" unless its controller pays "); if (cost != null) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java index 796fb67700..79bd6484f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common; +import java.util.List; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -45,7 +46,7 @@ public class GetEmblemEffect extends OneShotEffect { public GetEmblemEffect(Emblem emblem) { super(Outcome.Benefit); this.emblem = emblem; - this.staticText = "You get an emblem with \"" + emblem.getAbilities().getRules(null) + '"'; + this.staticText = "You get an emblem with \"" + +'"'; } public GetEmblemEffect(final GetEmblemEffect effect) { @@ -68,4 +69,21 @@ public class GetEmblemEffect extends OneShotEffect { return true; } + public String getText() { + StringBuilder sb = new StringBuilder(); + sb.append("You get an emblem with \""); + List rules = emblem.getAbilities().getRules(null); + if (rules.size() == 1) { + sb.append(rules.get(0)); + sb.append('"'); + } else if (rules.size() == 2) { + for (String s : rules) { + sb.append(s); + sb.append("\" and \""); + } + sb.append('"'); + } + sb.append('.'); + return sb.toString(); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java index 63effc4e1c..8c0d69c78c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java @@ -82,27 +82,27 @@ public class NameACardEffect extends OneShotEffect { switch (typeOfName) { case ALL: cardChoice.setChoices(CardRepository.instance.getNames()); - cardChoice.setMessage("Name a card"); + cardChoice.setMessage("Choose a card name"); break; case NON_ARTIFACT_AND_NON_LAND_NAME: cardChoice.setChoices(CardRepository.instance.getNonArtifactAndNonLandNames()); - cardChoice.setMessage("Name a non artifact and non land card"); + cardChoice.setMessage("Choose a nonartifact, nonland card name"); break; case NON_LAND_AND_NON_CREATURE_NAME: cardChoice.setChoices(CardRepository.instance.getNonLandAndNonCreatureNames()); - cardChoice.setMessage("Name a non land and non creature card"); + cardChoice.setMessage("Choose a nonland and non creature card"); break; case NON_LAND_NAME: cardChoice.setChoices(CardRepository.instance.getNonLandNames()); - cardChoice.setMessage("Name a non land card"); + cardChoice.setMessage("Choose a nonland card name"); break; case CREATURE_NAME: cardChoice.setChoices(CardRepository.instance.getCreatureNames()); - cardChoice.setMessage("Name a creature card"); + cardChoice.setMessage("Choose a creature card name"); break; case ARTIFACT_NAME: cardChoice.setChoices(CardRepository.instance.getArtifactNames()); - cardChoice.setMessage("Name an artifact card"); + cardChoice.setMessage("Choose an artifact card name"); break; } cardChoice.clearChoice(); @@ -130,7 +130,7 @@ public class NameACardEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("name a "); + StringBuilder sb = new StringBuilder("choose a "); switch (typeOfName) { case ALL: sb.append("card"); @@ -139,7 +139,7 @@ public class NameACardEffect extends OneShotEffect { sb.append("nonartifact, nonland card"); break; case NON_LAND_AND_NON_CREATURE_NAME: - sb.append("card other than a creature or a land card"); + sb.append("noncreature, nonland card"); break; case NON_LAND_NAME: sb.append("nonland card"); @@ -151,6 +151,7 @@ public class NameACardEffect extends OneShotEffect { sb.append("artifact card"); break; } + sb.append(" name"); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java index f5a366b6c1..7cf8dbfd71 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java @@ -48,7 +48,7 @@ public class UntapAllThatAttackedEffect extends OneShotEffect { public UntapAllThatAttackedEffect() { super(Outcome.Benefit); - staticText = " Untap all creatures that attacked this turn"; + staticText = "Untap all creatures that attacked this turn"; } public UntapAllThatAttackedEffect(final UntapAllThatAttackedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java index fdd2aefac5..fae351becc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java @@ -30,6 +30,7 @@ package mage.abilities.effects.common.combat; import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -45,8 +46,9 @@ public class CantBeBlockedByAllTargetEffect extends RestrictionEffect { public CantBeBlockedByAllTargetEffect(FilterCreaturePermanent filterBlockedBy, Duration duration) { super(duration); this.filterBlockedBy = filterBlockedBy; - staticText = "Target creature" + staticText = "target creature" + " can't be blocked " + + (duration == EndOfTurn ? "this turn " : "") + (filterBlockedBy.getMessage().startsWith("except by") ? "" : "by ") + filterBlockedBy.getMessage(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java index 884cc61e3a..4b9eedc8f6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java @@ -125,7 +125,7 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Enchanted creature gets "); + sb.append("enchanted creature gets "); String p = power.toString(); if (!p.startsWith("-")) { sb.append('+'); diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java index 52f45373b0..75ba52ece3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java @@ -37,6 +37,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; /** * @@ -106,9 +107,9 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { sb.append("search your library for "); if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) { if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) { - sb.append("any number of ").append(' '); + sb.append("any number of "); } else { - sb.append("up to ").append(target.getMaxNumberOfTargets()).append(' '); + sb.append("up to ").append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(' '); } sb.append(target.getTargetName()).append(" and put them onto the battlefield"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java index c29a2ef4cf..c090088572 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java @@ -122,7 +122,7 @@ public class BolsterEffect extends OneShotEffect { } else { sb.append("X, where X is the number of "); sb.append(amount.getMessage()); - sb.append(". (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)"); + sb.append(" (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)"); } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/keyword/DashAbility.java b/Mage/src/main/java/mage/abilities/keyword/DashAbility.java index 93a7f9fe42..96d2e45a43 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DashAbility.java @@ -78,6 +78,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), DashedCondition.instance, "", ""); ability.addEffect(new DashAddDelayedTriggeredAbilityEffect()); + ability.setRuleVisible(false); addSubAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java index 88e97204f6..b871cf0b81 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class ReachAbility extends StaticAbility implements MageSingleton { - private static final ReachAbility instance = new ReachAbility(); + private static final ReachAbility instance = new ReachAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class ReachAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Reach"; + return "reach"; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java index 3382b061db..0921b18e12 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java @@ -166,7 +166,7 @@ public class SuspendAbility extends SpecialAction { } StringBuilder sb = new StringBuilder("Suspend "); if (cost != null) { - sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append(" - ").append(cost.getText()); + sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append(" - ").append(cost.getText()).append(suspend == Integer.MAX_VALUE ? ". X can't be 0" : ""); if (!shortRule) { sb.append(" (Rather than cast this card from your hand, pay ") .append(cost.getText()) From 54b8f10c3cdd01da8c3717950f1a5231cef7e3b6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 16:08:06 -0400 Subject: [PATCH 006/164] text fixes and test fixes to fix how tests test text, then more text next --- .../src/mage/cards/b/BanishingKnack.java | 8 ++-- .../src/mage/cards/b/BelltollDragon.java | 8 ++-- .../src/mage/cards/b/BlackManaBattery.java | 8 ++-- .../src/mage/cards/b/BlueManaBattery.java | 8 ++-- Mage.Sets/src/mage/cards/d/DeityOfScars.java | 5 +-- .../src/mage/cards/d/DescentOfTheDragons.java | 2 +- .../src/mage/cards/d/DuergarMineCaptain.java | 11 ++++-- .../src/mage/cards/d/DutifulAttendant.java | 4 +- .../src/mage/cards/f/FieryBombardment.java | 9 +++-- Mage.Sets/src/mage/cards/f/FireAtWill.java | 5 +-- Mage.Sets/src/mage/cards/g/GilderBairn.java | 4 +- .../src/mage/cards/g/GleamOfAuthority.java | 4 +- .../src/mage/cards/g/GreenManaBattery.java | 8 ++-- Mage.Sets/src/mage/cards/h/HelixPinnacle.java | 2 +- .../src/mage/cards/m/MerrowBonegnawer.java | 4 +- Mage.Sets/src/mage/cards/m/Moonhold.java | 8 ++-- Mage.Sets/src/mage/cards/n/NightskyMimic.java | 4 +- Mage.Sets/src/mage/cards/p/PunctureBlast.java | 3 +- .../src/mage/cards/r/RedManaBattery.java | 8 ++-- .../src/mage/cards/r/RekindledFlame.java | 19 ++++++---- Mage.Sets/src/mage/cards/s/ScaleBlessing.java | 6 +-- .../src/mage/cards/s/ShorecrasherMimic.java | 4 +- Mage.Sets/src/mage/cards/t/TalarasBane.java | 15 ++++---- .../src/mage/cards/u/UnnervingAssault.java | 16 ++++---- Mage.Sets/src/mage/cards/w/WakeThrasher.java | 10 ++--- Mage.Sets/src/mage/cards/w/WardOfBones.java | 4 +- .../src/mage/cards/w/WhiteManaBattery.java | 8 ++-- .../abilities/keywords/DeathtouchTest.java | 4 +- .../abilities/keywords/ManifestTest.java | 8 ++-- .../cards/abilities/keywords/SuspendTest.java | 2 +- .../oneshot/exile/ExileAndReturnTest.java | 6 +-- .../oneshot/sacrifice/TradingPostTest.java | 2 +- .../other/SoulfireGrandMasterTest.java | 2 +- .../continuous/AngelOfJubilationTest.java | 6 +-- .../cards/continuous/SerraAscendantTest.java | 2 +- .../cards/control/ExchangeControlTest.java | 2 +- .../control/GainControlDiedCastAgainTest.java | 2 +- .../control/GainControlTargetEffectTest.java | 6 +-- .../test/cards/control/WillbreakerTest.java | 2 +- .../cards/copy/FeldonOfTheThirdPathTest.java | 4 +- .../test/cards/copy/IsochronScepterTest.java | 8 ++-- .../mage/test/cards/copy/MimicVatTest.java | 8 ++-- .../additional/RemoveCounterCostTest.java | 2 +- .../cost/modification/HeartstoneTest.java | 2 +- .../cards/enchantments/SkullclampTest.java | 2 +- .../test/cards/mana/ConditionalManaTest.java | 2 +- .../mage/test/cards/mana/CryptGhastTest.java | 2 +- .../test/cards/mana/DoublingCubeTest.java | 6 +-- .../test/cards/mana/HarvesterDruidTest.java | 12 +++--- .../cards/mana/NykthosShrineToNyxTest.java | 14 +++---- .../test/cards/mana/ReflectingPoolTest.java | 8 ++-- .../test/cards/mana/SylvokExplorerTest.java | 4 +- .../cards/replacement/GrindstoneTest.java | 37 +++++++++---------- .../replacement/LeylineOfTheVoidTest.java | 2 +- .../ZoneChangeReplacementTest.java | 4 +- .../cards/single/ContagionEngineTest.java | 2 +- .../cards/single/MagewrightStoneTest.java | 2 +- .../test/cards/single/SoulFoundryTest.java | 2 +- .../cards/single/mir/GrinningTotemTest.java | 4 +- .../cards/triggers/BecomesTheTargetTest.java | 2 +- .../test/cards/triggers/SpellskiteTest.java | 2 +- .../test/cards/watchers/FellShepherdTest.java | 2 +- .../multiplayer/BloodchiefAscensionTest.java | 2 +- .../abilities/ProtectionFromTypeTest.java | 4 +- .../org/mage/test/utils/ManaOptionsTest.java | 18 ++++----- .../main/java/mage/abilities/Abilities.java | 2 + .../java/mage/abilities/AbilitiesImpl.java | 9 ++++- .../java/mage/abilities/CompoundAbility.java | 2 +- .../costs/common/UntapTargetCost.java | 10 ++--- .../effects/common/GetEmblemEffect.java | 7 ++-- .../LookLibraryAndPickControllerEffect.java | 6 ++- .../combat/CantBlockAttachedEffect.java | 2 +- .../continuous/BoostEquippedEffect.java | 14 ++++--- .../abilities/keyword/ProtectionAbility.java | 2 +- .../mage/abilities/keyword/WitherAbility.java | 22 ++++++----- Mage/src/test/java/mage/ManaTest.java | 2 +- 76 files changed, 247 insertions(+), 227 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BanishingKnack.java b/Mage.Sets/src/mage/cards/b/BanishingKnack.java index 63501ca598..e583d54741 100644 --- a/Mage.Sets/src/mage/cards/b/BanishingKnack.java +++ b/Mage.Sets/src/mage/cards/b/BanishingKnack.java @@ -51,12 +51,14 @@ public class BanishingKnack extends CardImpl { private static final FilterPermanent filter = new FilterNonlandPermanent(); - public BanishingKnack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); + public BanishingKnack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new TapSourceCost()); gainedAbility.addTarget(new TargetPermanent(filter)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn) + .setText("Until end of turn, target creature gains \"{T}: Return target nonland permanent to its owner's hand.\"") + ); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/b/BelltollDragon.java b/Mage.Sets/src/mage/cards/b/BelltollDragon.java index a2eb839f71..8f62f096ab 100644 --- a/Mage.Sets/src/mage/cards/b/BelltollDragon.java +++ b/Mage.Sets/src/mage/cards/b/BelltollDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class BelltollDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,7 +58,7 @@ public class BelltollDragon extends CardImpl { } public BelltollDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -69,7 +69,7 @@ public class BelltollDragon extends CardImpl { this.addAbility(HexproofAbility.getInstance()); // Megamorph {5}{U}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}{U}"), true)); - + // When Belltoll Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java index 412775a234..4b831bee4f 100644 --- a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java @@ -64,10 +64,10 @@ public class BlackManaBattery extends CardImpl { Mana.BlackMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {B} to your mana pool, then add {B} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {B} to your mana pool, then add {B} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java index 6883996517..4a16c87b1d 100644 --- a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java @@ -64,10 +64,10 @@ public class BlueManaBattery extends CardImpl { Mana.BlueMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {U} to your mana pool, then add {U} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {U} to your mana pool, then add {U} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DeityOfScars.java b/Mage.Sets/src/mage/cards/d/DeityOfScars.java index b996d9bc06..6d979524ba 100644 --- a/Mage.Sets/src/mage/cards/d/DeityOfScars.java +++ b/Mage.Sets/src/mage/cards/d/DeityOfScars.java @@ -50,11 +50,10 @@ import mage.counters.CounterType; public class DeityOfScars extends CardImpl { public DeityOfScars(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B/G}{B/G}{B/G}{B/G}{B/G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B/G}{B/G}{B/G}{B/G}{B/G}"); this.subtype.add(SubType.SPIRIT); this.subtype.add(SubType.AVATAR); - this.power = new MageInt(7); this.toughness = new MageInt(7); @@ -62,7 +61,7 @@ public class DeityOfScars extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Deity of Scars enters the battlefield with two -1/-1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)))); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), "with two -1/-1 counters on it")); // {B/G}, Remove a -1/-1 counter from Deity of Scars: Regenerate Deity of Scars. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B/G}")); diff --git a/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java b/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java index da4c02d0cd..a8ec7660aa 100644 --- a/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java +++ b/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java @@ -72,7 +72,7 @@ class DescentOfTheDragonsEffect extends OneShotEffect { public DescentOfTheDragonsEffect() { super(Outcome.Benefit); - staticText = "Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying"; + staticText = "Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying"; } public DescentOfTheDragonsEffect(final DescentOfTheDragonsEffect effect) { diff --git a/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java b/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java index 09b46d0ffd..aeb1283878 100644 --- a/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java +++ b/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java @@ -45,12 +45,12 @@ import mage.filter.common.FilterAttackingCreature; /** * * @author jeffwadsworth - + * */ public class DuergarMineCaptain extends CardImpl { public DuergarMineCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R/W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R/W}"); this.subtype.add(SubType.DWARF); this.subtype.add(SubType.SOLDIER); @@ -58,10 +58,13 @@ public class DuergarMineCaptain extends CardImpl { this.toughness = new MageInt(1); // {1}{RW}, {untap}: Attacking creatures get +1/+0 until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 0, Duration.EndOfTurn, new FilterAttackingCreature(), false), new ManaCostsImpl("{1}{R/W}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostAllEffect(1, 0, Duration.EndOfTurn, new FilterAttackingCreature("attacking creatures"), false), + new ManaCostsImpl("{1}{R/W}") + ); ability.addCost(new UntapSourceCost()); this.addAbility(ability); - + } public DuergarMineCaptain(final DuergarMineCaptain card) { diff --git a/Mage.Sets/src/mage/cards/d/DutifulAttendant.java b/Mage.Sets/src/mage/cards/d/DutifulAttendant.java index 98407cddd0..a3d5a5e2a8 100644 --- a/Mage.Sets/src/mage/cards/d/DutifulAttendant.java +++ b/Mage.Sets/src/mage/cards/d/DutifulAttendant.java @@ -46,14 +46,14 @@ import mage.target.common.TargetCardInYourGraveyard; */ public class DutifulAttendant extends CardImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard("another creature card from your graveyard"); + private static final FilterCreatureCard filter = new FilterCreatureCard("another target creature card from your graveyard"); static { filter.add(new AnotherCardPredicate()); } public DutifulAttendant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/f/FieryBombardment.java b/Mage.Sets/src/mage/cards/f/FieryBombardment.java index a7c51fa2b1..63d29ac716 100644 --- a/Mage.Sets/src/mage/cards/f/FieryBombardment.java +++ b/Mage.Sets/src/mage/cards/f/FieryBombardment.java @@ -37,6 +37,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -54,15 +55,14 @@ import mage.target.common.TargetCreatureOrPlayer; public class FieryBombardment extends CardImpl { public FieryBombardment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); // Chroma - {2}, Sacrifice a creature: Fiery Bombardment deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost. Effect effect = new FieryBombardmentEffect(); - effect.setText("Chroma - Fiery Bombardment deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent())); ability.addTarget(new TargetCreatureOrPlayer()); + ability.setAbilityWord(AbilityWord.CHROMA); this.addAbility(ability); } @@ -81,6 +81,7 @@ class FieryBombardmentEffect extends OneShotEffect { public FieryBombardmentEffect() { super(Outcome.Benefit); + staticText = "{this} deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost."; } public FieryBombardmentEffect(final FieryBombardmentEffect effect) { @@ -117,4 +118,4 @@ class FieryBombardmentEffect extends OneShotEffect { } return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FireAtWill.java b/Mage.Sets/src/mage/cards/f/FireAtWill.java index 9185696458..182baebb8a 100644 --- a/Mage.Sets/src/mage/cards/f/FireAtWill.java +++ b/Mage.Sets/src/mage/cards/f/FireAtWill.java @@ -54,11 +54,10 @@ public class FireAtWill extends CardImpl { } public FireAtWill(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R/W}{R/W}{R/W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R/W}{R/W}{R/W}"); // Fire at Will deals 3 damage divided as you choose among one, two, or three target attacking or blocking creatures. - this.getSpellAbility().addEffect(new DamageMultiEffect(3)); + this.getSpellAbility().addEffect(new DamageMultiEffect(3).setText("{this} deals 3 damage divided as you choose among one, two, or three target attacking or blocking creatures.")); this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3, filter)); } diff --git a/Mage.Sets/src/mage/cards/g/GilderBairn.java b/Mage.Sets/src/mage/cards/g/GilderBairn.java index 0fadbc07bb..1ce8089546 100644 --- a/Mage.Sets/src/mage/cards/g/GilderBairn.java +++ b/Mage.Sets/src/mage/cards/g/GilderBairn.java @@ -52,7 +52,7 @@ import mage.target.TargetPermanent; public class GilderBairn extends CardImpl { public GilderBairn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}{G/U}"); this.subtype.add(SubType.OUPHE); this.power = new MageInt(1); @@ -80,7 +80,7 @@ class GilderBairnEffect extends OneShotEffect { public GilderBairnEffect() { super(Outcome.Benefit); - this.staticText = "For each counter on target permanent, put another of those counters on that permanent"; + this.staticText = "Double the number of each kind of counter on target permanent"; } public GilderBairnEffect(final GilderBairnEffect effect) { diff --git a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java index 82f91c5ec9..669c69b48f 100644 --- a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java +++ b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java @@ -70,7 +70,9 @@ public class GleamOfAuthority extends CardImpl { // Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control DynamicValue amount = new CountersOnControlledCount(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield) + .setText("Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control.") + )); // Enchanted creature has vigilance and "{W}, {T}: Bloster 1." ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); diff --git a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java index 0e273c06e0..2106d125af 100644 --- a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java +++ b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java @@ -64,10 +64,10 @@ public class GreenManaBattery extends CardImpl { Mana.GreenMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {G} to your mana pool, then add {G} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {G} to your mana pool, then add {G} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java index 5a5501bfb6..c4fe64e45a 100644 --- a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java +++ b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java @@ -50,7 +50,7 @@ import mage.counters.CounterType; */ public class HelixPinnacle extends CardImpl { - static final String rule = "if there are 100 or more tower counters on Helix Pinnacle, you win the game"; + static final String rule = "at the beginning of your upkeep, if there are 100 or more tower counters on Helix Pinnacle, you win the game"; public HelixPinnacle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); diff --git a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java index 089a13e108..87554db349 100644 --- a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java +++ b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java @@ -54,14 +54,14 @@ public class MerrowBonegnawer extends CardImpl { private UUID exileId = UUID.randomUUID(); - private static final FilterSpell filter = new FilterSpell("black spell"); + private static final FilterSpell filter = new FilterSpell("a black spell"); static { filter.add(new ColorPredicate(ObjectColor.BLACK)); } public MerrowBonegnawer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.ROGUE); diff --git a/Mage.Sets/src/mage/cards/m/Moonhold.java b/Mage.Sets/src/mage/cards/m/Moonhold.java index 9c559325df..1c10f6a44a 100644 --- a/Mage.Sets/src/mage/cards/m/Moonhold.java +++ b/Mage.Sets/src/mage/cards/m/Moonhold.java @@ -55,13 +55,13 @@ import mage.watchers.common.ManaSpentToCastWatcher; public class Moonhold extends CardImpl { public Moonhold(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R/W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R/W}"); // Target player can't play land cards this turn if {R} was spent to cast Moonhold and can't play creature cards this turn if {W} was spent to cast it. ContinuousRuleModifyingEffect effect = new MoonholdEffect(); ContinuousRuleModifyingEffect effect2 = new MoonholdEffect2(); - effect.setText("Target player can't play land cards this turn if {R} was spent to cast {this} "); - effect2.setText("and can't play creature cards this turn if {W} was spent to cast it."); + effect.setText("Target player can't play lands this turn if {R} was spent to cast {this}"); + effect2.setText("and can't cast creature spells this turn if {W} was spent to cast it."); this.getSpellAbility().addEffect(new ConditionalContinuousRuleModifyingEffect( effect, new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.R)))); @@ -69,7 +69,7 @@ public class Moonhold extends CardImpl { effect2, new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.W)))); this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new InfoEffect("(Do both if {R}{W} was spent.)")); + this.getSpellAbility().addEffect(new InfoEffect(" (Do both if {R}{W} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/cards/n/NightskyMimic.java b/Mage.Sets/src/mage/cards/n/NightskyMimic.java index a0e1832e99..268d86b9ae 100644 --- a/Mage.Sets/src/mage/cards/n/NightskyMimic.java +++ b/Mage.Sets/src/mage/cards/n/NightskyMimic.java @@ -58,10 +58,10 @@ public class NightskyMimic extends CardImpl { filter.add(new ColorPredicate(ObjectColor.BLACK)); } - private String rule = "Whenever you cast a spell that's both white and black, {this} has base power and toughness 4/4 until end of turn and gains flying until end of turn"; + private String rule = "Whenever you cast a spell that's both white and black, {this} has base power and toughness 4/4 until end of turn and gains flying until end of turn."; public NightskyMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W/B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/B}"); this.subtype.add(SubType.SHAPESHIFTER); this.color.setBlack(true); diff --git a/Mage.Sets/src/mage/cards/p/PunctureBlast.java b/Mage.Sets/src/mage/cards/p/PunctureBlast.java index 3e6bfc161d..715e672a61 100644 --- a/Mage.Sets/src/mage/cards/p/PunctureBlast.java +++ b/Mage.Sets/src/mage/cards/p/PunctureBlast.java @@ -41,11 +41,12 @@ import mage.target.common.TargetCreatureOrPlayer; public class PunctureBlast extends CardImpl { public PunctureBlast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); this.addAbility(WitherAbility.getInstance()); this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + this.getSpellAbility().setRuleAtTheTop(false); } public PunctureBlast(final PunctureBlast card) { diff --git a/Mage.Sets/src/mage/cards/r/RedManaBattery.java b/Mage.Sets/src/mage/cards/r/RedManaBattery.java index 224f287c21..e661c11359 100644 --- a/Mage.Sets/src/mage/cards/r/RedManaBattery.java +++ b/Mage.Sets/src/mage/cards/r/RedManaBattery.java @@ -64,10 +64,10 @@ public class RedManaBattery extends CardImpl { Mana.RedMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {R} to your mana pool, then add {R} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {R} to your mana pool, then add {R} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RekindledFlame.java b/Mage.Sets/src/mage/cards/r/RekindledFlame.java index a9896973ca..c8fde66460 100644 --- a/Mage.Sets/src/mage/cards/r/RekindledFlame.java +++ b/Mage.Sets/src/mage/cards/r/RekindledFlame.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; import mage.cards.CardImpl; @@ -48,22 +48,25 @@ import mage.target.common.TargetCreatureOrPlayer; * @author jeffwadsworth */ public class RekindledFlame extends CardImpl { - + static final String rule = "if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand"; public RekindledFlame(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}"); // Rekindled Flame deals 4 damage to target creature or player. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); - + // At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand. - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new ConditionalOneShotEffect(new ReturnSourceFromGraveyardToHandEffect(), new OpponentHasNoCardsInHandCondition(), rule), TargetController.YOU, true); + Ability ability = new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), TargetController.YOU, true + ), + new OpponentHasNoCardsInHandCondition(), rule); ability.setRuleVisible(true); this.addAbility(ability); - + } public RekindledFlame(final RekindledFlame card) { @@ -91,4 +94,4 @@ class OpponentHasNoCardsInHandCondition implements Condition { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java index c1d7edba64..59a9c5f17b 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java +++ b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java @@ -51,11 +51,11 @@ import mage.players.Player; public class ScaleBlessing extends CardImpl { public ScaleBlessing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}"); // Bolster 1, then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. Effect effect = new BolsterEffect(1); - effect.setText("Bolster 1"); + effect.setText("Bolster 1"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new ScaleBlessingEffect()); @@ -98,7 +98,7 @@ class ScaleBlessingEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { - for(Permanent permanent: game.getState().getBattlefield().getAllActivePermanents(filter , controller.getId(), game)) { + for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { permanent.addCounters(CounterType.P1P1.createInstance(), source, game); game.informPlayers(sourceObject.getName() + ": Put a +1/+1 counter on " + permanent.getLogName()); } diff --git a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java index 23e4341c3a..ac72bc7161 100644 --- a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java +++ b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java @@ -58,10 +58,10 @@ public class ShorecrasherMimic extends CardImpl { filter.add(new ColorPredicate(ObjectColor.BLUE)); } - private String rule = "Whenever you cast a spell that's both green and blue, {this} has base power and toughness 5/3 until end of turn and gains trample until end of turn"; + private String rule = "Whenever you cast a spell that's both green and blue, {this} has base power and toughness 5/3 until end of turn and gains trample until end of turn."; public ShorecrasherMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}"); this.subtype.add(SubType.SHAPESHIFTER); this.color.setBlue(true); diff --git a/Mage.Sets/src/mage/cards/t/TalarasBane.java b/Mage.Sets/src/mage/cards/t/TalarasBane.java index c89e8fb6a8..9715eeb33f 100644 --- a/Mage.Sets/src/mage/cards/t/TalarasBane.java +++ b/Mage.Sets/src/mage/cards/t/TalarasBane.java @@ -53,13 +53,12 @@ import mage.target.common.TargetOpponent; public class TalarasBane extends CardImpl { public TalarasBane(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal that creature card's toughness, then that player discards that card. this.getSpellAbility().addEffect(new TalarasBaneEffect()); this.getSpellAbility().addTarget(new TargetOpponent()); - + } public TalarasBane(final TalarasBane card) { @@ -73,9 +72,9 @@ public class TalarasBane extends CardImpl { } class TalarasBaneEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("a green or white creature card"); - + static { filter.add(Predicates.or( new ColorPredicate(ObjectColor.GREEN), @@ -85,7 +84,7 @@ class TalarasBaneEffect extends OneShotEffect { public TalarasBaneEffect() { super(Outcome.Detriment); - this.staticText = "Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal that creature card's toughness, then that player discards that card"; + this.staticText = "Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal to that creature card's toughness, then that player discards that card"; } public TalarasBaneEffect(final TalarasBaneEffect effect) { @@ -110,10 +109,10 @@ class TalarasBaneEffect extends OneShotEffect { } if (card != null) { int lifeGain = card.getToughness().getValue(); - you .gainLife(lifeGain, game); + you.gainLife(lifeGain, game); return targetPlayer.discard(card, source, game); } } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java index 9c6251028c..220e916e01 100644 --- a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java +++ b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java @@ -45,32 +45,31 @@ import mage.watchers.common.ManaSpentToCastWatcher; /** * * @author jeffwadsworth - + * */ public class UnnervingAssault extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control"); private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures you control"); - + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); filter2.add(new ControllerPredicate(TargetController.YOU)); } public UnnervingAssault(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U/R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U/R}"); // Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast Unnerving Assault, and creatures you control get +1/+0 until end of turn if {R} was spent to cast it. this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new BoostAllEffect(-1, 0, Duration.EndOfTurn, filter, false), - new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/0 until end of turn if {U} was spent to cast {this},")); + new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast {this},")); this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new BoostAllEffect(1, 0, Duration.EndOfTurn, filter2, false), - new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/0 until end of turn if {R} was spent to cast it")); + new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/+0 until end of turn if {R} was spent to cast it")); this.getSpellAbility().addEffect(new InfoEffect("(Do both if {U}{R} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); - + } public UnnervingAssault(final UnnervingAssault card) { @@ -82,4 +81,3 @@ public class UnnervingAssault extends CardImpl { return new UnnervingAssault(this); } } - diff --git a/Mage.Sets/src/mage/cards/w/WakeThrasher.java b/Mage.Sets/src/mage/cards/w/WakeThrasher.java index 077a90acaa..b9f7be99fe 100644 --- a/Mage.Sets/src/mage/cards/w/WakeThrasher.java +++ b/Mage.Sets/src/mage/cards/w/WakeThrasher.java @@ -49,7 +49,7 @@ import mage.game.events.GameEvent.EventType; public class WakeThrasher extends CardImpl { public WakeThrasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.SOLDIER); @@ -57,7 +57,7 @@ public class WakeThrasher extends CardImpl { this.toughness = new MageInt(1); // Whenever a permanent you control becomes untapped, Wake Thrasher gets +1/+1 until end of turn. - this.addAbility(new BecomesUntappedControlledPermanentTriggeredAbility(new BoostSourceEffect(1,1, Duration.EndOfTurn), false)); + this.addAbility(new BecomesUntappedControlledPermanentTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false)); } @@ -71,7 +71,7 @@ public class WakeThrasher extends CardImpl { } } -class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilityImpl{ +class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilityImpl { public BecomesUntappedControlledPermanentTriggeredAbility(Effect effect, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); @@ -98,7 +98,7 @@ class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilit @Override public String getRule() { - return "When a permanent you control becomes untapped, " + super.getRule(); + return "Whenever a permanent you control becomes untapped, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/w/WardOfBones.java b/Mage.Sets/src/mage/cards/w/WardOfBones.java index 85058af51f..ca33b2b267 100644 --- a/Mage.Sets/src/mage/cards/w/WardOfBones.java +++ b/Mage.Sets/src/mage/cards/w/WardOfBones.java @@ -76,7 +76,9 @@ class WardOfBonesEffect extends ContinuousRuleModifyingEffectImpl { public WardOfBonesEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Each opponent who controls more creatures than you can't play creature cards. The same is true for artifacts, enchantments, and lands"; + staticText = "Each opponent who controls more creatures than you can't cast creature spells. " + + "The same is true for artifacts and enchantments.

" + + "Each opponent who controls more lands than you can't play lands."; } public WardOfBonesEffect(final WardOfBonesEffect effect) { diff --git a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java index 9e78d925f2..d2304d34b9 100644 --- a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java +++ b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java @@ -64,10 +64,10 @@ public class WhiteManaBattery extends CardImpl { Mana.WhiteMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {W} to your mana pool, then add {W} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {W} to your mana pool, then add {W} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java index 5d6ec647d1..387bc7127e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java @@ -88,7 +88,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild", "Marath, Will of the Wild", StackClause.WHILE_NOT_ON_STACK); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Archangel of Thune"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, Remove X +1/+1 counters from Marath", "Archangel of Thune"); setChoice(playerA, "X=3"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player @@ -132,7 +132,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Elesh Norn, Grand Cenobite"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, Remove X +1/+1 counters from Marath", "Elesh Norn, Grand Cenobite"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player setChoice(playerA, "X=1"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java index 4d9ad42869..058c8787f8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java @@ -273,7 +273,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); setStopAt(2, PhaseStep.BEGIN_COMBAT); @@ -309,7 +309,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{5}{G}: Turn"); @@ -353,7 +353,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); setStopAt(2, PhaseStep.END_TURN); @@ -431,7 +431,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); setChoice(playerB, "Silvercoat Lion"); activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice a creature"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java index b57d4b3c5a..9f25fe66a1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java @@ -82,7 +82,7 @@ public class SuspendTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Jhoira of the Ghitu", 1); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend"); setChoice(playerA, "Silvercoat Lion"); setStopAt(11, PhaseStep.PRECOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java index 23cf48dd18..9d950e8a0f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java @@ -53,7 +53,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tawnos's Coffin"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}", "Silvercoat Lion"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -83,7 +83,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tawnos's Coffin"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Battlegrowth", "Silvercoat Lion"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}", "Silvercoat Lion"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}", "Silvercoat Lion"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -123,7 +123,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Battlegrowth", "Bramble Elemental"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blanchwood Armor", "Bramble Elemental"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frog Tongue", "Bramble Elemental"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}", "Bramble Elemental"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}", "Bramble Elemental"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java index 2ca85699eb..f1e1a6900f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java @@ -59,7 +59,7 @@ public class TradingPostTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Act of Treason", "Savannah Lions"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},{T}, Sacrifice a creature", "Helm of Possession", "Act of Treason", StackClause.WHILE_NOT_ON_STACK); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, {T}, Sacrifice a creature", "Helm of Possession", "Act of Treason", StackClause.WHILE_NOT_ON_STACK); setChoice(playerA, "Savannah Lions"); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java index 32387a9896..d180cdadf6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java @@ -185,7 +185,7 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { // {3}, {T}: Rod of Ruin deals 1 damage to target creature or player. addCard(Zone.BATTLEFIELD, playerA, "Rod of Ruin", 1); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java index b5acc76e54..e5ce6a0800 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java @@ -82,7 +82,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Island", 4); addCard(Zone.BATTLEFIELD, playerB, "Food Chain"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2},Sacrifice a permanent you control: Return target creature to its owner's hand."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand."); playerB.addChoice("Food Chain"); playerA.addTarget("Angel of Jubilation"); @@ -100,7 +100,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk"); addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves", 2); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2},Sacrifice a permanent you control: Return target creature to its owner's hand."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand."); playerB.addChoice("Nantuko Husk"); playerA.addTarget("Angel of Jubilation"); @@ -151,7 +151,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tomb of Urami"); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}, Sacrifice all lands you control: Create a legendary 5/5 black Demon Spirit creature token with flying named Urami."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}, Sacrifice all lands you control: Create a legendary 5/5 black Demon Spirit creature token with flying named Urami."); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java index 1e19212192..ceed83b997 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java @@ -69,7 +69,7 @@ public class SerraAscendantTest extends CardTestPlayerBase { playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains"); castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Martyr of Sands"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},You may reveal X white cards from your hand"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, You may reveal X white cards from your hand"); setChoice(playerA,"X=3"); attack(3, playerA, "Serra Ascendant"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java index 9eba9d61cb..038f5665e8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java @@ -214,7 +214,7 @@ public class ExchangeControlTest extends CardTestPlayerBase { addTarget(playerA, "Manta Riders"); // now use the activated ability to make the "Silvercoat Lions" (that became Mana Riders) flying - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}: {this} gains Flying until end of turn."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}: {this} gains flying until end of turn."); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java index f6cf2fd3f1..2246c955a1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java @@ -100,7 +100,7 @@ public class GainControlDiedCastAgainTest extends CardTestPlayerBase { castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerB, "Akroma's Vengeance"); // Put Elesh Norn back on library - activateAbility(5, PhaseStep.END_TURN, playerB, "{1}{B},{T}: Put target creature card", "Elesh Norn, Grand Cenobite"); + activateAbility(5, PhaseStep.END_TURN, playerB, "{1}{B}, {T}: Put target creature card", "Elesh Norn, Grand Cenobite"); castSpell(6, PhaseStep.PRECOMBAT_MAIN, playerB, "Elesh Norn, Grand Cenobite"); setStopAt(6, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java index 075d4f1ac0..3a169d8f9d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java @@ -60,10 +60,10 @@ public class GainControlTargetEffectTest extends CardTestPlayerBase { // Persist (When this creature dies, if it had no -1/-1 counters on it, return it to the battlefield under its owner's control with a -1/-1 counter on it.) addCard(Zone.BATTLEFIELD, playerB, "Glen Elendra Archmage"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as {this} remains tapped.", "Glen Elendra Archmage"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as {this} remains tapped.", "Glen Elendra Archmage"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Strike", playerA); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U},Sacrifice {this}: Counter target noncreature spell.", "Lightning Strike"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}, Sacrifice {this}: Counter target noncreature spell.", "Lightning Strike"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -94,7 +94,7 @@ public class GainControlTargetEffectTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Mutavault", 1); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}: Until end of turn {this} becomes"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}: Gain control", "Mutavault"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}: Gain control", "Mutavault"); setChoice(playerA, "No"); // Don't untap the Shackles setStopAt(3, PhaseStep.PRECOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java index 103c8848bb..893bd4fd0d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java @@ -60,7 +60,7 @@ public class WillbreakerTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B},Remove", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Remove", "Silvercoat Lion"); setChoice(playerA, "X=0"); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java index d157967cb5..29f0bf95f4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java @@ -58,7 +58,7 @@ public class FeldonOfTheThirdPathTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, - "{2}{R},{T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", + "{2}{R}, {T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", "Highway Robber"); setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); execute(); @@ -82,7 +82,7 @@ public class FeldonOfTheThirdPathTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, - "{2}{R},{T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", + "{2}{R}, {T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", "Sepulchral Primordial"); addTarget(playerA, "Silvercoat Lion"); // target for ETB Sepulchral Primordial setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java index 2036f56dc2..8369719040 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java @@ -71,7 +71,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Lightning Bolt"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}:"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); @@ -93,7 +93,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Lightning Bolt"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}:"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "No"); @@ -136,7 +136,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { attack(2, playerB, "Dross Crocodile"); attack(2, playerB, "Dross Crocodile"); - activateAbility(2, PhaseStep.DECLARE_BLOCKERS, playerA, "{2},{T}:"); + activateAbility(2, PhaseStep.DECLARE_BLOCKERS, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); @@ -180,7 +180,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Silence"); - activateAbility(2, PhaseStep.UPKEEP, playerA, "{2},{T}:"); + activateAbility(2, PhaseStep.UPKEEP, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java index 9004e3a81a..b708a3d6c9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java @@ -63,10 +63,10 @@ public class MimicVatTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clone"); setChoice(playerA, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice a creature"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature"); setChoice(playerA, "Yes"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}: Create a token"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}: Create a token"); setChoice(playerA, "Silvercoat Lion"); setStopAt(3, PhaseStep.BEGIN_COMBAT); @@ -95,10 +95,10 @@ public class MimicVatTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph"); setChoice(playerA, "Yes"); setChoice(playerA, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice a creature"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature"); setChoice(playerA, "Yes"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}: Create a token that's a copy of a card exiled with "); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}: Create a token that's a copy of a card exiled with "); setChoice(playerA, "Yes"); setChoice(playerA, "Silvercoat Lion"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java index 96f73b57b8..d2650054c7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java @@ -48,7 +48,7 @@ public class RemoveCounterCostTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Novijen Sages"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},Remove two +1/+1 counters"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, Remove two +1/+1 counters"); setChoice(playerA, "X=2"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java index 9310dcbf95..f33ff1c4fb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java @@ -54,7 +54,7 @@ public class HeartstoneTest extends CardTestPlayerBase { addCard(Zone.HAND, playerB, "Lightning Bolt"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U},Tap two untapped Wizards you control: Copy target instant or sorcery spell. You may choose new targets for the copy.", "Lightning Bolt"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U}, Tap two untapped Wizards you control: Copy target instant or sorcery spell. You may choose new targets for the copy.", "Lightning Bolt"); setChoice(playerA, "Yes"); addTarget(playerA, playerB); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java index 2d00ce3f91..71ea880114 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java @@ -69,7 +69,7 @@ public class SkullclampTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Silvercoat Lion"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X},Sacrifice"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X}, Sacrifice"); setChoice(playerB, "X=2"); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java index 4c68018520..104cebecbf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java @@ -128,7 +128,7 @@ public class ConditionalManaTest extends CardTestPlayerBase { activateManaAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: Add {C}{C}{C}{C}"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X},{T}: Untap"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X}, {T}: Untap"); setChoice(playerB, "X=4"); addTarget(playerB, "Island"); addTarget(playerB, "Island"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java index b178bc6472..54f9684f2e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java @@ -84,7 +84,7 @@ public class CryptGhastTest extends CardTestPlayerBase { // {X}{U}{R},{T}: Nin, the Pain Artist deals X damage to target creature. That creature's controller draws X cards. addCard(Zone.BATTLEFIELD, playerB, "Nin, the Pain Artist", 1); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{X}{U}{R},{T}: {this} deals X damage to target creature", "Crypt Ghast"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{X}{U}{R}, {T}: {this} deals X damage to target creature", "Crypt Ghast"); setChoice(playerB, "X=2"); // Crypt Ghast may no longer give additional mana diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java index 19b042b09d..e5d467026c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java @@ -1,12 +1,10 @@ package org.mage.test.cards.mana; -import mage.abilities.costs.mana.ColorlessManaCost; import mage.constants.ManaType; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; -import org.mage.test.serverside.base.impl.CardTestAPIImpl; public class DoublingCubeTest extends CardTestPlayerBase { @@ -26,18 +24,16 @@ public class DoublingCubeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, cube); addCard(Zone.BATTLEFIELD, playerA, upwelling); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}{C}"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}:"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}:"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); assertManaPool(playerA, ManaType.COLORLESS, 4); - } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java index 48ce51cda9..f03c021f1c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java @@ -52,8 +52,8 @@ public class HarvesterDruidTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 2 red and 1 blue mana", "{R}{R}{U}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{R}{U}{U}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 2 red and 1 blue mana", "{U}{R}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{R}", options.get(1).toString()); } @Test @@ -68,9 +68,9 @@ public class HarvesterDruidTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 3 red and 1 blue mana", "{R}{R}{R}{U}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{R}{R}{U}{U}", options.get(1).toString()); - Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{R}{R}{U}{U}", options.get(2).toString()); - Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{R}{U}{U}{U}", options.get(3).toString()); + Assert.assertEquals("Player should be able to create 3 red and 1 blue mana", "{U}{R}{R}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(2).toString()); + Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{U}{R}", options.get(3).toString()); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java index 2c7a35b08c..29df140553 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java @@ -52,7 +52,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool. addCard(Zone.BATTLEFIELD, playerA, "Omnath, Locus of Mana", 1); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); @@ -75,12 +75,12 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool. addCard(Zone.BATTLEFIELD, playerA, "Omnath, Locus of Mana", 1); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); @@ -106,12 +106,12 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // If unused mana would empty from your mana pool, that mana becomes colorless instead. addCard(Zone.BATTLEFIELD, playerA, "Kruphix, God of Horizons", 1); // 1 G devotion - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -143,7 +143,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cackling Counterpart"); addTarget(playerA, "Simic Guildmage"); - activateManaAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -205,7 +205,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2); // two colorless to pay for nykthos addCard(Zone.HAND, playerA, pObliterator); // just for something to cast for 4 black mana - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Black"); // should produce 4 black mana castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pObliterator); // costs exactly 4 black mana should be castable diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java index 862b036a30..8479228d8b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java @@ -174,13 +174,13 @@ public class ReflectingPoolTest extends CardTestPlayerBase { ManaOptions options = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("Player A should be able to create the ", "{G}{G}{G}", options.get(0).toString()); - Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(1).toString()); - Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet - Assert.assertEquals("Player A should be able to create the ", "{G}{W}{W}", options.get(3).toString()); + Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(1).toString()); + Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet + Assert.assertEquals("Player A should be able to create the ", "{W}{W}{G}", options.get(3).toString()); Assert.assertEquals("Player A should be able to create only 3 different mana options", 4, options.size()); options = playerB.getAvailableManaTest(currentGame); - Assert.assertEquals("Player B should be able to create the ", "{G}{W}", options.get(0).toString()); + Assert.assertEquals("Player B should be able to create the ", "{W}{G}", options.get(0).toString()); Assert.assertEquals("Player B should be able to create the ", "{W}{W}", options.get(1).toString()); Assert.assertEquals("Player B should be able to create only 3 different mana options", 2, options.size()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java index be7cc9427c..3c6fce6f11 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java @@ -70,8 +70,8 @@ public class SylvokExplorerTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{R}{W}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{U}{W}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{W}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{W}{U}", options.get(1).toString()); } @Test diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java index eea4e061a7..56e6ce1d86 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java @@ -37,12 +37,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - public class GrindstoneTest extends CardTestPlayerBase { /** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Leaving one Progenius in play + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Leaving one Progenius in play */ @Test public void testGrindstoneProgenius() { @@ -61,19 +60,19 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - - Assert.assertEquals("Progenitus has to be in the libarary", 1, playerB.getLibrary().size()); + + Assert.assertEquals("Progenitus has to be in the libarary", 1, playerB.getLibrary().size()); assertPermanentCount(playerA, "Painter's Servant", 1); } - + /** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Iterating with two Progenius for a draw + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Iterating with two Progenius for a draw */ @Test public void testGrindstoneProgeniusDraw() { @@ -92,19 +91,19 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - + Assert.assertTrue("Has to be a draw because of endless iteration", currentGame.isADraw()); assertPermanentCount(playerA, "Painter's Servant", 1); } - -/** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Iterating with two Progenius for a draw + + /** + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Iterating with two Progenius for a draw */ @Test public void testGrindstoneUlamog() { @@ -125,16 +124,14 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - + // No cards in graveyard because Ulamog shuffle all cards back to Lib assertGraveyardCount(playerB, 0); assertPermanentCount(playerA, "Painter's Servant", 1); - } + } } - - diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java index 9ef378862f..52168da7c8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java @@ -59,7 +59,7 @@ public class LeylineOfTheVoidTest extends CardTestPlayerBase { // {X}, {T}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0. addCard(Zone.BATTLEFIELD, playerA, "Helm of Obedience"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},{T}: Target opponent puts cards", playerB); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, {T}: Target opponent puts cards", playerB); setChoice(playerA, "X=1"); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java index d9c413363f..6680c84977 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java @@ -332,7 +332,7 @@ public class ZoneChangeReplacementTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}: Return target creature", "Silvercoat Lion"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}: Return target creature", "Silvercoat Lion"); castSpell(2, PhaseStep.BEGIN_COMBAT, playerA, "Terror", "Silvercoat Lion"); setStopAt(2, PhaseStep.END_COMBAT); @@ -364,7 +364,7 @@ public class ZoneChangeReplacementTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerB, "Swamp", 5); addCard(Zone.GRAVEYARD, playerB, "Jace, Vryn's Prodigy"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}: Return target creature", "Jace, Vryn's Prodigy"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}: Return target creature", "Jace, Vryn's Prodigy"); // {T}: Draw a card, then discard a card. If there are five or more cards in your graveyard, exile Jace, Vryn's Prodigy, then return him to the battefield transformed under his owner's control. activateAbility(2, PhaseStep.BEGIN_COMBAT, playerB, "{T}: Draw a card, then discard a card. If there are five or more cards in your graveyard"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java index ff91ebf653..2b24a74680 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java @@ -85,7 +85,7 @@ public class ContagionEngineTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Contagion Engine"); addTarget(playerA, playerB); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4},{T}: Proliferate"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}, {T}: Proliferate"); setChoice(playerA, "Wall of Frost^Kalonian Behemoth^Plated Slagwurm^Teysa, Envoy of Ghosts^Ajani Goldmane"); setChoice(playerA, "Wall of Frost^Kalonian Behemoth^Plated Slagwurm^Teysa, Envoy of Ghosts^Ajani Goldmane"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java index bc6de56293..9f931fbd17 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java @@ -17,7 +17,7 @@ public class MagewrightStoneTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, meanderer, 1, true); addCard(Zone.BATTLEFIELD, playerA, magewrightStone); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},{T}: Untap target creature", meanderer); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, {T}: Untap target creature", meanderer); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java index 09a5327a48..59aae8be99 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java @@ -53,7 +53,7 @@ public class SoulFoundryTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Foundry"); setChoice(playerA, "Yes"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},{T}: Create a token"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, {T}: Create a token"); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java index 0484faccaa..8069e2d2e1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java @@ -12,7 +12,7 @@ public class GrinningTotemTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); addCard(Zone.BATTLEFIELD, playerA, "Grinning Totem"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); setStopAt(3, PhaseStep.BEGIN_COMBAT); execute(); @@ -28,7 +28,7 @@ public class GrinningTotemTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tormod's Crypt"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}, Sacrifice {this}: Exile all cards", playerA); setStopAt(3, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java index 7f90d651e3..6cf97093b4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java @@ -52,7 +52,7 @@ public class BecomesTheTargetTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P},{T}: Tap target creature", "Silvercoat Lion"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P}, {T}: Tap target creature", "Silvercoat Lion"); setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java index d342098352..28ca2c83e0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java @@ -97,7 +97,7 @@ public class SpellskiteTest extends CardTestPlayerBase { // Whenever Frost Titan enters the battlefield or attacks, tap target permanent. It doesn't untap during its controller's next untap step. addCard(Zone.HAND, playerB, "Frost Titan", 1); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Gain control", "Spellskite"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Gain control", "Spellskite"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frost Titan"); addTarget(playerB, "Silvercoat Lion"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java index 160f68428f..01a5e9eb1b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java @@ -29,7 +29,7 @@ public class FellShepherdTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Fell Shepherd"); playerA.addChoice("Craw Wurm"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{B},Sacrifice another creature: Target creature gets -2/-2 until end of turn.", "Raging Goblin"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Sacrifice another creature: Target creature gets -2/-2 until end of turn.", "Raging Goblin"); attack(3, playerA, "Fell Shepherd"); setStopAt(3, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java index 0bcc381376..1569a8ec8d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java @@ -172,7 +172,7 @@ public class BloodchiefAscensionTest extends CardTestMultiPlayerBase { addCard(Zone.HAND, playerB, "Bellows Lizard", 5); // Player order: A -> D -> C -> B - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerD, "{U},{T}: Each player discards"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerD, "{U}, {T}: Each player discards"); setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java index 08c6b54f2f..6c11c32730 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java @@ -17,7 +17,7 @@ public class ProtectionFromTypeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tel-Jilad Fallen"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a charge counter from {this}, {T}: put a -1/-1 counter on target creature.", "Tel-Jilad Fallen"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Remove a charge counter from {this}, {T}: put a -1/-1 counter on target creature.", "Tel-Jilad Fallen"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -32,7 +32,7 @@ public class ProtectionFromTypeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Coral Merfolk"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a charge counter from {this}, {T}: Put a -1/-1 counter on target creature.", "Coral Merfolk"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Remove a charge counter from {this}, {T}: Put a -1/-1 counter on target creature.", "Coral Merfolk"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java index 0f45a8e717..91ea81bf86 100644 --- a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java @@ -72,9 +72,9 @@ public class ManaOptionsTest extends CardTestPlayerBase { Assert.assertEquals("mana variations don't fit", 4, manaOptions.size()); Assert.assertEquals("{G}{G}{G}", getManaOption(0, manaOptions)); - Assert.assertEquals("{R}{G}{G}{W}", getManaOption(1, manaOptions)); - Assert.assertEquals("{R}{R}{G}{W}{W}", getManaOption(2, manaOptions)); - Assert.assertEquals("{R}{R}{R}{W}{W}{W}", getManaOption(3, manaOptions)); + Assert.assertEquals("{W}{R}{G}{G}", getManaOption(1, manaOptions)); + Assert.assertEquals("{W}{W}{R}{R}{G}", getManaOption(2, manaOptions)); + Assert.assertEquals("{W}{W}{W}{R}{R}{R}", getManaOption(3, manaOptions)); } @@ -95,11 +95,11 @@ public class ManaOptionsTest extends CardTestPlayerBase { Assert.assertEquals("{C}{C}{W}", getManaOption(1, manaOptions)); Assert.assertEquals("{C}{C}{U}", getManaOption(2, manaOptions)); Assert.assertEquals("{C}{W}{W}", getManaOption(3, manaOptions)); - Assert.assertEquals("{C}{U}{W}", getManaOption(4, manaOptions)); + Assert.assertEquals("{C}{W}{U}", getManaOption(4, manaOptions)); Assert.assertEquals("{C}{U}{U}", getManaOption(5, manaOptions)); Assert.assertEquals("{W}{W}{W}", getManaOption(6, manaOptions)); - Assert.assertEquals("{U}{W}{W}", getManaOption(7, manaOptions)); - Assert.assertEquals("{U}{U}{W}", getManaOption(8, manaOptions)); + Assert.assertEquals("{W}{W}{U}", getManaOption(7, manaOptions)); + Assert.assertEquals("{W}{U}{U}", getManaOption(8, manaOptions)); Assert.assertEquals("{U}{U}{U}", getManaOption(9, manaOptions)); } @@ -151,7 +151,7 @@ public class ManaOptionsTest extends CardTestPlayerBase { ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); - Assert.assertEquals("{C}{G}{G}{W}{W}", getManaOption(0, manaOptions)); + Assert.assertEquals("{C}{W}{W}{G}{G}", getManaOption(0, manaOptions)); } // Crystal Quarry @@ -169,8 +169,8 @@ public class ManaOptionsTest extends CardTestPlayerBase { ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("mana variations don't fit", 2, manaOptions.size()); - Assert.assertEquals("{C}{G}{G}{G}{W}{W}", getManaOption(0, manaOptions)); - Assert.assertEquals("{R}{G}{U}{W}{B}", getManaOption(1, manaOptions)); + Assert.assertEquals("{C}{W}{W}{G}{G}{G}", getManaOption(0, manaOptions)); + Assert.assertEquals("{W}{U}{B}{R}{G}", getManaOption(1, manaOptions)); } // Nykthos, Shrine to Nyx diff --git a/Mage/src/main/java/mage/abilities/Abilities.java b/Mage/src/main/java/mage/abilities/Abilities.java index 2e4c629a2c..d0425f6fd7 100644 --- a/Mage/src/main/java/mage/abilities/Abilities.java +++ b/Mage/src/main/java/mage/abilities/Abilities.java @@ -61,6 +61,8 @@ public interface Abilities extends List, Serializable { */ List getRules(String source); + List getRules(String source, boolean capitalize); + /** * Retrieves all activated abilities for the given {@link Zone}. * diff --git a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java index 7a1dfba19d..a7a10a3236 100644 --- a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java @@ -69,6 +69,11 @@ public class AbilitiesImpl extends ArrayList implements Ab @Override public List getRules(String source) { + return getRules(source, true); + } + + @Override + public List getRules(String source, boolean capitalize) { List rules = new ArrayList<>(); for (T ability : this) { @@ -78,7 +83,9 @@ public class AbilitiesImpl extends ArrayList implements Ab if (!(ability instanceof SpellAbility || ability instanceof PlayLandAbility)) { String rule = ability.getRule(); if (rule != null && rule.length() > 3) { - rule = Character.toUpperCase(rule.charAt(0)) + rule.substring(1); + if (capitalize) { + rule = Character.toUpperCase(rule.charAt(0)) + rule.substring(1); + } if (ability.getRuleAtTheTop()) { rules.add(0, rule); } else { diff --git a/Mage/src/main/java/mage/abilities/CompoundAbility.java b/Mage/src/main/java/mage/abilities/CompoundAbility.java index d122735f84..e07d934980 100644 --- a/Mage/src/main/java/mage/abilities/CompoundAbility.java +++ b/Mage/src/main/java/mage/abilities/CompoundAbility.java @@ -31,7 +31,7 @@ public class CompoundAbility extends AbilitiesImpl { } StringBuilder sb = new StringBuilder(); - List rules = super.getRules(null); + List rules = super.getRules(null,false); for (int index = 0; index < rules.size(); index++) { if (index > 0) { if (index < rules.size() - 1) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java index 6f58c745bd..9eca132786 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.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.abilities.costs.common; import mage.constants.Outcome; @@ -38,6 +37,7 @@ import mage.target.common.TargetControlledPermanent; import java.util.List; import java.util.UUID; import mage.abilities.costs.Cost; +import mage.util.CardUtil; /** * @@ -49,7 +49,7 @@ public class UntapTargetCost extends CostImpl { public UntapTargetCost(TargetControlledPermanent target) { this.target = target; - this.text = "Untap " + target.getMaxNumberOfTargets() + ' ' + target.getTargetName(); + this.text = "Untap " + CardUtil.numberToText(target.getMaxNumberOfTargets(), "") + ' ' + target.getTargetName(); } public UntapTargetCost(final UntapTargetCost cost) { @@ -60,10 +60,11 @@ public class UntapTargetCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { if (target.choose(Outcome.Untap, controllerId, sourceId, game)) { - for (UUID targetId: (List)target.getTargets()) { + for (UUID targetId : (List) target.getTargets()) { Permanent permanent = game.getPermanent(targetId); - if (permanent == null) + if (permanent == null) { return false; + } paid |= permanent.untap(game); } } @@ -80,5 +81,4 @@ public class UntapTargetCost extends CostImpl { return new UntapTargetCost(this); } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java index 79bd6484f2..7ceebd0111 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java @@ -46,7 +46,7 @@ public class GetEmblemEffect extends OneShotEffect { public GetEmblemEffect(Emblem emblem) { super(Outcome.Benefit); this.emblem = emblem; - this.staticText = "You get an emblem with \"" + +'"'; + this.staticText = getText(); } public GetEmblemEffect(final GetEmblemEffect effect) { @@ -74,7 +74,9 @@ public class GetEmblemEffect extends OneShotEffect { sb.append("You get an emblem with \""); List rules = emblem.getAbilities().getRules(null); if (rules.size() == 1) { - sb.append(rules.get(0)); + for (String s : rules) { + sb.append(s); + } sb.append('"'); } else if (rules.size() == 2) { for (String s : rules) { @@ -83,7 +85,6 @@ public class GetEmblemEffect extends OneShotEffect { } sb.append('"'); } - sb.append('.'); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index b7e43315d5..5a93cbae46 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -264,9 +264,11 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff sb.append(". You may reveal "); sb.append(filter.getMessage()).append(" from among them and put it into your "); } else if (targetPickedCards == Zone.BATTLEFIELD) { - sb.append(". You "); + sb.append(". "); if (optional) { - sb.append("may "); + sb.append("You may p"); + } else { + sb.append('P'); } sb.append("put ").append(filter.getMessage()).append(" from among them onto the "); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index 1283cc5972..f622abea91 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -63,7 +63,7 @@ public class CantBlockAttachedEffect extends RestrictionEffect { sb.append(' ').append(filter.getMessage()); } if (duration == EndOfTurn) { - sb.append("this turn"); + sb.append(" this turn"); } else if (!duration.toString().isEmpty()) { sb.append(' ').append(duration.toString()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java index 796fa3060c..0de648e5bf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.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.abilities.effects.common.continuous; import mage.constants.Duration; @@ -116,21 +115,24 @@ public class BoostEquippedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Equipped creature gets "); + sb.append("equipped creature gets "); String p = power.toString(); - if (!p.startsWith("-")) + if (!p.startsWith("-")) { sb.append('+'); + } sb.append(p).append('/'); String t = toughness.toString(); if (!t.startsWith("-")) { - if (p.startsWith("-")) + if (p.startsWith("-")) { sb.append('-'); - else + } else { sb.append('+'); + } } sb.append(t); - if (duration != Duration.WhileOnBattlefield) + if (duration != Duration.WhileOnBattlefield) { sb.append(' ').append(duration.toString()); + } String message = power.getMessage(); if (!message.isEmpty()) { sb.append(" for each "); diff --git a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java index 46471af292..5f1b480406 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java @@ -89,7 +89,7 @@ public class ProtectionAbility extends StaticAbility { @Override public String getRule() { - return "protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); + return "Protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); } public boolean canTarget(MageObject source, Game game) { diff --git a/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java b/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java index a88922d345..69381c0a15 100644 --- a/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.constants.Zone; @@ -37,19 +36,24 @@ import java.io.ObjectStreamException; /** * 702.77. Wither * - * 702.77a. Wither is a static ability. Damage dealt to a creature by a source with wither isn't marked on that creature. Rather, it causes that many -1/-1 counters to be put on that creature. See rule 119.3. + * 702.77a. Wither is a static ability. Damage dealt to a creature by a source + * with wither isn't marked on that creature. Rather, it causes that many -1/-1 + * counters to be put on that creature. See rule 119.3. * - * 702.77b. If a permanent leaves the battlefield before an effect causes it to deal damage, its last known information is used to determine whether it had wither. + * 702.77b. If a permanent leaves the battlefield before an effect causes it to + * deal damage, its last known information is used to determine whether it had + * wither. * - * 702.77c. The wither rules function no matter what zone an object with wither deals damage from. + * 702.77c. The wither rules function no matter what zone an object with wither + * deals damage from. * - * 702.77d. Multiple instances of wither on the same object are redundant. + * 702.77d. Multiple instances of wither on the same object are redundant. * - * @author nantuko + * @author nantuko */ public class WitherAbility extends StaticAbility implements MageSingleton { - private static final WitherAbility instance = new WitherAbility(); + private static final WitherAbility instance = new WitherAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -65,7 +69,7 @@ public class WitherAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Wither (This deals damage to creatures in the form of -1/-1 counters.)"; + return "wither (This deals damage to creatures in the form of -1/-1 counters.)"; } @Override diff --git a/Mage/src/test/java/mage/ManaTest.java b/Mage/src/test/java/mage/ManaTest.java index 2f49626955..1ad59de468 100644 --- a/Mage/src/test/java/mage/ManaTest.java +++ b/Mage/src/test/java/mage/ManaTest.java @@ -497,7 +497,7 @@ public class ManaTest { String ret = mana.toString(); // then - assertEquals("{6}{R}{G}{G}{U}{U}{U}{B}{B}{B}{Any}{Any}", ret); + assertEquals("{6}{U}{U}{U}{B}{B}{B}{R}{G}{G}{Any}{Any}", ret); } @Test From b94c23023641eedfdebaf76943a66821c737c32c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 14:54:37 +0200 Subject: [PATCH 007/164] Implemented Goblin Festival --- .../src/mage/cards/g/GoblinFestival.java | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinFestival.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinFestival.java b/Mage.Sets/src/mage/cards/g/GoblinFestival.java new file mode 100644 index 0000000000..8a12d1021a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinFestival.java @@ -0,0 +1,147 @@ +/* + * 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.g; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCreatureOrPlayer; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class GoblinFestival extends CardImpl { + + public GoblinFestival(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); + + // {2}: Goblin Festival deals 1 damage to target creature or player. Flip a coin. If you lose the flip, choose one of your opponents. That player gains control of Goblin Festival. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{2}")); + ability.addTarget(new TargetCreatureOrPlayer()); + ability.addEffect(new GoblinFestivalChangeControlEffect()); + this.addAbility(ability); + } + + public GoblinFestival(final GoblinFestival card) { + super(card); + } + + @Override + public GoblinFestival copy() { + return new GoblinFestival(this); + } +} + +class GoblinFestivalChangeControlEffect extends OneShotEffect { + + public GoblinFestivalChangeControlEffect() { + super(Outcome.Benefit); + this.staticText = "Flip a coin. If you lose the flip, choose one of your opponents. That player gains control of {this}"; + } + + public GoblinFestivalChangeControlEffect(final GoblinFestivalChangeControlEffect effect) { + super(effect); + } + + @Override + public GoblinFestivalChangeControlEffect copy() { + return new GoblinFestivalChangeControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (!controller.flipCoin(game)) { + Target target = new TargetOpponent(); + target.setNotTarget(true); + if (controller.chooseTarget(outcome, target, source, game)) { + ContinuousEffect effect = new GoblinFestivalGainControlEffect(Duration.Custom, target.getFirstTarget()); + effect.setTargetPointer(new FixedTarget(source.getSourceId())); + game.addEffect(effect, source); + return true; + } + } + } + return false; + } +} + +class GoblinFestivalGainControlEffect extends ContinuousEffectImpl { + + UUID controller; + + public GoblinFestivalGainControlEffect(Duration duration, UUID controller) { + super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controller = controller; + } + + public GoblinFestivalGainControlEffect(final GoblinFestivalGainControlEffect effect) { + super(effect); + this.controller = effect.controller; + } + + @Override + public GoblinFestivalGainControlEffect copy() { + return new GoblinFestivalGainControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (targetPointer != null) { + permanent = game.getPermanent(targetPointer.getFirst(game, source)); + } + if (permanent != null) { + return permanent.changeControllerId(controller, game); + } + return false; + } + + @Override + public String getText(Mode mode) { + return "That player gains control of {this}"; + } +} From 5d82208a82fe70262a22a2b2d65ac724dcedcd1c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 14:54:38 +0200 Subject: [PATCH 008/164] Implemented Goblin Festival --- Mage.Sets/src/mage/sets/UrzasDestiny.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index e05b5e775a..6a243198e5 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -73,7 +73,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Capashen Standard", 4, Rarity.COMMON, mage.cards.c.CapashenStandard.class)); cards.add(new SetCardInfo("Capashen Templar", 5, Rarity.COMMON, mage.cards.c.CapashenTemplar.class)); cards.add(new SetCardInfo("Carnival of Souls", 55, Rarity.RARE, mage.cards.c.CarnivalOfSouls.class)); - cards.add(new SetCardInfo("Chime of Night", 56, Rarity.COMMON, mage.cards.c.ChimeOfNight.class)); + cards.add(new SetCardInfo("Chime of Night", 56, Rarity.COMMON, mage.cards.c.ChimeOfNight.class)); cards.add(new SetCardInfo("Colos Yearling", 79, Rarity.COMMON, mage.cards.c.ColosYearling.class)); cards.add(new SetCardInfo("Compost", 102, Rarity.UNCOMMON, mage.cards.c.Compost.class)); cards.add(new SetCardInfo("Covetous Dragon", 80, Rarity.RARE, mage.cards.c.CovetousDragon.class)); @@ -95,6 +95,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Fodder Cannon", 131, Rarity.UNCOMMON, mage.cards.f.FodderCannon.class)); cards.add(new SetCardInfo("Gamekeeper", 106, Rarity.UNCOMMON, mage.cards.g.Gamekeeper.class)); cards.add(new SetCardInfo("Goblin Berserker", 82, Rarity.UNCOMMON, mage.cards.g.GoblinBerserker.class)); + cards.add(new SetCardInfo("Goblin Festival", 83, Rarity.RARE, mage.cards.g.GoblinFestival.class)); cards.add(new SetCardInfo("Goblin Gardener", 84, Rarity.COMMON, mage.cards.g.GoblinGardener.class)); cards.add(new SetCardInfo("Goblin Marshal", 85, Rarity.RARE, mage.cards.g.GoblinMarshal.class)); cards.add(new SetCardInfo("Goblin Masons", 86, Rarity.COMMON, mage.cards.g.GoblinMasons.class)); @@ -104,7 +105,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); - cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); + cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); cards.add(new SetCardInfo("Junk Diver", 132, Rarity.RARE, mage.cards.j.JunkDiver.class)); cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); @@ -140,7 +141,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Rescue", 44, Rarity.COMMON, mage.cards.r.Rescue.class)); cards.add(new SetCardInfo("Rofellos, Llanowar Emissary", 118, Rarity.RARE, mage.cards.r.RofellosLlanowarEmissary.class)); cards.add(new SetCardInfo("Sanctimony", 16, Rarity.UNCOMMON, mage.cards.s.Sanctimony.class)); - cards.add(new SetCardInfo("Scent of Jasmine", 17, Rarity.COMMON, mage.cards.s.ScentOfJasmine.class)); + cards.add(new SetCardInfo("Scent of Jasmine", 17, Rarity.COMMON, mage.cards.s.ScentOfJasmine.class)); cards.add(new SetCardInfo("Scour", 18, Rarity.UNCOMMON, mage.cards.s.Scour.class)); cards.add(new SetCardInfo("Serra Advocate", 19, Rarity.UNCOMMON, mage.cards.s.SerraAdvocate.class)); cards.add(new SetCardInfo("Sigil of Sleep", 46, Rarity.COMMON, mage.cards.s.SigilOfSleep.class)); From 19a67a76ff62c4124582ec8c213c161ce8fcff64 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 14:56:43 +0200 Subject: [PATCH 009/164] Implemented Sphere of Purity --- .../src/mage/cards/s/SphereOfPurity.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfPurity.java diff --git a/Mage.Sets/src/mage/cards/s/SphereOfPurity.java b/Mage.Sets/src/mage/cards/s/SphereOfPurity.java new file mode 100644 index 0000000000..d7c691bc97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfPurity.java @@ -0,0 +1,97 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J + */ +public class SphereOfPurity extends CardImpl { + + public SphereOfPurity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If an artifact would deal damage to you, prevent 1 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SphereOfPurityEffect())); + } + + public SphereOfPurity(final SphereOfPurity card) { + super(card); + } + + @Override + public SphereOfPurity copy() { + return new SphereOfPurity(this); + } +} + +class SphereOfPurityEffect extends PreventionEffectImpl { + + public SphereOfPurityEffect() { + super(Duration.WhileOnBattlefield, 1, false, false); + this.staticText = "If an artifact would deal damage to you, prevent 1 of that damage"; + } + + public SphereOfPurityEffect(SphereOfPurityEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(source.getControllerId())) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent != null && permanent.isArtifact()) { + return super.applies(event, source, game); + } + } + return false; + } + + @Override + public SphereOfPurityEffect copy() { + return new SphereOfPurityEffect(this); + } +} From 9902cc17d24e2831d37ee29fa1c2e3ec0ff394f9 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 14:56:52 +0200 Subject: [PATCH 010/164] Implemented Sphere of Purity --- Mage.Sets/src/mage/sets/Mirrodin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index 2348a680ac..7222f68d8a 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -250,6 +250,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Soul Foundry", 246, Rarity.RARE, mage.cards.s.SoulFoundry.class)); cards.add(new SetCardInfo("Soul Nova", 25, Rarity.UNCOMMON, mage.cards.s.SoulNova.class)); cards.add(new SetCardInfo("Spellweaver Helix", 247, Rarity.RARE, mage.cards.s.SpellweaverHelix.class)); + cards.add(new SetCardInfo("Sphere of Purity", 26, Rarity.COMMON, mage.cards.s.SphereOfPurity.class)); cards.add(new SetCardInfo("Spikeshot Goblin", 108, Rarity.COMMON, mage.cards.s.SpikeshotGoblin.class)); cards.add(new SetCardInfo("Spoils of the Vault", 78, Rarity.RARE, mage.cards.s.SpoilsOfTheVault.class)); cards.add(new SetCardInfo("Stalking Stones", 284, Rarity.UNCOMMON, mage.cards.s.StalkingStones.class)); From f16b5881e8d421737b0ac6b402eebf579a799319 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 18:37:09 -0400 Subject: [PATCH 011/164] fext tixes --- Mage.Sets/src/mage/cards/a/AltarGolem.java | 18 ++++---- .../mage/cards/b/BattlefieldThaumaturge.java | 11 +++-- .../src/mage/cards/b/BloodcrazedHoplite.java | 4 +- Mage.Sets/src/mage/cards/c/CavalryMaster.java | 15 ++++--- .../src/mage/cards/c/ChariotOfVictory.java | 4 +- .../src/mage/cards/c/ColossalHeroics.java | 7 ++- Mage.Sets/src/mage/cards/d/DakraMystic.java | 23 +++++----- .../src/mage/cards/d/DementiaSliver.java | 15 ++++--- .../src/mage/cards/d/DictateOfErebos.java | 6 +-- Mage.Sets/src/mage/cards/e/Evangelize.java | 2 +- .../src/mage/cards/f/FirewakeSliver.java | 16 +++---- .../src/mage/cards/f/FlagstonesOfTrokair.java | 4 +- .../src/mage/cards/f/FlowstoneChanneler.java | 5 +-- .../src/mage/cards/g/GoblinSkycutter.java | 6 +-- Mage.Sets/src/mage/cards/g/Godsend.java | 4 +- Mage.Sets/src/mage/cards/g/Greenseeker.java | 6 +-- Mage.Sets/src/mage/cards/h/Hubris.java | 4 +- .../src/mage/cards/l/LaunchTheFleet.java | 2 +- .../mage/cards/l/LimDulTheNecromancer.java | 4 +- .../src/mage/cards/m/MagusOfTheScroll.java | 6 +-- .../src/mage/cards/m/MangaraOfCorondor.java | 2 +- .../src/mage/cards/m/MirrorUniverse.java | 2 +- .../src/mage/cards/m/MogissWarhound.java | 8 ++-- Mage.Sets/src/mage/cards/m/Molder.java | 6 +-- .../src/mage/cards/m/MwonvuliAcidMoss.java | 16 ++++--- .../src/mage/cards/n/NessianGameWarden.java | 4 +- .../src/mage/cards/p/PendelhavenElder.java | 8 +++- .../mage/cards/p/PharikaGodOfAffliction.java | 2 +- .../src/mage/cards/p/PrismaticGeoscope.java | 12 +++-- .../mage/cards/p/PropheticFlamespeaker.java | 8 ++-- Mage.Sets/src/mage/cards/r/Reiterate.java | 18 ++------ .../src/mage/cards/r/RiptideChimera.java | 9 ++-- .../src/mage/cards/r/RitualOfTheReturned.java | 2 +- .../src/mage/cards/s/ScarwoodTreefolk.java | 6 +-- .../src/mage/cards/s/ScreechingSliver.java | 4 +- Mage.Sets/src/mage/cards/s/ScrybRanger.java | 5 ++- .../src/mage/cards/s/SetessanTactics.java | 7 ++- .../src/mage/cards/s/SidewinderSliver.java | 13 +++--- Mage.Sets/src/mage/cards/s/SpellSwindle.java | 2 +- Mage.Sets/src/mage/cards/s/Spirespine.java | 8 ++-- .../src/mage/cards/s/StormFleetAerialist.java | 2 +- .../src/mage/cards/s/StranglingSoot.java | 2 +- .../src/mage/cards/s/SwarmbornGiant.java | 10 ++--- .../src/mage/cards/v/VesuvanShapeshifter.java | 6 +-- Mage.Sets/src/mage/cards/w/WheelOfFate.java | 4 +- Mage.Sets/src/mage/cards/w/WormwoodDryad.java | 6 +-- .../condition/common/IsStepCondition.java | 2 +- .../AddConditionalManaOfAnyColorEffect.java | 4 +- .../common/CreateTokenCopyTargetEffect.java | 4 +- .../common/PreventDamageToTargetEffect.java | 15 +++---- ...TopCardOfLibraryIntoGraveTargetEffect.java | 2 +- .../TapAllTargetPlayerControlsEffect.java | 2 +- .../combat/BlocksIfAbleAttachedEffect.java | 4 +- .../combat/BlocksIfAbleSourceEffect.java | 6 +-- ...MustBeBlockedByAtLeastOneTargetEffect.java | 44 +++++++++---------- ...dHandLibraryForCardNameAndExileEffect.java | 2 +- .../abilities/keyword/FlankingAbility.java | 12 ++--- .../mage/abilities/keyword/MorphAbility.java | 6 ++- .../abilities/keyword/RampageAbility.java | 2 +- .../mage/abilities/keyword/ShadowAbility.java | 6 ++- .../main/java/mage/filter/StaticFilters.java | 2 +- 61 files changed, 223 insertions(+), 224 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AltarGolem.java b/Mage.Sets/src/mage/cards/a/AltarGolem.java index 551314c24d..40a7fad949 100644 --- a/Mage.Sets/src/mage/cards/a/AltarGolem.java +++ b/Mage.Sets/src/mage/cards/a/AltarGolem.java @@ -53,18 +53,18 @@ import mage.target.common.TargetControlledCreaturePermanent; /** * * @author jeffwadsworth - + * */ public class AltarGolem extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control"); - + static { filter.add(Predicates.not(new TappedPredicate())); } public AltarGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); this.subtype.add(SubType.GOLEM); this.power = new MageInt(0); @@ -72,17 +72,17 @@ public class AltarGolem extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - + // Altar Golem's power and toughness are each equal to the number of creatures on the battlefield. - DynamicValue amount = new PermanentsOnBattlefieldCount(new FilterCreaturePermanent("creatures in play")); + DynamicValue amount = new PermanentsOnBattlefieldCount(new FilterCreaturePermanent("creatures on the battlefield")); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(amount, Duration.EndOfGame))); - + // Altar Golem doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Tap five untapped creatures you control: Untap Altar Golem. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(5, 5, filter, true)))); - + } public AltarGolem(final AltarGolem card) { diff --git a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java index 1177fc15e2..9b0993799e 100644 --- a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java +++ b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java @@ -55,7 +55,7 @@ import mage.util.CardUtil; public class BattlefieldThaumaturge extends CardImpl { public BattlefieldThaumaturge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.HUMAN, SubType.WIZARD); this.power = new MageInt(2); @@ -79,10 +79,9 @@ public class BattlefieldThaumaturge extends CardImpl { class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEffectImpl { - public BattlefieldThaumaturgeSpellsCostReductionEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); - this.staticText = "Each instant and sorcery spell you cast costs 1 less to cast for each creature it targets"; + this.staticText = "Each instant and sorcery spell you cast costs {1} less to cast for each creature it targets"; } protected BattlefieldThaumaturgeSpellsCostReductionEffect(BattlefieldThaumaturgeSpellsCostReductionEffect effect) { @@ -92,9 +91,9 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { Set creaturesTargeted = new HashSet<>(); - for (Target target: abilityToModify.getTargets()) { - for (UUID uuid: target.getTargets()) { - Permanent permanent = game.getPermanent(uuid); + for (Target target : abilityToModify.getTargets()) { + for (UUID uuid : target.getTargets()) { + Permanent permanent = game.getPermanent(uuid); if (permanent != null && permanent.isCreature()) { creaturesTargeted.add(permanent.getId()); } diff --git a/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java b/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java index b83b30f684..4ea155477d 100644 --- a/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java +++ b/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java @@ -61,7 +61,7 @@ public class BloodcrazedHoplite extends CardImpl { } public BloodcrazedHoplite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN, SubType.SOLDIER); this.power = new MageInt(2); @@ -88,7 +88,7 @@ public class BloodcrazedHoplite extends CardImpl { class BloodcrazedHopliteTriggeredAbility extends TriggeredAbilityImpl { public BloodcrazedHopliteTriggeredAbility() { - super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); + super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), false); } public BloodcrazedHopliteTriggeredAbility(BloodcrazedHopliteTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/c/CavalryMaster.java b/Mage.Sets/src/mage/cards/c/CavalryMaster.java index ca06f4981a..6d20173064 100644 --- a/Mage.Sets/src/mage/cards/c/CavalryMaster.java +++ b/Mage.Sets/src/mage/cards/c/CavalryMaster.java @@ -46,15 +46,15 @@ import mage.filter.predicate.mageobject.AbilityPredicate; * @author Plopman */ public class CavalryMaster extends CardImpl { - + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures you control with flanking"); - - static{ + + static { filter.add(new AbilityPredicate(FlankingAbility.class)); } - + public CavalryMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.KNIGHT); @@ -64,7 +64,10 @@ public class CavalryMaster extends CardImpl { // Flanking this.addAbility(new FlankingAbility()); // Other creatures you control with flanking have flanking. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, true))); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, true) + .setText("Other creatures you control with flanking have flanking.") + )); } public CavalryMaster(final CavalryMaster card) { diff --git a/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java b/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java index e45ae7966d..9207df79dd 100644 --- a/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java +++ b/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java @@ -52,13 +52,13 @@ import mage.constants.Zone; public class ChariotOfVictory extends CardImpl { public ChariotOfVictory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature has first strike, trample, and haste. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT)); Effect effect = new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.EQUIPMENT); - effect.setText(", trample"); + effect.setText(", trample,"); ability.addEffect(effect); effect = new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.EQUIPMENT); effect.setText("and haste"); diff --git a/Mage.Sets/src/mage/cards/c/ColossalHeroics.java b/Mage.Sets/src/mage/cards/c/ColossalHeroics.java index bcad9fda9e..3dd6608302 100644 --- a/Mage.Sets/src/mage/cards/c/ColossalHeroics.java +++ b/Mage.Sets/src/mage/cards/c/ColossalHeroics.java @@ -45,14 +45,13 @@ import mage.target.common.TargetCreaturePermanent; public class ColossalHeroics extends CardImpl { public ColossalHeroics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); // Strive - Colossal Heroics costs {1}{G} more to cast for each target beyond the first. this.addAbility(new StriveAbility("{1}{G}")); // Any number of target creatures each get +2/+2 until end of turn. Untap those creatures. - Effect effect = new BoostTargetEffect(2,2, Duration.EndOfTurn); - effect.setText("Any number of target creatures each get +2/+2"); + Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); + effect.setText("Any number of target creatures each get +2/+2 until end of turn."); this.getSpellAbility().addEffect(effect); effect = new UntapTargetEffect(); effect.setText("Untap those creatures"); diff --git a/Mage.Sets/src/mage/cards/d/DakraMystic.java b/Mage.Sets/src/mage/cards/d/DakraMystic.java index 18ff2b5fa9..3c9b890b5c 100644 --- a/Mage.Sets/src/mage/cards/d/DakraMystic.java +++ b/Mage.Sets/src/mage/cards/d/DakraMystic.java @@ -52,7 +52,7 @@ import mage.players.Player; public class DakraMystic extends CardImpl { public DakraMystic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.WIZARD); @@ -63,8 +63,7 @@ public class DakraMystic extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DakraMysticEffect(), new ManaCostsImpl("{U}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - - + } public DakraMystic(final DakraMystic card) { @@ -78,38 +77,38 @@ public class DakraMystic extends CardImpl { } class DakraMysticEffect extends OneShotEffect { - + public DakraMysticEffect() { super(Outcome.Detriment); - this.staticText = "Each player reveals the top card of his or her library. You may put the revealed cards into their owners graveyard. If you don't, each player draws a card"; + this.staticText = "Each player reveals the top card of his or her library. You may put the revealed cards into their owners' graveyard. If you don't, each player draws a card"; } - + public DakraMysticEffect(final DakraMysticEffect effect) { super(effect); } - + @Override public DakraMysticEffect copy() { return new DakraMysticEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && player.getLibrary().hasCards()) { player.revealCards(player.getLogName(), new CardsImpl(player.getLibrary().getFromTop(game)), game); } } if (controller.chooseUse(outcome, "Put revealed cards into graveyard?", source, game)) { - for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); if (player != null && player.getLibrary().hasCards()) { player.moveCards(player.getLibrary().getFromTop(game), Zone.GRAVEYARD, source, game); } - } + } } else { new DrawCardAllEffect(1).apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/d/DementiaSliver.java b/Mage.Sets/src/mage/cards/d/DementiaSliver.java index 97d586ff79..8e5cfb838b 100644 --- a/Mage.Sets/src/mage/cards/d/DementiaSliver.java +++ b/Mage.Sets/src/mage/cards/d/DementiaSliver.java @@ -51,7 +51,7 @@ import mage.target.common.TargetOpponent; * @author fireshoes */ public class DementiaSliver extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("All Slivers"); static { @@ -59,7 +59,7 @@ public class DementiaSliver extends CardImpl { } public DementiaSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -70,7 +70,12 @@ public class DementiaSliver extends CardImpl { gainedAbility.addTarget(new TargetOpponent()); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(gainedAbility, Duration.WhileOnBattlefield, filter, - "All Slivers have \"{T}: Name a card. Target opponent reveals a card at random from his or her hand. If it's the named card, that player discards it\""))); + "All Slivers have \"{T}: Choose a card name. " + + "Target opponent reveals a card at random from his or her hand." + + " If that card has the chosen name, that player discards it." + + " Activate this ability only during your turn.\"" + ) + )); } public DementiaSliver(final DementiaSliver card) { @@ -98,7 +103,7 @@ class DementiaSliverEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); if (opponent != null && sourceObject != null && !cardName.isEmpty()) { if (!opponent.getHand().isEmpty()) { Cards revealed = new CardsImpl(); @@ -121,4 +126,4 @@ class DementiaSliverEffect extends OneShotEffect { return new DementiaSliverEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DictateOfErebos.java b/Mage.Sets/src/mage/cards/d/DictateOfErebos.java index 87cb1a626f..4efc724617 100644 --- a/Mage.Sets/src/mage/cards/d/DictateOfErebos.java +++ b/Mage.Sets/src/mage/cards/d/DictateOfErebos.java @@ -45,19 +45,19 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class DictateOfErebos extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control"); static { filter.add(new ControllerPredicate(TargetController.YOU)); } public DictateOfErebos(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); // Flash this.addAbility(FlashAbility.getInstance()); // Whenever a creature you control dies, each opponent sacrifices a creature. - this.addAbility(new DiesCreatureTriggeredAbility(new SacrificeOpponentsEffect(new FilterControlledCreaturePermanent("a creature")), false, filter)); + this.addAbility(new DiesCreatureTriggeredAbility(new SacrificeOpponentsEffect(new FilterControlledCreaturePermanent("creature")), false, filter)); } public DictateOfErebos(final DictateOfErebos card) { diff --git a/Mage.Sets/src/mage/cards/e/Evangelize.java b/Mage.Sets/src/mage/cards/e/Evangelize.java index 74ad62887d..c9209a99c3 100644 --- a/Mage.Sets/src/mage/cards/e/Evangelize.java +++ b/Mage.Sets/src/mage/cards/e/Evangelize.java @@ -53,7 +53,7 @@ public class Evangelize extends CardImpl { // Gain control of target creature of an opponent's choice that he or she controls. GainControlTargetEffect effect = new GainControlTargetEffect(Duration.EndOfGame); - effect.setText("Gain control of target creature of an opponent's choice that he or she controls"); + effect.setText("Gain control of target creature of an opponent's choice he or she controls"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addTarget(new TargetOpponentsChoicePermanent(1, 1, filter, false, true)); } diff --git a/Mage.Sets/src/mage/cards/f/FirewakeSliver.java b/Mage.Sets/src/mage/cards/f/FirewakeSliver.java index 3fcef064a9..fe0ec2a538 100644 --- a/Mage.Sets/src/mage/cards/f/FirewakeSliver.java +++ b/Mage.Sets/src/mage/cards/f/FirewakeSliver.java @@ -53,32 +53,32 @@ import mage.target.common.TargetCreaturePermanent; */ public class FirewakeSliver extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("All sliver creatures"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("All Sliver creatures"); private static final FilterCreaturePermanent targetSliverFilter = new FilterCreaturePermanent("Sliver"); static { filter.add(new SubtypePredicate(SubType.SLIVER)); targetSliverFilter.add(new SubtypePredicate(SubType.SLIVER)); } - + public FirewakeSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); // All Sliver creatures have haste. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false))); + // All Slivers have "{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn." - Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2,2,Duration.EndOfTurn), new GenericManaCost(1)); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 2, Duration.EndOfTurn), new GenericManaCost(1)); gainedAbility.addCost(new SacrificeSourceCost()); gainedAbility.addTarget(new TargetCreaturePermanent(targetSliverFilter)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( gainedAbility, Duration.WhileOnBattlefield, - filter, "All Slivers have \"{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn.\""))); - + filter, "All Slivers have \"{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn.\""))); + } public FirewakeSliver(final FirewakeSliver card) { diff --git a/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java b/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java index d9decea82e..b49857fe67 100644 --- a/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java +++ b/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java @@ -53,14 +53,14 @@ public class FlagstonesOfTrokair extends CardImpl { } public FlagstonesOfTrokair(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); addSuperType(SuperType.LEGENDARY); // {tap}: Add {W} to your mana pool. this.addAbility(new WhiteManaAbility()); // When Flagstones of Trokair is put into a graveyard from the battlefield, you may search your library for a Plains card and put it onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(FILTER), true, true), true)); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(FILTER), true, false), true)); } public FlagstonesOfTrokair(final FlagstonesOfTrokair card) { diff --git a/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java b/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java index 6ed51dca07..b70542b911 100644 --- a/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java +++ b/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; @@ -43,7 +43,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreaturePermanent; /** @@ -69,7 +68,7 @@ public class FlowstoneChanneler extends CardImpl { ability.addEffect(effect); ability.addTarget(new TargetCreaturePermanent()); ability.addCost(new TapSourceCost()); - ability.addCost(new DiscardTargetCost(new TargetCardInHand())); + ability.addCost(new DiscardCardCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java b/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java index 16147bfc0f..112f0a02ca 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java +++ b/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class GoblinSkycutter extends CardImpl { @@ -59,7 +59,7 @@ public class GoblinSkycutter extends CardImpl { } public GoblinSkycutter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(2); @@ -67,7 +67,7 @@ public class GoblinSkycutter extends CardImpl { // Sacrifice Goblin Skycutter: Goblin Skycutter deals 2 damage to target creature with flying. That creature loses flying until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new SacrificeSourceCost()); - ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn).setText("that creature loses flying until end of turn")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Godsend.java b/Mage.Sets/src/mage/cards/g/Godsend.java index 580494ee00..c47dbf04cb 100644 --- a/Mage.Sets/src/mage/cards/g/Godsend.java +++ b/Mage.Sets/src/mage/cards/g/Godsend.java @@ -63,7 +63,7 @@ import mage.util.CardUtil; public class Godsend extends CardImpl { public Godsend(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.EQUIPMENT); @@ -195,7 +195,7 @@ class GodsendRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { public GodsendRuleModifyingEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Opponents can't cast cards with the same name as cards exiled with {this}"; + staticText = "Your opponents can't cast cards with the same name as cards exiled with {this}"; } public GodsendRuleModifyingEffect(final GodsendRuleModifyingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/g/Greenseeker.java b/Mage.Sets/src/mage/cards/g/Greenseeker.java index 9f0a7e6ece..4b873b29bb 100644 --- a/Mage.Sets/src/mage/cards/g/Greenseeker.java +++ b/Mage.Sets/src/mage/cards/g/Greenseeker.java @@ -51,7 +51,7 @@ import java.util.UUID; public class Greenseeker extends CardImpl { public Greenseeker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SPELLSHAPER); this.power = new MageInt(1); @@ -59,8 +59,8 @@ public class Greenseeker extends CardImpl { // {G}, {tap}, Discard a card: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), - new ManaCostsImpl("{G}")); + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/h/Hubris.java b/Mage.Sets/src/mage/cards/h/Hubris.java index 0c8751cc88..cb4cb55983 100644 --- a/Mage.Sets/src/mage/cards/h/Hubris.java +++ b/Mage.Sets/src/mage/cards/h/Hubris.java @@ -52,7 +52,7 @@ import mage.target.common.TargetCreaturePermanent; public class Hubris extends CardImpl { public Hubris(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return target creature and all Auras attached to it to their owners' hand. this.getSpellAbility().addEffect(new HubrisReturnEffect()); @@ -80,7 +80,7 @@ class HubrisReturnEffect extends OneShotEffect { public HubrisReturnEffect() { super(Outcome.Benefit); - this.staticText = "Return target creature and all Auras attached to it to their owners' hand"; + this.staticText = "Return target creature and all Auras attached to it to their owners' hands"; } public HubrisReturnEffect(final HubrisReturnEffect effect) { diff --git a/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java b/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java index edb409c372..8a19cbb2d2 100644 --- a/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java +++ b/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java @@ -55,7 +55,7 @@ public class LaunchTheFleet extends CardImpl { // Until end of turn, any number of target creatures each gain "Whenever this creature attacks, create a 1/1 white Soldier token tapped and attacking." this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); Effect effect = new GainAbilityTargetEffect(new AttacksTriggeredAbility(new CreateTokenEffect(new SoldierToken(), 1, true, true), false), Duration.EndOfTurn); - effect.setText("Until end of turn, any number of target creatures each gain \"Whenever this creature attacks, create a 1/1 white Soldier token tapped and attacking.\""); + effect.setText("Until end of turn, any number of target creatures each gain \"Whenever this creature attacks, create a 1/1 white Soldier creature token that's tapped and attacking.\""); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java index 0e1abb3cca..c04355a0ba 100644 --- a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java +++ b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; */ public class LimDulTheNecromancer extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls"); private static final FilterPermanent filter2 = new FilterPermanent("Zombie"); static { @@ -67,7 +67,7 @@ public class LimDulTheNecromancer extends CardImpl { } public LimDulTheNecromancer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java b/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java index 3c84e6ae22..aab52ad541 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class MagusOfTheScroll extends CardImpl { public MagusOfTheScroll(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(1); @@ -85,7 +85,7 @@ class MagusOfTheScrollEffect extends OneShotEffect { public MagusOfTheScrollEffect() { super(Outcome.Neutral); - staticText = "Reveal a card at random from your hand. If it's the named card, {this} deals 2 damage to target creature or player"; + staticText = ", then reveal a card at random from your hand. If it's the named card, {this} deals 2 damage to target creature or player"; } public MagusOfTheScrollEffect(final MagusOfTheScrollEffect effect) { @@ -126,4 +126,4 @@ class MagusOfTheScrollEffect extends OneShotEffect { public MagusOfTheScrollEffect copy() { return new MagusOfTheScrollEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java b/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java index 718cfcd57f..3decdc220e 100644 --- a/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java +++ b/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java @@ -59,7 +59,7 @@ public class MangaraOfCorondor extends CardImpl { // {T}: Exile Mangara of Corondor and target permanent. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(), new TapSourceCost()); - ability.addEffect(new ExileTargetEffect()); + ability.addEffect(new ExileTargetEffect().setText("and target permanent")); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MirrorUniverse.java b/Mage.Sets/src/mage/cards/m/MirrorUniverse.java index fe8b1ba141..aae1fd8ea1 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorUniverse.java +++ b/Mage.Sets/src/mage/cards/m/MirrorUniverse.java @@ -55,7 +55,7 @@ public class MirrorUniverse extends CardImpl { Zone.BATTLEFIELD, new ExchangeLifeTargetEffect(), new TapSourceCost(), - new IsStepCondition(PhaseStep.UPKEEP), + new IsStepCondition(PhaseStep.UPKEEP, true), null); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetOpponent()); diff --git a/Mage.Sets/src/mage/cards/m/MogissWarhound.java b/Mage.Sets/src/mage/cards/m/MogissWarhound.java index d4138b8534..1d5ce89a0a 100644 --- a/Mage.Sets/src/mage/cards/m/MogissWarhound.java +++ b/Mage.Sets/src/mage/cards/m/MogissWarhound.java @@ -51,7 +51,7 @@ import mage.constants.Zone; public class MogissWarhound extends CardImpl { public MogissWarhound(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HOUND); this.power = new MageInt(2); @@ -62,13 +62,13 @@ public class MogissWarhound extends CardImpl { // Mogis's Warhound attacks each turn if able. this.addAbility(new AttacksEachCombatStaticAbility()); // Enchanted creature gets +2/+2 and attacks each turn if able. - Effect effect = new BoostEnchantedEffect(2,2,Duration.WhileOnBattlefield); + Effect effect = new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +2/+2"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); effect = new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA); - effect.setText("and attacks each turn if able"); + effect.setText("and attacks each combat if able"); ability.addEffect(effect); - this.addAbility(ability); + this.addAbility(ability); } public MogissWarhound(final MogissWarhound card) { diff --git a/Mage.Sets/src/mage/cards/m/Molder.java b/Mage.Sets/src/mage/cards/m/Molder.java index 3969ed8f67..303dd0f33c 100644 --- a/Mage.Sets/src/mage/cards/m/Molder.java +++ b/Mage.Sets/src/mage/cards/m/Molder.java @@ -49,17 +49,17 @@ import mage.target.TargetPermanent; public class Molder extends CardImpl { public Molder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}"); // Destroy target artifact or enchantment with converted mana cost X. It can't be regenerated. You gain X life. - this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); this.getSpellAbility().addTarget(new TargetPermanent(new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"))); this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue())); } @Override public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { + if (ability instanceof SpellAbility) { ability.getTargets().clear(); int xValue = ability.getManaCostsToPay().getX(); FilterArtifactOrEnchantmentPermanent filter = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"); diff --git a/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java b/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java index 0b59350e95..e4d18bdc96 100644 --- a/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java +++ b/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java @@ -46,14 +46,17 @@ import mage.target.common.TargetCardInLibrary; */ public class MwonvuliAcidMoss extends CardImpl { - public MwonvuliAcidMoss(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}{G}"); - - FilterLandCard filterForest = new FilterLandCard(); + private static final FilterLandCard filterForest = new FilterLandCard("Forest card"); + + static { filterForest.add(new SubtypePredicate(SubType.FOREST)); - + } + + public MwonvuliAcidMoss(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + // Destroy target land. Search your library for a Forest card and put that card onto the battlefield tapped. Then shuffle your library. - this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(new FilterLandPermanent())); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterForest), true, true)); } @@ -67,4 +70,3 @@ public class MwonvuliAcidMoss extends CardImpl { return new MwonvuliAcidMoss(this); } } - diff --git a/Mage.Sets/src/mage/cards/n/NessianGameWarden.java b/Mage.Sets/src/mage/cards/n/NessianGameWarden.java index fe78091f32..9f6511ef2c 100644 --- a/Mage.Sets/src/mage/cards/n/NessianGameWarden.java +++ b/Mage.Sets/src/mage/cards/n/NessianGameWarden.java @@ -57,7 +57,7 @@ import mage.target.TargetCard; public class NessianGameWarden extends CardImpl { public NessianGameWarden(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(4); @@ -87,7 +87,7 @@ class NessianGameWardenEffect extends OneShotEffect { public NessianGameWardenEffect() { super(Outcome.DrawCard); - this.staticText = "look at the top X cards of your library, where X is the number of forests you control. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order"; + this.staticText = "look at the top X cards of your library, where X is the number of Forests you control. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order"; } public NessianGameWardenEffect(final NessianGameWardenEffect effect) { diff --git a/Mage.Sets/src/mage/cards/p/PendelhavenElder.java b/Mage.Sets/src/mage/cards/p/PendelhavenElder.java index f35e1bdf70..ea1ff6e889 100644 --- a/Mage.Sets/src/mage/cards/p/PendelhavenElder.java +++ b/Mage.Sets/src/mage/cards/p/PendelhavenElder.java @@ -52,6 +52,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; public class PendelhavenElder extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each 1/1 creature you control"); + static { filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, 1)); filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, 1)); @@ -59,14 +60,17 @@ public class PendelhavenElder extends CardImpl { } public PendelhavenElder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(1); this.toughness = new MageInt(1); // {tap}: Each 1/1 creature you control gets +1/+2 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 2, Duration.EndOfTurn, filter, false), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 2, Duration.EndOfTurn, filter, false) + .setText("Each 1/1 creature you control gets +1/+2 until end of turn."), + new TapSourceCost() + )); } public PendelhavenElder(final PendelhavenElder card) { diff --git a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java index 44d0bafbb6..1314189669 100644 --- a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java +++ b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java @@ -91,7 +91,7 @@ class PharikaExileEffect extends OneShotEffect { public PharikaExileEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Exile target creature card from a graveyard. It's owner creates a 1/1 black and green Snake enchantment creature token with deathtouch"; + staticText = "Exile target creature card from a graveyard. Its owner creates a 1/1 black and green Snake enchantment creature token with deathtouch"; } public PharikaExileEffect(final PharikaExileEffect effect) { diff --git a/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java b/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java index 181e72eae5..eaf69c3c93 100644 --- a/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java +++ b/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java @@ -29,19 +29,20 @@ package mage.cards.p; import java.util.UUID; import mage.Mana; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.mana.DynamicManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; /** * * @author fireshoes */ - public class PrismaticGeoscope extends CardImpl { public PrismaticGeoscope(UUID ownerId, CardSetInfo setInfo) { @@ -51,8 +52,13 @@ public class PrismaticGeoscope extends CardImpl { this.addAbility(new EntersBattlefieldTappedAbility()); // Domain — {T}: Add X mana in any combination of colors to your mana pool, where X is the number of basic land types among lands you control. - this.addAbility(new DynamicManaAbility(new Mana(0,0,0,0,0,0,1, 0), new DomainValue(), new TapSourceCost(), - "Add X mana in any combination of colors to your mana pool, where X is the number of basic land types among lands you control.")); + Ability ability = new DynamicManaAbility( + new Mana(0, 0, 0, 0, 0, 0, 1, 0), new DomainValue(), new TapSourceCost(), + "Add X mana in any combination of colors to your mana pool," + + " where X is the number of basic land types among lands you control." + ); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public PrismaticGeoscope(final PrismaticGeoscope card) { diff --git a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java index 9755ae63ac..437e494ceb 100644 --- a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java +++ b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; public class PropheticFlamespeaker extends CardImpl { public PropheticFlamespeaker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); @@ -87,7 +87,7 @@ class PropheticFlamespeakerExileEffect extends OneShotEffect { public PropheticFlamespeakerExileEffect() { super(Outcome.Detriment); - this.staticText = "Exile the top card of your library. You may play it this turn"; + this.staticText = "exile the top card of your library. You may play it this turn"; } public PropheticFlamespeakerExileEffect(final PropheticFlamespeakerExileEffect effect) { @@ -142,7 +142,7 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) && - objectId.equals(getTargetPointer().getFirst(game, source)); + return source.getControllerId().equals(affectedControllerId) + && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/r/Reiterate.java b/Mage.Sets/src/mage/cards/r/Reiterate.java index a2b8feeeba..867267f8f2 100644 --- a/Mage.Sets/src/mage/cards/r/Reiterate.java +++ b/Mage.Sets/src/mage/cards/r/Reiterate.java @@ -33,9 +33,7 @@ import mage.abilities.keyword.BuybackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterSpell; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.StaticFilters; import mage.target.TargetSpell; /** @@ -43,23 +41,15 @@ import mage.target.TargetSpell; * @author fireshoes */ public class Reiterate extends CardImpl { - - private static final FilterSpell filter = new FilterSpell(); - - static { - filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY))); - } public Reiterate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{R}"); // Buyback {3} this.addAbility(new BuybackAbility("{3}")); - + // Copy target instant or sorcery spell. You may choose new targets for the copy. - this.getSpellAbility().addTarget(new TargetSpell(filter)); + this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELL)); this.getSpellAbility().addEffect(new CopyTargetSpellEffect()); } diff --git a/Mage.Sets/src/mage/cards/r/RiptideChimera.java b/Mage.Sets/src/mage/cards/r/RiptideChimera.java index 487b25e6ed..a8cc3869ac 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideChimera.java +++ b/Mage.Sets/src/mage/cards/r/RiptideChimera.java @@ -48,14 +48,13 @@ import mage.filter.predicate.mageobject.CardTypePredicate; public class RiptideChimera extends CardImpl { private static final FilterControlledPermanent filter = new FilterControlledPermanent("an enchantment you control"); - + static { filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); } - - + public RiptideChimera(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.CHIMERA); this.power = new MageInt(3); @@ -65,7 +64,7 @@ public class RiptideChimera extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // At the beginning of your upkeep, return an enchantment you control to its owner's hand. Effect effect = new ReturnToHandChosenControlledPermanentEffect(filter, 1); - effect.setText("return an enchanment you control to its owner's hand"); + effect.setText("return an enchantment you control to its owner's hand"); this.addAbility(new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java index 32466b5951..5d59286f57 100644 --- a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java +++ b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java @@ -71,7 +71,7 @@ class RitualOfTheReturnedExileEffect extends OneShotEffect { public RitualOfTheReturnedExileEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "Exile target creature card from your graveyard. Create a black Zombie creature token with power equal to the exiled card's power and toughness equal to the exiled card's toughness"; + this.staticText = "Exile target creature card from your graveyard. Create a black Zombie creature token. Its power is equal to that card's power and its toughness is equal to that card's toughness."; } public RitualOfTheReturnedExileEffect(final RitualOfTheReturnedExileEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java b/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java index 4224b95321..e8cc9eae1a 100644 --- a/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java +++ b/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java @@ -42,16 +42,14 @@ import mage.constants.SubType; */ public class ScarwoodTreefolk extends CardImpl { - private static final String staticText = "{this} enters the battlefield tapped"; - public ScarwoodTreefolk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.TREEFOLK); this.power = new MageInt(3); this.toughness = new MageInt(5); // Scarwood Treefolk enters the battlefield tapped. - this.addAbility(new EntersBattlefieldAbility(new TapSourceEffect(), staticText)); + this.addAbility(new EntersBattlefieldAbility(new TapSourceEffect(), "tapped")); } public ScarwoodTreefolk(final ScarwoodTreefolk card) { diff --git a/Mage.Sets/src/mage/cards/s/ScreechingSliver.java b/Mage.Sets/src/mage/cards/s/ScreechingSliver.java index 410b3bb91d..6062928272 100644 --- a/Mage.Sets/src/mage/cards/s/ScreechingSliver.java +++ b/Mage.Sets/src/mage/cards/s/ScreechingSliver.java @@ -52,7 +52,7 @@ public class ScreechingSliver extends CardImpl { private static final FilterPermanent filter = new FilterPermanent(SubType.SLIVER, "All Slivers"); public ScreechingSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); @@ -63,7 +63,7 @@ public class ScreechingSliver extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, - filter, "All Sliver creatures have \"{T}: Target player puts the top card of his or her library into his or her graveyard.\""))); + filter, "All Slivers have \"{T}: Target player puts the top card of his or her library into his or her graveyard.\""))); } public ScreechingSliver(final ScreechingSliver card) { diff --git a/Mage.Sets/src/mage/cards/s/ScrybRanger.java b/Mage.Sets/src/mage/cards/s/ScrybRanger.java index 02046aa557..cf02647b4f 100644 --- a/Mage.Sets/src/mage/cards/s/ScrybRanger.java +++ b/Mage.Sets/src/mage/cards/s/ScrybRanger.java @@ -53,13 +53,14 @@ import mage.target.common.TargetCreaturePermanent; */ public class ScrybRanger extends CardImpl { - private static final FilterControlledLandPermanent filterForest = new FilterControlledLandPermanent("Forest"); + private static final FilterControlledLandPermanent filterForest = new FilterControlledLandPermanent("a Forest"); + static { filterForest.add(new SubtypePredicate(SubType.FOREST)); } public ScrybRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.FAERIE); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SetessanTactics.java b/Mage.Sets/src/mage/cards/s/SetessanTactics.java index 05a5d4b4c6..cee3c7f116 100644 --- a/Mage.Sets/src/mage/cards/s/SetessanTactics.java +++ b/Mage.Sets/src/mage/cards/s/SetessanTactics.java @@ -58,20 +58,19 @@ public class SetessanTactics extends CardImpl { } public SetessanTactics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Strive - Setessan Tactics costs G more to cast for each target beyond the first. this.addAbility(new StriveAbility("{G}")); // Until end of turn, any number of target creatures each get +1/+1 and gain "T: This creature fights another target creature." this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); - Effect effect = new BoostTargetEffect(1,1, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("Until end of turn, any number of target creatures each get +1/+1"); this.getSpellAbility().addEffect(effect); Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new FightTargetSourceEffect(), new TapSourceCost()); gainedAbility.addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn, - "and gain \"T: This creature fights another target creature.\"")); + "and gain \"{T}: This creature fights another target creature.\"")); } public SetessanTactics(final SetessanTactics card) { diff --git a/Mage.Sets/src/mage/cards/s/SidewinderSliver.java b/Mage.Sets/src/mage/cards/s/SidewinderSliver.java index a550eb520d..2feea699fc 100644 --- a/Mage.Sets/src/mage/cards/s/SidewinderSliver.java +++ b/Mage.Sets/src/mage/cards/s/SidewinderSliver.java @@ -48,20 +48,23 @@ import mage.filter.predicate.mageobject.SubtypePredicate; public class SidewinderSliver extends CardImpl { static final private FilterCreaturePermanent filter = new FilterCreaturePermanent("All Sliver creatures"); - - static{ + + static { filter.add(new SubtypePredicate(SubType.SLIVER)); } - + public SidewinderSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); // All Sliver creatures have flanking. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, false))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, false) + .setText("all Slivers have flanking") + )); } public SidewinderSliver(final SidewinderSliver card) { diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java index ff0a1baae8..a956b52b36 100644 --- a/Mage.Sets/src/mage/cards/s/SpellSwindle.java +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -69,7 +69,7 @@ class SpellSwindleEffect extends OneShotEffect { public SpellSwindleEffect() { super(Outcome.Detriment); staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " - + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool\""; + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool.\""; } public SpellSwindleEffect(final SpellSwindleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/Spirespine.java b/Mage.Sets/src/mage/cards/s/Spirespine.java index 056814ee38..84e2e02ffd 100644 --- a/Mage.Sets/src/mage/cards/s/Spirespine.java +++ b/Mage.Sets/src/mage/cards/s/Spirespine.java @@ -51,7 +51,7 @@ import mage.constants.Zone; public class Spirespine extends CardImpl { public Spirespine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(4); @@ -61,12 +61,12 @@ public class Spirespine extends CardImpl { this.addAbility(new BestowAbility(this, "{4}{G}")); // Spirespine blocks each turn if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BlocksIfAbleSourceEffect(Duration.WhileOnBattlefield))); - // Enchanted creature gets +4/+1 and blocks each turn if able. - Effect effect = new BoostEnchantedEffect(4,1, Duration.WhileOnBattlefield); + // Enchanted creature gets +4/+1 and blocks each combat if able. + Effect effect = new BoostEnchantedEffect(4, 1, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +4/+1"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); effect = new BlocksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA); - effect.setText("and blocks each turn if able"); + effect.setText("and blocks each combat if able"); ability.addEffect(effect); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java index eec83b174c..c62904dbd1 100644 --- a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java +++ b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java @@ -60,7 +60,7 @@ public class StormFleetAerialist extends CardImpl { // Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.instance, - "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/StranglingSoot.java b/Mage.Sets/src/mage/cards/s/StranglingSoot.java index a0d58fff08..e0d40c4eb8 100644 --- a/Mage.Sets/src/mage/cards/s/StranglingSoot.java +++ b/Mage.Sets/src/mage/cards/s/StranglingSoot.java @@ -45,7 +45,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class StranglingSoot extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with toughess 3 or less"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with toughness 3 or less"); static { filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, 4)); diff --git a/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java b/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java index a5499529a0..e5a2333fac 100644 --- a/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java +++ b/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java @@ -56,7 +56,7 @@ import mage.game.events.GameEvent.EventType; public class SwarmbornGiant extends CardImpl { public SwarmbornGiant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.GIANT); this.power = new MageInt(6); @@ -67,13 +67,13 @@ public class SwarmbornGiant extends CardImpl { // {4}{G}{G}: Monstrosity 2. this.addAbility(new MonstrosityAbility("{4}{G}{G}", 2)); - + // As long as Swarmborn Giant is monstrous, it has reach. Ability ability = new SimpleStaticAbility( Zone.BATTLEFIELD, new ConditionalContinuousEffect(new GainAbilitySourceEffect(ReachAbility.getInstance(), Duration.WhileOnBattlefield), - MonstrousCondition.instance, - "As long as {this} is monstrous, it has reach")); + MonstrousCondition.instance, + "As long as {this} is monstrous, it has reach")); this.addAbility(ability); } @@ -118,6 +118,6 @@ class SwarmbornGiantTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you're dealt combat damage, " + super.getRule(); + return "When you're dealt combat damage, " + super.getRule(); } } diff --git a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java index 128d109df8..87525a45d8 100644 --- a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java +++ b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java @@ -72,9 +72,6 @@ public class VesuvanShapeshifter extends CardImpl { this.power = new MageInt(0); this.toughness = new MageInt(0); - // Morph {1}{U} - this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}"))); - // As Vesuvan Shapeshifter turned face up, may choose another creature. If you do, until Vesuvan Shapeshifter is turned face down, it becomes a copy of that creature Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new AsTurnedFaceUpEffect(new VesuvanShapeshifterEffect(), false)); ability.setWorksFaceDown(true); @@ -91,6 +88,9 @@ public class VesuvanShapeshifter extends CardImpl { effect = new VesuvanShapeshifterFaceDownEffect(); ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, true); this.addAbility(ability); + + // Morph {1}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}"))); } public VesuvanShapeshifter(final VesuvanShapeshifter card) { diff --git a/Mage.Sets/src/mage/cards/w/WheelOfFate.java b/Mage.Sets/src/mage/cards/w/WheelOfFate.java index fa76391cce..4dd0bd1ae0 100644 --- a/Mage.Sets/src/mage/cards/w/WheelOfFate.java +++ b/Mage.Sets/src/mage/cards/w/WheelOfFate.java @@ -43,7 +43,7 @@ import mage.constants.CardType; public class WheelOfFate extends CardImpl { public WheelOfFate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},""); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); this.color.setRed(true); @@ -51,7 +51,7 @@ public class WheelOfFate extends CardImpl { this.addAbility(new SuspendAbility(4, new ManaCostsImpl("{1}{R}"), this)); // Each player discards his or her hand, then draws seven cards. this.getSpellAbility().addEffect(new DiscardHandAllEffect()); - this.getSpellAbility().addEffect(new DrawCardAllEffect(7)); + this.getSpellAbility().addEffect(new DrawCardAllEffect(7).setText(", then draws seven cards")); } public WheelOfFate(final WheelOfFate card) { diff --git a/Mage.Sets/src/mage/cards/w/WormwoodDryad.java b/Mage.Sets/src/mage/cards/w/WormwoodDryad.java index b82f938a24..3751876afd 100644 --- a/Mage.Sets/src/mage/cards/w/WormwoodDryad.java +++ b/Mage.Sets/src/mage/cards/w/WormwoodDryad.java @@ -50,7 +50,7 @@ import mage.constants.Zone; public class WormwoodDryad extends CardImpl { public WormwoodDryad(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.DRYAD); this.power = new MageInt(3); this.toughness = new MageInt(1); @@ -58,13 +58,13 @@ public class WormwoodDryad extends CardImpl { // {G}: Wormwood Dryad gains forestwalk until end of turn and deals 1 damage to you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn), new ManaCostsImpl("{G}")); - ability.addEffect(new DamageControllerEffect(1)); + ability.addEffect(new DamageControllerEffect(1).setText("and deals 1 damage to you")); this.addAbility(ability); // {B}: Wormwood Dryad gains swampwalk until end of turn and deals 1 damage to you. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new SwampwalkAbility(false), Duration.EndOfTurn), new ManaCostsImpl("{B}")); - ability.addEffect(new DamageControllerEffect(1)); + ability.addEffect(new DamageControllerEffect(1).setText("and deals 1 damage to you")); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java index 3d474b252a..9fc545d982 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java @@ -59,7 +59,7 @@ public class IsStepCondition implements Condition { public String toString() { StringBuilder sb = new StringBuilder("during "); if (onlyDuringYourSteps) { - sb.append("your "); + sb.append("your ").append(phaseStep.getStepText()); } else if (phaseStep == PhaseStep.UPKEEP) { sb.append("any upkeep step"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java index 14803dfc47..633d8a0bd3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java @@ -63,7 +63,9 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { staticText = "Add " + (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "") + " mana " - + (oneChoice ? "of any one color" : "in any combination of colors") + + (oneChoice ? "of any" + + (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one") + + " color" : "in any combination of colors") + " to your mana pool. " + manaBuilder.getRule(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 56c2b43515..a6c556be36 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -277,14 +277,14 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { if (tapped && !attacking) { sb.append("tapped "); } - sb.append("token"); + sb.append("token that's a copy of target creature"); } else { sb.append(number); sb.append(" "); if (tapped && !attacking) { sb.append("tapped "); } - sb.append("tokens"); + sb.append("tokens that are copies of target creature"); } if (attacking) { sb.append(" that are"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java index a1167c7f02..aa07e5bdd0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.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.abilities.effects.common; import mage.constants.Duration; @@ -45,23 +44,23 @@ public class PreventDamageToTargetEffect extends PreventionEffectImpl { public PreventDamageToTargetEffect(Duration duration) { this(duration, false); } - + public PreventDamageToTargetEffect(Duration duration, boolean onlyCombat) { this(duration, Integer.MAX_VALUE, onlyCombat); } - + public PreventDamageToTargetEffect(Duration duration, int amount) { this(duration, amount, false); } - + public PreventDamageToTargetEffect(Duration duration, int amount, boolean onlyCombat) { super(duration, amount, onlyCombat); } - + public PreventDamageToTargetEffect(Duration duration, boolean onlyCombat, boolean consumable, DynamicValue amountToPreventDynamic) { super(duration, 0, onlyCombat, consumable, amountToPreventDynamic); } - + public PreventDamageToTargetEffect(final PreventDamageToTargetEffect effect) { super(effect); } @@ -83,9 +82,9 @@ public class PreventDamageToTargetEffect extends PreventionEffectImpl { } StringBuilder sb = new StringBuilder(); if (amountToPrevent == Integer.MAX_VALUE) { - sb.append("Prevent all damage that would be dealt to target "); + sb.append("prevent all damage that would be dealt to target "); } else { - sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to target "); + sb.append("prevent the next ").append(amountToPrevent).append(" damage that would be dealt to target "); } sb.append(mode.getTargets().get(0).getTargetName()); if (!duration.toString().isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java index 27b2e0c149..717a3426b5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java @@ -75,7 +75,7 @@ public class PutTopCardOfLibraryIntoGraveTargetEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("Target player puts the top "); + StringBuilder sb = new StringBuilder("target player puts the top "); if (numberCards.toString().equals("1")) { sb.append(" card"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java index cca02db55a..08ca0c506f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java @@ -80,6 +80,6 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "tap all " + filter.getMessage() + " target " + mode.getTargets().get(0).getMessage() + " controls"; + return "tap all " + filter.toString() + " target " + mode.getTargets().get(0).getMessage() + " controls"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java index 988c75ff76..c7dd2cf8c2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.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.abilities.effects.common.combat; import mage.abilities.Ability; @@ -38,12 +37,11 @@ import mage.game.permanent.Permanent; /** * @author LevelX2 */ - public class BlocksIfAbleAttachedEffect extends RequirementEffect { public BlocksIfAbleAttachedEffect(Duration duration, AttachmentType attachmentType) { super(duration); - this.staticText = attachmentType.verb() + " creature blocks each turn if able"; + this.staticText = attachmentType.verb() + " creature blocks each combat if able"; } public BlocksIfAbleAttachedEffect(final BlocksIfAbleAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java index 97e46cc571..1fda34c497 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.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.abilities.effects.common.combat; import mage.abilities.Ability; @@ -39,7 +38,6 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ - public class BlocksIfAbleSourceEffect extends RequirementEffect { public BlocksIfAbleSourceEffect(Duration duration) { @@ -78,7 +76,7 @@ public class BlocksIfAbleSourceEffect extends RequirementEffect { @Override public String getText(Mode mode) { - return "{this} blocks each turn if able."; + return "{this} blocks each combat if able."; } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java index 7f1c8b1de7..c03f59a035 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.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.abilities.effects.common.combat; import java.util.UUID; @@ -35,35 +34,32 @@ import mage.constants.Duration; import mage.game.Game; import mage.game.permanent.Permanent; - /** * !! This effect does only support one target. * * * http://tappedout.net/mtg-questions/must-be-blocked-if-able-effect-makes-other-attacking-creatures-essentially-unblockable/ * - * When you Declare Blockers, you choose an arrangement for your blockers, - * then check to see if there are any restrictions or requirements. + * When you Declare Blockers, you choose an arrangement for your blockers, then + * check to see if there are any restrictions or requirements. * - * If any restrictions are violated, the block is illegal. (For example, - * trying to block with Sightless Ghoul) - * If any requirements are violated, the least possible number of requirements - * must be violated, otherwise the block is illegal. (For example, your opponent - * control two creatures that he has cast Deadly Allure on, but you control only - * one creature. Blocking either one will violate a requirement, "This creature - * must be blocked this turn if able", but it will also violate the least - * possible number of requirements, thus it is legal.) - * If the block is illegal, the game state backs up and you declare blockers - * again. (Note that while you can, in some cases, circumvent requirements - * such as "This creature must be blocked" or "This creature must block - * any attacking creature" you can never circumvent restrictions: "This creature - * can't block" or "Only one creature may block this turn.") - * Because you declare ALL your blockers at once, THEN check for - * restrictions/requirements, you may block Deadly Allure'd creatures - * with only one creature, if you choose. - * This still works with Lure: This card sets up a requirement that ALL - * creatures must block it if able. Any block that violates more than - * the minimum number of requirements is still illegal. + * If any restrictions are violated, the block is illegal. (For example, trying + * to block with Sightless Ghoul) If any requirements are violated, the least + * possible number of requirements must be violated, otherwise the block is + * illegal. (For example, your opponent control two creatures that he has cast + * Deadly Allure on, but you control only one creature. Blocking either one will + * violate a requirement, "This creature must be blocked this turn if able", but + * it will also violate the least possible number of requirements, thus it is + * legal.) If the block is illegal, the game state backs up and you declare + * blockers again. (Note that while you can, in some cases, circumvent + * requirements such as "This creature must be blocked" or "This creature must + * block any attacking creature" you can never circumvent restrictions: "This + * creature can't block" or "Only one creature may block this turn.") Because + * you declare ALL your blockers at once, THEN check for + * restrictions/requirements, you may block Deadly Allure'd creatures with only + * one creature, if you choose. This still works with Lure: This card sets up a + * requirement that ALL creatures must block it if able. Any block that violates + * more than the minimum number of requirements is still illegal. * * @author LevelX2 */ @@ -75,7 +71,7 @@ public class MustBeBlockedByAtLeastOneTargetEffect extends RequirementEffect { public MustBeBlockedByAtLeastOneTargetEffect(Duration duration) { super(duration); - staticText = "Target creature must be blocked this turn if able"; + staticText = "target creature must be blocked this turn if able"; } public MustBeBlockedByAtLeastOneTargetEffect(final MustBeBlockedByAtLeastOneTargetEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java index 797a5edcf9..5be2bb16f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java @@ -129,7 +129,7 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect @Override public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); - sb.append("Search ").append(this.searchWhatText); + sb.append("search ").append(this.searchWhatText); sb.append(" graveyard, hand, and library for "); sb.append(this.searchForText); sb.append(" and exile them. Then that player shuffles his or her library"); diff --git a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java index d8df61ca87..ce887d86e0 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import mage.abilities.TriggeredAbilityImpl; @@ -11,12 +10,9 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; - /** * @author Plopman */ - - public class FlankingAbility extends TriggeredAbilityImpl { public FlankingAbility() { @@ -37,9 +33,8 @@ public class FlankingAbility extends TriggeredAbilityImpl { if (event.getTargetId().equals(this.getSourceId())) { Permanent permanent = game.getPermanent(event.getSourceId()); if (permanent != null) { - boolean hasFlankingAbility = - permanent.getAbilities().stream().anyMatch(ability -> ability instanceof FlankingAbility); - + boolean hasFlankingAbility + = permanent.getAbilities().stream().anyMatch(ability -> ability instanceof FlankingAbility); if (!hasFlankingAbility) { for (Effect effect : this.getEffects()) { @@ -54,7 +49,7 @@ public class FlankingAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Flanking"; + return "flanking"; } @Override @@ -62,5 +57,4 @@ public class FlankingAbility extends TriggeredAbilityImpl { return new FlankingAbility(this); } - } diff --git a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java index 557236e5ca..dfe545198c 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java @@ -138,7 +138,11 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost break; } } - sb.append(morphCosts.getText()).append(' '); + sb.append(morphCosts.getText()); + if (!(morphCosts.get(morphCosts.size() - 1) instanceof ManaCosts)) { + sb.append('.'); + } + sb.append(' '); if (megamorph) { sb.append(REMINDER_TEXT_MEGA); } else { diff --git a/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java b/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java index 29fde94fe9..b35919daa5 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java @@ -46,7 +46,7 @@ public class RampageAbility extends BecomesBlockedTriggeredAbility { public RampageAbility(int amount) { super(null, false); - rule = "rampage " + amount + "(Whenever this creature becomes blocked, it gets +" + rule = "rampage " + amount + " (Whenever this creature becomes blocked, it gets +" + amount + "/+" + amount + " until end of turn for each creature blocking it beyond the first.)"; RampageValue rv = new RampageValue(amount); this.addEffect(new BoostSourceEffect(rv, rv, Duration.EndOfTurn, true)); diff --git a/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java b/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java index 667e4aa22f..2573570731 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java @@ -12,10 +12,12 @@ import mage.game.permanent.Permanent; /** * "Shadow" keyword + * * @author Loki */ public class ShadowAbility extends EvasionAbility implements MageSingleton { - private static final ShadowAbility instance = new ShadowAbility(); + + private static final ShadowAbility instance = new ShadowAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -31,7 +33,7 @@ public class ShadowAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Shadow (This creature can block or be blocked by only creatures with shadow.)"; + return "shadow (This creature can block or be blocked by only creatures with shadow.)"; } @Override diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 60c7d931a3..84695fd94f 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -59,7 +59,7 @@ public final class StaticFilters { public static final FilterCreaturePermanent FILTER_PERMANENT_A_CREATURE = new FilterCreaturePermanent("a creature"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES = new FilterCreaturePermanent("creatures"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_GOBLINS = new FilterCreaturePermanent(SubType.GOBLIN, "Goblin creatures"); - public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "Sliver creatures"); + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "all Sliver creatures"); public static final FilterPlaneswalkerPermanent FILTER_PERMANENT_PLANESWALKER = new FilterPlaneswalkerPermanent(); public static final FilterPermanent FILTER_PERMANENT_NON_LAND = new FilterNonlandPermanent(); From a7ff929e6388e8b2026285699c870c3ac397709e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 18:43:51 -0400 Subject: [PATCH 012/164] fixed Reveille Squad trigger --- Mage.Sets/src/mage/cards/r/ReveilleSquad.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/r/ReveilleSquad.java b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java index 3c7aa5d44c..fc79bb682b 100644 --- a/Mage.Sets/src/mage/cards/r/ReveilleSquad.java +++ b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java @@ -92,7 +92,12 @@ class ReveilleSquadTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getCombat().getDefenders().contains(controllerId); + for (UUID attackerId : game.getCombat().getAttackers()) { + if (game.getCombat().getDefenderId(attackerId).equals(controllerId)) { + return true; + } + } + return false; } @Override From be725ce0129b7299495be6a54f0acdfddc99a0ad Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:26:54 +0200 Subject: [PATCH 013/164] Implemented Chaos Moon --- Mage.Sets/src/mage/cards/c/ChaosMoon.java | 224 ++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChaosMoon.java diff --git a/Mage.Sets/src/mage/cards/c/ChaosMoon.java b/Mage.Sets/src/mage/cards/c/ChaosMoon.java new file mode 100644 index 0000000000..9db40417ac --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosMoon.java @@ -0,0 +1,224 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.MageObject; +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.TapForManaAllTriggeredManaAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AddManaToManaPoolTargetControllerEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ManaEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.mana.DelayedTriggeredManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class ChaosMoon extends CardImpl { + + public ChaosMoon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + + + // At the beginning of each upkeep, count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} to his or her mana pool (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ChaosMoonEffect(), TargetController.ANY, false)); + } + + public ChaosMoon(final ChaosMoon card) { + super(card); + } + + @Override + public ChaosMoon copy() { + return new ChaosMoon(this); + } +} + +class ChaosMoonEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public ChaosMoonEffect() { + super(Outcome.Neutral); + this.staticText = "count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} to his or her mana pool (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type"; + } + + public ChaosMoonEffect(final ChaosMoonEffect effect) { + super(effect); + } + + @Override + public ChaosMoonEffect copy() { + return new ChaosMoonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + int permanentsInPlay = new PermanentsOnBattlefieldCount().calculate(game, source, null); + // Odd + if (permanentsInPlay % 2 != 0) { + game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source); + new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source); + } + // Even + else { + game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source); + game.addEffect(new ChaosMoonEvenReplacementEffect(), source); + } + return true; + } + return false; + } +} + +class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility { + + private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); + + static { + filter.add(new SubtypePredicate(SubType.MOUNTAIN)); + } + + public ChaosMoonOddTriggeredAbility() { + super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.R), "his or her"), Duration.EndOfTurn, false); + this.usesStack = false; + } + + public ChaosMoonOddTriggeredAbility(ChaosMoonOddTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent land = game.getPermanent(event.getTargetId()); + if (land != null && filter.match(land, game)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(land.getControllerId())); + } + return true; + } + return false; + } + + @Override + public ChaosMoonOddTriggeredAbility copy() { + return new ChaosMoonOddTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Until end of turn, whenever a player taps a Mountain for mana, that player adds {R} to his or her mana pool"; + } +} + +class ChaosMoonEvenReplacementEffect extends ReplacementEffectImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); + + static { + filter.add(new SubtypePredicate(SubType.MOUNTAIN)); + } + + ChaosMoonEvenReplacementEffect() { + super(Duration.EndOfTurn, Outcome.Neutral); + staticText = "Until end of turn, if a Mountain is tapped for mana, it produces colorless mana instead of any other type."; + } + + ChaosMoonEvenReplacementEffect(final ChaosMoonEvenReplacementEffect effect) { + super(effect); + } + + @Override + public ChaosMoonEvenReplacementEffect copy() { + return new ChaosMoonEvenReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + mana.setToMana(Mana.ColorlessMana(mana.count())); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject mageObject = game.getObject(event.getSourceId()); + if (mageObject != null && mageObject.isLand()) { + Permanent land = game.getPermanent(event.getSourceId()); + return land != null && filter.match(land, game); + } + return false; + } +} From d762223aea9db01d22bffa20765be5fe7b5c879a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:26:59 +0200 Subject: [PATCH 014/164] Implemented Chaos Moon --- Mage.Sets/src/mage/sets/IceAge.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 9c28934691..ab2a279101 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -61,7 +61,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Arenson's Aura", 227, Rarity.COMMON, mage.cards.a.ArensonsAura.class)); cards.add(new SetCardInfo("Armor of Faith", 228, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class)); cards.add(new SetCardInfo("Arnjlot's Ascent", 57, Rarity.COMMON, mage.cards.a.ArnjlotsAscent.class)); - cards.add(new SetCardInfo("Ashen Ghoul", 2, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); + cards.add(new SetCardInfo("Ashen Ghoul", 2, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); cards.add(new SetCardInfo("Aurochs", 113, Rarity.COMMON, mage.cards.a.Aurochs.class)); cards.add(new SetCardInfo("Avalanche", 171, Rarity.UNCOMMON, mage.cards.a.Avalanche.class)); cards.add(new SetCardInfo("Balduvian Barbarians", 172, Rarity.COMMON, mage.cards.b.BalduvianBarbarians.class)); @@ -85,6 +85,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Caribou Range", 235, Rarity.RARE, mage.cards.c.CaribouRange.class)); cards.add(new SetCardInfo("Celestial Sword", 289, Rarity.RARE, mage.cards.c.CelestialSword.class)); cards.add(new SetCardInfo("Centaur Archer", 360, Rarity.UNCOMMON, mage.cards.c.CentaurArcher.class)); + cards.add(new SetCardInfo("Chaos Moon", 179, Rarity.RARE, mage.cards.c.ChaosMoon.class)); cards.add(new SetCardInfo("Chub Toad", 117, Rarity.COMMON, mage.cards.c.ChubToad.class)); cards.add(new SetCardInfo("Circle of Protection: Black", 236, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class)); cards.add(new SetCardInfo("Circle of Protection: Blue", 237, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlue.class)); @@ -108,7 +109,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Disenchant", 244, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Drift of the Dead", 11, Rarity.UNCOMMON, mage.cards.d.DriftOfTheDead.class)); cards.add(new SetCardInfo("Dwarven Armory", 182, Rarity.RARE, mage.cards.d.DwarvenArmory.class)); - cards.add(new SetCardInfo("Earthlink", 363, Rarity.RARE, mage.cards.e.Earthlink.class)); + cards.add(new SetCardInfo("Earthlink", 363, Rarity.RARE, mage.cards.e.Earthlink.class)); cards.add(new SetCardInfo("Elder Druid", 120, Rarity.RARE, mage.cards.e.ElderDruid.class)); cards.add(new SetCardInfo("Elemental Augury", 364, Rarity.RARE, mage.cards.e.ElementalAugury.class)); cards.add(new SetCardInfo("Enduring Renewal", 247, Rarity.RARE, mage.cards.e.EnduringRenewal.class)); @@ -231,7 +232,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Orcish Healer", 208, Rarity.UNCOMMON, mage.cards.o.OrcishHealer.class)); cards.add(new SetCardInfo("Orcish Librarian", 209, Rarity.RARE, mage.cards.o.OrcishLibrarian.class)); cards.add(new SetCardInfo("Orcish Lumberjack", 210, Rarity.COMMON, mage.cards.o.OrcishLumberjack.class)); - cards.add(new SetCardInfo("Orcish Squatters", 211, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); + cards.add(new SetCardInfo("Orcish Squatters", 211, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 269, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 270, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); cards.add(new SetCardInfo("Pale Bears", 144, Rarity.RARE, mage.cards.p.PaleBears.class)); @@ -270,14 +271,14 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Silver Erne", 98, Rarity.UNCOMMON, mage.cards.s.SilverErne.class)); cards.add(new SetCardInfo("Skeleton Ship", 379, Rarity.RARE, mage.cards.s.SkeletonShip.class)); cards.add(new SetCardInfo("Skull Catapult", 311, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); - cards.add(new SetCardInfo("Snow Fortress", 312, Rarity.RARE, mage.cards.s.SnowFortress.class)); + cards.add(new SetCardInfo("Snow Fortress", 312, Rarity.RARE, mage.cards.s.SnowFortress.class)); cards.add(new SetCardInfo("Snow-Covered Forest", 347, Rarity.COMMON, mage.cards.s.SnowCoveredForest.class)); cards.add(new SetCardInfo("Snow-Covered Island", 348, Rarity.COMMON, mage.cards.s.SnowCoveredIsland.class)); cards.add(new SetCardInfo("Snow-Covered Mountain", 349, Rarity.COMMON, mage.cards.s.SnowCoveredMountain.class)); cards.add(new SetCardInfo("Snow-Covered Plains", 350, Rarity.COMMON, mage.cards.s.SnowCoveredPlains.class)); cards.add(new SetCardInfo("Snow-Covered Swamp", 351, Rarity.COMMON, mage.cards.s.SnowCoveredSwamp.class)); cards.add(new SetCardInfo("Snow Hound", 277, Rarity.UNCOMMON, mage.cards.s.SnowHound.class)); - cards.add(new SetCardInfo("Soldevi Golem", 313, Rarity.RARE, mage.cards.s.SoldeviGolem.class)); + cards.add(new SetCardInfo("Soldevi Golem", 313, Rarity.RARE, mage.cards.s.SoldeviGolem.class)); cards.add(new SetCardInfo("Soldevi Machinist", 102, Rarity.UNCOMMON, mage.cards.s.SoldeviMachinist.class)); cards.add(new SetCardInfo("Soldevi Simulacrum", 314, Rarity.UNCOMMON, mage.cards.s.SoldeviSimulacrum.class)); cards.add(new SetCardInfo("Songs of the Damned", 48, Rarity.COMMON, mage.cards.s.SongsOfTheDamned.class)); From 39ca775710807d44065630e8efdf2e52a3da990e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:28:59 +0200 Subject: [PATCH 015/164] Implemented Pale Moon --- Mage.Sets/src/mage/cards/p/PaleMoon.java | 117 +++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PaleMoon.java diff --git a/Mage.Sets/src/mage/cards/p/PaleMoon.java b/Mage.Sets/src/mage/cards/p/PaleMoon.java new file mode 100644 index 0000000000..70548af74f --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PaleMoon.java @@ -0,0 +1,117 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author L_J + */ +public class PaleMoon extends CardImpl { + + public PaleMoon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + + // Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type. + this.getSpellAbility().addEffect(new PaleMoonReplacementEffect()); + } + + public PaleMoon(final PaleMoon card) { + super(card); + } + + @Override + public PaleMoon copy() { + return new PaleMoon(this); + } +} + +class PaleMoonReplacementEffect extends ReplacementEffectImpl { + + private static final FilterLandPermanent filter = FilterLandPermanent.nonbasicLands(); + + PaleMoonReplacementEffect() { + super(Duration.EndOfTurn, Outcome.Neutral); + staticText = "Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type"; + } + + PaleMoonReplacementEffect(final PaleMoonReplacementEffect effect) { + super(effect); + } + + @Override + public PaleMoonReplacementEffect copy() { + return new PaleMoonReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + mana.setToMana(Mana.ColorlessMana(mana.count())); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject mageObject = game.getObject(event.getSourceId()); + if (mageObject != null && mageObject.isLand()) { + Permanent land = game.getPermanent(event.getSourceId()); + return land != null && filter.match(land, game); + } + return false; + } +} From 6758997a5b403cd18a5573a20c90fe1ad4c6edc5 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:29:14 +0200 Subject: [PATCH 016/164] Implemented Pale Moon --- Mage.Sets/src/mage/sets/Nemesis.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Nemesis.java b/Mage.Sets/src/mage/sets/Nemesis.java index 26de845697..b8225ffd6a 100644 --- a/Mage.Sets/src/mage/sets/Nemesis.java +++ b/Mage.Sets/src/mage/sets/Nemesis.java @@ -118,6 +118,7 @@ public class Nemesis extends ExpansionSet { cards.add(new SetCardInfo("Oraxid", 35, Rarity.COMMON, mage.cards.o.Oraxid.class)); cards.add(new SetCardInfo("Overlaid Terrain", 108, Rarity.RARE, mage.cards.o.OverlaidTerrain.class)); cards.add(new SetCardInfo("Pack Hunt", 109, Rarity.RARE, mage.cards.p.PackHunt.class)); + cards.add(new SetCardInfo("Pale Moon", 36, Rarity.RARE, mage.cards.p.PaleMoon.class)); cards.add(new SetCardInfo("Parallax Dementia", 62, Rarity.COMMON, mage.cards.p.ParallaxDementia.class)); cards.add(new SetCardInfo("Parallax Inhibitor", 134, Rarity.RARE, mage.cards.p.ParallaxInhibitor.class)); cards.add(new SetCardInfo("Parallax Nexus", 63, Rarity.RARE, mage.cards.p.ParallaxNexus.class)); From 4e0af7271da62c63d452fc79601e18f23a429982 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:31:03 +0200 Subject: [PATCH 017/164] Implemented Deep Water --- Mage.Sets/src/mage/cards/d/DeepWater.java | 120 ++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeepWater.java diff --git a/Mage.Sets/src/mage/cards/d/DeepWater.java b/Mage.Sets/src/mage/cards/d/DeepWater.java new file mode 100644 index 0000000000..d4aebc95fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeepWater.java @@ -0,0 +1,120 @@ +/* + * 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.d; + +import java.util.UUID; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +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.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author L_J + */ +public class DeepWater extends CardImpl { + + public DeepWater(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}"); + + // {U}: Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DeepWaterReplacementEffect(), new ManaCostsImpl("{U}")); + this.addAbility(ability); + } + + public DeepWater(final DeepWater card) { + super(card); + } + + @Override + public DeepWater copy() { + return new DeepWater(this); + } +} + +class DeepWaterReplacementEffect extends ReplacementEffectImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + DeepWaterReplacementEffect() { + super(Duration.EndOfTurn, Outcome.Neutral); + staticText = "Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type"; + } + + DeepWaterReplacementEffect(final DeepWaterReplacementEffect effect) { + super(effect); + } + + @Override + public DeepWaterReplacementEffect copy() { + return new DeepWaterReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + mana.setToMana(Mana.BlueMana(mana.count())); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject mageObject = game.getObject(event.getSourceId()); + if (mageObject != null && mageObject.isLand()) { + Permanent land = game.getPermanent(event.getSourceId()); + return land != null && filter.match(land, game); + } + return false; + } +} From 7d5e57913c93deb63b8712671ac09ce3e6d64d3f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 20:31:12 +0200 Subject: [PATCH 018/164] Implemented Deep Water --- Mage.Sets/src/mage/sets/TheDark.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/TheDark.java b/Mage.Sets/src/mage/sets/TheDark.java index bb52a5f4cb..bacad0e06f 100644 --- a/Mage.Sets/src/mage/sets/TheDark.java +++ b/Mage.Sets/src/mage/sets/TheDark.java @@ -72,6 +72,7 @@ public class TheDark extends ExpansionSet { cards.add(new SetCardInfo("Coal Golem", 96, Rarity.UNCOMMON, mage.cards.c.CoalGolem.class)); cards.add(new SetCardInfo("Dance of Many", 21, Rarity.RARE, mage.cards.d.DanceOfMany.class)); cards.add(new SetCardInfo("Dark Heart of the Wood", 117, Rarity.COMMON, mage.cards.d.DarkHeartOfTheWood.class)); + cards.add(new SetCardInfo("Deep Water", 22, Rarity.COMMON, mage.cards.d.DeepWater.class)); cards.add(new SetCardInfo("Diabolic Machine", 98, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class)); cards.add(new SetCardInfo("Drowned", 23, Rarity.COMMON, mage.cards.d.Drowned.class)); cards.add(new SetCardInfo("Dust to Dust", 78, Rarity.COMMON, mage.cards.d.DustToDust.class)); From 6d80d5a11b3de6b46a5ccf602e8f8f660efbf833 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 21:42:04 +0200 Subject: [PATCH 019/164] Implemented Skullscorch --- Mage.Sets/src/mage/cards/s/Skullscorch.java | 114 ++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Skullscorch.java diff --git a/Mage.Sets/src/mage/cards/s/Skullscorch.java b/Mage.Sets/src/mage/cards/s/Skullscorch.java new file mode 100644 index 0000000000..733f936b02 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Skullscorch.java @@ -0,0 +1,114 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author L_J (based on code by dustinconrad) + */ +public class Skullscorch extends CardImpl { + + public Skullscorch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}{R}"); + + // Target player discards two cards at random unless that player has Skullscorch deal 4 damage to him or her. + this.getSpellAbility().addEffect(new SkullscorchDiscardEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public Skullscorch(final Skullscorch card) { + super(card); + } + + @Override + public Skullscorch copy() { + return new Skullscorch(this); + } +} + +class SkullscorchDiscardEffect extends OneShotEffect { + + public SkullscorchDiscardEffect() { + super(Outcome.DrawCard); + staticText = "Target player discards two cards at random unless that player has {source} deal 4 damage to him or her"; + } + + public SkullscorchDiscardEffect(final SkullscorchDiscardEffect effect) { + super(effect); + } + + @Override + public SkullscorchDiscardEffect copy() { + return new SkullscorchDiscardEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + StackObject spell = null; + for(StackObject object : game.getStack()){ + if(object instanceof Spell && object.getSourceId().equals(source.getSourceId())){ + spell = object; + } + } + if(spell != null){ + boolean discardCards = true; + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + if (player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 4 damage to you?", source, game)){ + discardCards = false; + player.damage(4, source.getSourceId(), game, false, true); + game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 4 to him or her"); + } + if (discardCards) { + player.discard(2, true, source, game); + } + } + return discardCards; + } + return false; + } + +} From 43da0781d87e9ab2c6b8987cf4c965cf8e80a293 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 21:42:16 +0200 Subject: [PATCH 020/164] Implemented Skullscorch --- Mage.Sets/src/mage/sets/Torment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Torment.java b/Mage.Sets/src/mage/sets/Torment.java index 417758cde8..b78a8465c6 100644 --- a/Mage.Sets/src/mage/sets/Torment.java +++ b/Mage.Sets/src/mage/sets/Torment.java @@ -159,6 +159,7 @@ public class Torment extends ExpansionSet { cards.add(new SetCardInfo("Shade's Form", 81, Rarity.COMMON, mage.cards.s.ShadesForm.class)); cards.add(new SetCardInfo("Shambling Swarm", 82, Rarity.RARE, mage.cards.s.ShamblingSwarm.class)); cards.add(new SetCardInfo("Sickening Dreams", 83, Rarity.UNCOMMON, mage.cards.s.SickeningDreams.class)); + cards.add(new SetCardInfo("Skullscorch", 114, Rarity.RARE, mage.cards.s.Skullscorch.class)); cards.add(new SetCardInfo("Skywing Aven", 47, Rarity.COMMON, mage.cards.s.SkywingAven.class)); cards.add(new SetCardInfo("Slithery Stalker", 84, Rarity.UNCOMMON, mage.cards.s.SlitheryStalker.class)); cards.add(new SetCardInfo("Sonic Seizure", 115, Rarity.COMMON, mage.cards.s.SonicSeizure.class)); From d4abd011fafc7fd9e01c926ad4d1ff96a534587a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 23:08:21 +0200 Subject: [PATCH 021/164] Implemented Hypnox --- Mage.Sets/src/mage/cards/h/Hypnox.java | 149 +++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/Hypnox.java diff --git a/Mage.Sets/src/mage/cards/h/Hypnox.java b/Mage.Sets/src/mage/cards/h/Hypnox.java new file mode 100644 index 0000000000..c5e78cce38 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/Hypnox.java @@ -0,0 +1,149 @@ +/* + * 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.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.condition.common.CastFromHandSourceCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +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.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.watchers.common.CastFromHandWatcher; + +/** + * + * @author L_J + */ +public class Hypnox extends CardImpl { + + public Hypnox(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{8}{B}{B}{B}"); + this.subtype.add(SubType.NIGHTMARE); + this.subtype.add(SubType.HORROR); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Hypnox enters the battlefield, if you cast it from your hand, exile all cards from target opponent's hand. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new HypnoxExileEffect()); + ability.addTarget(new TargetOpponent()); + this.addAbility(new ConditionalTriggeredAbility(ability, CastFromHandSourceCondition.instance, + "When {this} enters the battlefield, if you cast it from your hand, exile all cards from target opponent's hand."), new CastFromHandWatcher()); + + // When Hypnox leaves the battlefield, return the exiled cards to their owner's hand. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new HypnoxReturnEffect(), false)); + } + + public Hypnox(final Hypnox card) { + super(card); + } + + @Override + public Hypnox copy() { + return new Hypnox(this); + } +} + +class HypnoxExileEffect extends OneShotEffect { + HypnoxExileEffect() { + super(Outcome.Exile); + staticText = "Exile all cards from target opponent's hand"; + } + + HypnoxExileEffect(final HypnoxExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + for (UUID cid : player.getHand().copy()) { + Card c = game.getCard(cid); + if (c != null) { + c.moveToExile(source.getSourceId(), "Hypnox", source.getSourceId(), game); + } + } + return true; + } + return false; + } + + @Override + public HypnoxExileEffect copy() { + return new HypnoxExileEffect(this); + } + + } + +class HypnoxReturnEffect extends OneShotEffect { + + public HypnoxReturnEffect() { + super(Outcome.ReturnToHand); + this.staticText = "return the exiled cards to their owner's hand"; + } + + public HypnoxReturnEffect(final HypnoxReturnEffect effect) { + super(effect); + } + + @Override + public HypnoxReturnEffect copy() { + return new HypnoxReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + ExileZone exZone = game.getExile().getExileZone(source.getSourceId()); + if (exZone != null) { + return controller.moveCards(exZone.getCards(game), Zone.HAND, source, game); + } + return true; + } + return false; + } +} From 9989f5a9fea4c6cfc6927f98419af96d3b3336c2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 23:09:16 +0200 Subject: [PATCH 022/164] Implemented Longhorn Firebeast --- .../src/mage/cards/l/LonghornFirebeast.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LonghornFirebeast.java diff --git a/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java b/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java new file mode 100644 index 0000000000..fb0ccd56b0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java @@ -0,0 +1,110 @@ +/* + * 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.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author noxx & L_J + + */ +public class LonghornFirebeast extends CardImpl { + + public LonghornFirebeast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.OX); + this.subtype.add(SubType.BEAST); + + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Longhorn Firebeast enters the battlefield, any opponent may have it deal 5 damage to him or her. If a player does, sacrifice Longhorn Firebeast. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LonghornFirebeastEffect(), false)); + } + + public LonghornFirebeast(final LonghornFirebeast card) { + super(card); + } + + @Override + public LonghornFirebeast copy() { + return new LonghornFirebeast(this); + } +} + +class LonghornFirebeastEffect extends OneShotEffect { + + public LonghornFirebeastEffect() { + super(Outcome.Neutral); + staticText = "any opponent may have it deal 5 damage to him or her. If a player does, sacrifice {this}"; + } + + LonghornFirebeastEffect(final LonghornFirebeastEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (controller != null && permanent != null) { + for (UUID opponentUuid : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(opponentUuid); + if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getLogName() + " deal 5 damage to you?", source, game)) { + game.informPlayers(opponent.getLogName() + " has chosen to receive 5 damage from " + permanent.getLogName()); + opponent.damage(5, permanent.getId(), game, false, true); + permanent.sacrifice(source.getSourceId(), game); + return true; + } + } + game.informPlayers("5 damage wasn't dealt so " + permanent.getLogName() + " won't be sacrificed."); + return true; + } + return false; + } + + @Override + public LonghornFirebeastEffect copy() { + return new LonghornFirebeastEffect(this); + } + +} From 1217ccff85bd82cb57672d6bd02af2fa6b48fbf7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 8 Oct 2017 23:09:51 +0200 Subject: [PATCH 023/164] Implemented Hypnox and Longhorn Firebeast --- Mage.Sets/src/mage/sets/Torment.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Torment.java b/Mage.Sets/src/mage/sets/Torment.java index b78a8465c6..a0d03e5286 100644 --- a/Mage.Sets/src/mage/sets/Torment.java +++ b/Mage.Sets/src/mage/sets/Torment.java @@ -106,6 +106,7 @@ public class Torment extends ExpansionSet { cards.add(new SetCardInfo("Hydromorph Guardian", 39, Rarity.COMMON, mage.cards.h.HydromorphGuardian.class)); cards.add(new SetCardInfo("Hydromorph Gull", 40, Rarity.UNCOMMON, mage.cards.h.HydromorphGull.class)); cards.add(new SetCardInfo("Hypochondria", 7, Rarity.UNCOMMON, mage.cards.h.Hypochondria.class)); + cards.add(new SetCardInfo("Hypnox", 64, Rarity.RARE, mage.cards.h.Hypnox.class)); cards.add(new SetCardInfo("Ichorid", 65, Rarity.RARE, mage.cards.i.Ichorid.class)); cards.add(new SetCardInfo("Insidious Dreams", 66, Rarity.RARE, mage.cards.i.InsidiousDreams.class)); cards.add(new SetCardInfo("Insist", 127, Rarity.RARE, mage.cards.i.Insist.class)); @@ -117,6 +118,7 @@ public class Torment extends ExpansionSet { cards.add(new SetCardInfo("Last Laugh", 68, Rarity.RARE, mage.cards.l.LastLaugh.class)); cards.add(new SetCardInfo("Liquify", 41, Rarity.COMMON, mage.cards.l.Liquify.class)); cards.add(new SetCardInfo("Llawan, Cephalid Empress", 42, Rarity.RARE, mage.cards.l.LlawanCephalidEmpress.class)); + cards.add(new SetCardInfo("Longhorn Firebeast", 103, Rarity.COMMON, mage.cards.l.LonghornFirebeast.class)); cards.add(new SetCardInfo("Major Teroh", 8, Rarity.RARE, mage.cards.m.MajorTeroh.class)); cards.add(new SetCardInfo("Mesmeric Fiend", 69, Rarity.COMMON, mage.cards.m.MesmericFiend.class)); cards.add(new SetCardInfo("Militant Monk", 9, Rarity.COMMON, mage.cards.m.MilitantMonk.class)); From 118978e39d65146b12ec29b00d2eac1217e1f8ec Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 9 Oct 2017 12:23:14 -0400 Subject: [PATCH 024/164] text fixes --- Mage.Sets/src/mage/cards/b/BonethornValesk.java | 2 +- Mage.Sets/src/mage/cards/c/ChillHaunting.java | 2 +- Mage.Sets/src/mage/cards/k/KrovikanWhispers.java | 2 +- Mage.Sets/src/mage/cards/l/LightningSerpent.java | 8 ++++---- Mage.Sets/src/mage/cards/l/LightningStorm.java | 2 +- Mage.Sets/src/mage/cards/s/SurgingAether.java | 2 +- Mage.Sets/src/mage/cards/s/SurgingDementia.java | 4 ++-- Mage.Sets/src/mage/cards/s/SurgingFlame.java | 5 +++-- Mage.Sets/src/mage/cards/v/VexingSphinx.java | 5 ++--- .../mage/abilities/keyword/CumulativeUpkeepAbility.java | 9 ++++++--- 10 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BonethornValesk.java b/Mage.Sets/src/mage/cards/b/BonethornValesk.java index 6af8e310eb..ebaa60b72f 100644 --- a/Mage.Sets/src/mage/cards/b/BonethornValesk.java +++ b/Mage.Sets/src/mage/cards/b/BonethornValesk.java @@ -53,7 +53,7 @@ public class BonethornValesk extends CardImpl { this.toughness = new MageInt(2); // Whenever a permanent is turned face up, Bonethorn Valesk deals 1 damage to target creature or player. - Ability ability = new TurnedFaceUpAllTriggeredAbility(new DamageTargetEffect(1), new FilterPermanent()); + Ability ability = new TurnedFaceUpAllTriggeredAbility(new DamageTargetEffect(1), new FilterPermanent("a permanent")); ability.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ChillHaunting.java b/Mage.Sets/src/mage/cards/c/ChillHaunting.java index 4a9dfd5fff..77610b404d 100644 --- a/Mage.Sets/src/mage/cards/c/ChillHaunting.java +++ b/Mage.Sets/src/mage/cards/c/ChillHaunting.java @@ -50,7 +50,7 @@ public class ChillHaunting extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); // As an additional cost to cast Chill Haunting, exile X creature cards from your graveyard. - this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"), true)); + this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("creature cards from your graveyard"), true)); // Target creature gets -X/-X until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java index 06287397b1..2aee7e8829 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java @@ -68,7 +68,7 @@ public class KrovikanWhispers extends CardImpl { this.addAbility(ability); // Cumulative upkeep-Pay {U} or {B}. - this.addAbility(new CumulativeUpkeepAbility(new OrCost(new ManaCostsImpl("{U}"), new ManaCostsImpl("{B}"), "Pay {U} or pay {B}"))); + this.addAbility(new CumulativeUpkeepAbility(new OrCost(new ManaCostsImpl("{U}"), new ManaCostsImpl("{B}"), "{U} or {B}"))); // You control enchanted creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); diff --git a/Mage.Sets/src/mage/cards/l/LightningSerpent.java b/Mage.Sets/src/mage/cards/l/LightningSerpent.java index 37e36d2d72..c567141b31 100644 --- a/Mage.Sets/src/mage/cards/l/LightningSerpent.java +++ b/Mage.Sets/src/mage/cards/l/LightningSerpent.java @@ -29,8 +29,8 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.keyword.HasteAbility; @@ -39,8 +39,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.counters.CounterType; +import mage.game.events.GameEvent; /** * @@ -49,7 +49,7 @@ import mage.counters.CounterType; public class LightningSerpent extends CardImpl { public LightningSerpent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.SERPENT); this.power = new MageInt(2); @@ -62,7 +62,7 @@ public class LightningSerpent extends CardImpl { // Lightning Serpent enters the battlefield with X +1/+0 counters on it. this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P0.createInstance()))); // At the beginning of the end step, sacrifice Lightning Serpent. - this.addAbility(new BeginningOfEndStepTriggeredAbility(new SacrificeSourceEffect(), TargetController.ANY, false)); + this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect())); } public LightningSerpent(final LightningSerpent card) { diff --git a/Mage.Sets/src/mage/cards/l/LightningStorm.java b/Mage.Sets/src/mage/cards/l/LightningStorm.java index c69e97fc88..0c7c4cd07b 100644 --- a/Mage.Sets/src/mage/cards/l/LightningStorm.java +++ b/Mage.Sets/src/mage/cards/l/LightningStorm.java @@ -69,7 +69,7 @@ public class LightningStorm extends CardImpl { new LightningStormAddCounterEffect(), new DiscardTargetCost(new TargetCardInHand(new FilterLandCard("a land card")))); ability.setMayActivate(TargetController.ANY); - ability.addEffect(new InfoEffect("Any player may activate this ability but only if {this} is on the stack")); + ability.addEffect(new InfoEffect(" Any player may activate this ability but only if {this} is on the stack")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index ccb530ace5..79d406787f 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -45,7 +45,7 @@ public class SurgingAether extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SurgingDementia.java b/Mage.Sets/src/mage/cards/s/SurgingDementia.java index dfe6b8e92c..d24c284691 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingDementia.java +++ b/Mage.Sets/src/mage/cards/s/SurgingDementia.java @@ -42,10 +42,10 @@ import mage.target.TargetPlayer; public class SurgingDementia extends CardImpl { public SurgingDementia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); // Target player discards a card. this.getSpellAbility().getEffects().add(new DiscardTargetEffect(1)); diff --git a/Mage.Sets/src/mage/cards/s/SurgingFlame.java b/Mage.Sets/src/mage/cards/s/SurgingFlame.java index 07ab76ed79..2a7b218a35 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingFlame.java +++ b/Mage.Sets/src/mage/cards/s/SurgingFlame.java @@ -42,10 +42,11 @@ import mage.target.common.TargetCreatureOrPlayer; public class SurgingFlame extends CardImpl { public SurgingFlame(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); + // Surging Flame deals 2 damage to target creature or player. this.getSpellAbility().addEffect(new DamageTargetEffect(2)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); diff --git a/Mage.Sets/src/mage/cards/v/VexingSphinx.java b/Mage.Sets/src/mage/cards/v/VexingSphinx.java index 3a1f7376c2..d5908b2b31 100644 --- a/Mage.Sets/src/mage/cards/v/VexingSphinx.java +++ b/Mage.Sets/src/mage/cards/v/VexingSphinx.java @@ -30,7 +30,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DiesTriggeredAbility; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.keyword.FlyingAbility; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -40,7 +40,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; -import mage.target.common.TargetCardInHand; /** * @@ -59,7 +58,7 @@ public class VexingSphinx extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Cumulative upkeep-Discard a card. - this.addAbility(new CumulativeUpkeepAbility(new DiscardTargetCost(new TargetCardInHand()))); + this.addAbility(new CumulativeUpkeepAbility(new DiscardCardCost())); // When Vexing Sphinx dies, draw a card for each age counter on it. this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.AGE)))); diff --git a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java index f24a1a8817..42144532db 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.OrCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; @@ -70,9 +71,11 @@ public class CumulativeUpkeepAbility extends BeginningOfUpkeepTriggeredAbility { @Override public String getRule() { - StringBuilder sb = new StringBuilder("Cumulative upkeep "); - if (!(cumulativeCost instanceof ManaCost)) { - sb.append("— "); + StringBuilder sb = new StringBuilder("Cumulative upkeep"); + if (!(cumulativeCost instanceof ManaCost || cumulativeCost instanceof OrCost)) { + sb.append("—"); + } else { + sb.append(' '); } sb.append(cumulativeCost.getText()); return sb.toString(); From 901a64059263e978e6b4cae49b9909d98d576c1d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 9 Oct 2017 12:30:36 -0400 Subject: [PATCH 025/164] updated MTGO 1v1 Commander banlist --- .../src/mage/deck/MTGO1v1Commander.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java index 6b0f0dab25..7281e662c8 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java @@ -36,17 +36,20 @@ public class MTGO1v1Commander extends Commander { public MTGO1v1Commander() { super("MTGO 1v1 Commander"); banned.add("Ancestral Recall"); - banned.add("Arcum Dagsson"); banned.add("Back to Basics"); banned.add("Balance"); + banned.add("Baral, Chief of Compliance"); banned.add("Bazaar of Baghdad"); banned.add("Black Lotus"); banned.add("Braids, Cabal Minion"); banned.add("Brainstorm"); banned.add("Channel"); banned.add("Derevi, Empyrial Tactician"); + banned.add("Demonic Tutor"); banned.add("Dig Through Time"); banned.add("Edric, Spymaster of Trest"); + banned.add("Emrakul, the Aeons Torn"); + banned.add("Enlightened Tutor"); banned.add("Entomb"); banned.add("Fastbond"); banned.add("Food Chain"); @@ -55,6 +58,7 @@ public class MTGO1v1Commander extends Commander { banned.add("Griselbrand"); banned.add("Hermit Druid"); banned.add("Humility"); + banned.add("Imperial Seal"); banned.add("Karakas"); banned.add("Library of Alexandria"); banned.add("Mana Crypt"); @@ -68,6 +72,7 @@ public class MTGO1v1Commander extends Commander { banned.add("Mox Pearl"); banned.add("Mox Ruby"); banned.add("Mox Sapphire"); + banned.add("Mystical Tutor"); banned.add("Natural Order"); banned.add("Necropotence"); banned.add("Oath of Druids"); @@ -88,8 +93,8 @@ public class MTGO1v1Commander extends Commander { banned.add("Treachery"); banned.add("Treasure Cruise"); banned.add("Vial Smasher the Fierce"); + banned.add("Vampiric Tutor"); banned.add("Yamgmoth's Bargain"); - banned.add("Yisan, the Wanderer Bard"); banned.add("Zur the Enchanter"); } -} \ No newline at end of file +} From 0d1add38174acb625cf1d15807c20f74c4b8e0ed Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 10 Oct 2017 21:16:54 +0200 Subject: [PATCH 026/164] Minor cleanup --- Mage.Sets/src/mage/cards/l/LastLaugh.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/l/LastLaugh.java b/Mage.Sets/src/mage/cards/l/LastLaugh.java index f1bbbe4b18..2a2c1238d5 100644 --- a/Mage.Sets/src/mage/cards/l/LastLaugh.java +++ b/Mage.Sets/src/mage/cards/l/LastLaugh.java @@ -45,25 +45,22 @@ import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; - /** * * @author L_J */ public class LastLaugh extends CardImpl { - private static final FilterPermanent filterAnotherPermanent = new FilterPermanent("a permanent other than Last Laugh"); + private static final FilterPermanent filter = new FilterPermanent("a permanent other than Last Laugh"); static { - filterAnotherPermanent.add(new AnotherPredicate()); + filter.add(new AnotherPredicate()); } - public static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent(); - public LastLaugh(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}"); // Whenever a permanent other than Last Laugh is put into a graveyard from the battlefield, Last Laugh deals 1 damage to each creature and each player. - this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new DamageEverythingEffect(1), false, filterAnotherPermanent, false)); + this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new DamageEverythingEffect(1), false, filter, false)); // When no creatures are on the battlefield, sacrifice Last Laugh. this.addAbility(new LastLaughStateTriggeredAbility()); @@ -97,7 +94,7 @@ class LastLaughStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getBattlefield().count(LastLaugh.filterCreature, this.getSourceId(), this.getControllerId(), game) == 0; + return game.getBattlefield().count(new FilterCreaturePermanent(), this.getSourceId(), this.getControllerId(), game) == 0; } @Override From 0119930845513676a65cad29728808d994d8b03e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 10 Oct 2017 21:19:20 +0200 Subject: [PATCH 027/164] Implemented Samite Sanctuary --- .../src/mage/cards/s/SamiteSanctuary.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SamiteSanctuary.java diff --git a/Mage.Sets/src/mage/cards/s/SamiteSanctuary.java b/Mage.Sets/src/mage/cards/s/SamiteSanctuary.java new file mode 100644 index 0000000000..9f6fa57696 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SamiteSanctuary.java @@ -0,0 +1,69 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class SamiteSanctuary extends CardImpl { + + public SamiteSanctuary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + // {2}: Prevent the next 1 damage that would be dealt to target creature this turn. Any player may activate this ability. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn ,1), new ManaCostsImpl("{2}")); + ability.addTarget(new TargetCreaturePermanent()); + ability.setMayActivate(TargetController.ANY); + ability.addEffect(new InfoEffect("Any player may activate this ability")); + this.addAbility(ability); + } + + public SamiteSanctuary(final SamiteSanctuary card) { + super(card); + } + + @Override + public SamiteSanctuary copy() { + return new SamiteSanctuary(this); + } +} From 34723aa4893540649b8a255eddfc0ce0449a1342 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 10 Oct 2017 21:22:18 +0200 Subject: [PATCH 028/164] Implemented Task Mage Assembly --- .../src/mage/cards/t/TaskMageAssembly.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TaskMageAssembly.java diff --git a/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java b/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java new file mode 100644 index 0000000000..395b642149 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java @@ -0,0 +1,103 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class TaskMageAssembly extends CardImpl { + + public TaskMageAssembly(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + + // When there are no creatures on the battlefield, sacrifice Task Mage Assembly. + this.addAbility(new TaskMageAssemblyStateTriggeredAbility()); + + // {2}: Task Mage Assembly deals 1 damage to target creature. Any player may activate this ability but only any time he or she could cast a sorcery. + ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{2}")); + ability.addTarget(new TargetCreaturePermanent()); + ability.setMayActivate(TargetController.ANY); + ability.addEffect(new InfoEffect("Any player may activate this ability")); + this.addAbility(ability); + } + + public TaskMageAssembly(final TaskMageAssembly card) { + super(card); + } + + @Override + public TaskMageAssembly copy() { + return new TaskMageAssembly(this); + } +} + +class TaskMageAssemblyStateTriggeredAbility extends StateTriggeredAbility { + + public TaskMageAssemblyStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new SacrificeSourceEffect()); + } + + public TaskMageAssemblyStateTriggeredAbility(final TaskMageAssemblyStateTriggeredAbility ability) { + super(ability); + } + + @Override + public TaskMageAssemblyStateTriggeredAbility copy() { + return new TaskMageAssemblyStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.getBattlefield().count(new FilterCreaturePermanent(), this.getSourceId(), this.getControllerId(), game) == 0; + } + + @Override + public String getRule() { + return new StringBuilder("When there are no creatures on the battlefield, ").append(super.getRule()).toString() ; + } + +} From f50d52a92b711ad4d89556a7a10f277d0ae71ca2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 10 Oct 2017 21:22:32 +0200 Subject: [PATCH 029/164] Implemented Samite Sanctuary and Task Mage Assembly --- Mage.Sets/src/mage/sets/Prophecy.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 03b140387b..10b7c6d885 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -90,7 +90,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Flameshot", 90, Rarity.UNCOMMON, mage.cards.f.Flameshot.class)); cards.add(new SetCardInfo("Flowering Field", 9, Rarity.UNCOMMON, mage.cards.f.FloweringField.class)); cards.add(new SetCardInfo("Foil", 34, Rarity.UNCOMMON, mage.cards.f.Foil.class)); - cards.add(new SetCardInfo("Forgotten Harvest", 114, Rarity.RARE, mage.cards.f.ForgottenHarvest.class)); + cards.add(new SetCardInfo("Forgotten Harvest", 114, Rarity.RARE, mage.cards.f.ForgottenHarvest.class)); cards.add(new SetCardInfo("Greel's Caress", 67, Rarity.COMMON, mage.cards.g.GreelsCaress.class)); cards.add(new SetCardInfo("Greel, Mind Raker", 66, Rarity.RARE, mage.cards.g.GreelMindRaker.class)); cards.add(new SetCardInfo("Gulf Squid", 35, Rarity.COMMON, mage.cards.g.GulfSquid.class)); @@ -102,7 +102,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Jolrael, Empress of Beasts", 115, Rarity.RARE, mage.cards.j.JolraelEmpressOfBeasts.class)); cards.add(new SetCardInfo("Jolrael's Favor", 116, Rarity.COMMON, mage.cards.j.JolraelsFavor.class)); cards.add(new SetCardInfo("Keldon Arsonist", 92, Rarity.UNCOMMON, mage.cards.k.KeldonArsonist.class)); - cards.add(new SetCardInfo("Keldon Berserker", 93, Rarity.COMMON, mage.cards.k.KeldonBerserker.class)); + cards.add(new SetCardInfo("Keldon Berserker", 93, Rarity.COMMON, mage.cards.k.KeldonBerserker.class)); cards.add(new SetCardInfo("Keldon Firebombers", 94, Rarity.RARE, mage.cards.k.KeldonFirebombers.class)); cards.add(new SetCardInfo("Latulla, Keldon Overseer", 95, Rarity.RARE, mage.cards.l.LatullaKeldonOverseer.class)); cards.add(new SetCardInfo("Lesser Gargadon", 97, Rarity.UNCOMMON, mage.cards.l.LesserGargadon.class)); @@ -135,11 +135,12 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Rib Cage Spider", 121, Rarity.COMMON, mage.cards.r.RibCageSpider.class)); cards.add(new SetCardInfo("Ridgeline Rager", 100, Rarity.COMMON, mage.cards.r.RidgelineRager.class)); cards.add(new SetCardInfo("Root Cage", 122, Rarity.UNCOMMON, mage.cards.r.RootCage.class)); + cards.add(new SetCardInfo("Samite Sanctuary", 21, Rarity.RARE, mage.cards.s.SamiteSanctuary.class)); cards.add(new SetCardInfo("Scoria Cat", 101, Rarity.UNCOMMON, mage.cards.s.ScoriaCat.class)); cards.add(new SetCardInfo("Searing Wind", 103, Rarity.RARE, mage.cards.s.SearingWind.class)); cards.add(new SetCardInfo("Shield Dancer", 23, Rarity.UNCOMMON, mage.cards.s.ShieldDancer.class)); cards.add(new SetCardInfo("Silt Crawler", 123, Rarity.COMMON, mage.cards.s.SiltCrawler.class)); - cards.add(new SetCardInfo("Snag", 124, Rarity.UNCOMMON, mage.cards.s.Snag.class)); + cards.add(new SetCardInfo("Snag", 124, Rarity.UNCOMMON, mage.cards.s.Snag.class)); cards.add(new SetCardInfo("Spiketail Drake", 48, Rarity.UNCOMMON, mage.cards.s.SpiketailDrake.class)); cards.add(new SetCardInfo("Spiketail Hatchling", 49, Rarity.COMMON, mage.cards.s.SpiketailHatchling.class)); cards.add(new SetCardInfo("Spitting Spider", 125, Rarity.UNCOMMON, mage.cards.s.SpittingSpider.class)); @@ -150,6 +151,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Stormwatch Eagle", 50, Rarity.COMMON, mage.cards.s.StormwatchEagle.class)); cards.add(new SetCardInfo("Sunken Field", 51, Rarity.UNCOMMON, mage.cards.s.SunkenField.class)); cards.add(new SetCardInfo("Sword Dancer", 25, Rarity.UNCOMMON, mage.cards.s.SwordDancer.class)); + cards.add(new SetCardInfo("Task Mage Assembly", 105, Rarity.RARE, mage.cards.t.TaskMageAssembly.class)); cards.add(new SetCardInfo("Thrive", 129, Rarity.COMMON, mage.cards.t.Thrive.class)); cards.add(new SetCardInfo("Trenching Steed", 26, Rarity.COMMON, mage.cards.t.TrenchingSteed.class)); cards.add(new SetCardInfo("Troubled Healer", 27, Rarity.COMMON, mage.cards.t.TroubledHealer.class)); @@ -163,7 +165,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Whip Sergeant", 107, Rarity.UNCOMMON, mage.cards.w.WhipSergeant.class)); cards.add(new SetCardInfo("Whipstitched Zombie", 81, Rarity.COMMON, mage.cards.w.WhipstitchedZombie.class)); cards.add(new SetCardInfo("Wild Might", 134, Rarity.COMMON, mage.cards.w.WildMight.class)); - cards.add(new SetCardInfo("Windscouter", 53, Rarity.UNCOMMON, mage.cards.w.Windscouter.class)); + cards.add(new SetCardInfo("Windscouter", 53, Rarity.UNCOMMON, mage.cards.w.Windscouter.class)); cards.add(new SetCardInfo("Wintermoon Mesa", 143, Rarity.RARE, mage.cards.w.WintermoonMesa.class)); cards.add(new SetCardInfo("Withdraw", 54, Rarity.COMMON, mage.cards.w.Withdraw.class)); cards.add(new SetCardInfo("Zerapa Minotaur", 108, Rarity.COMMON, mage.cards.z.ZerapaMinotaur.class)); From bef2137443a6cf12074dd68289a8936244c99ea1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 10 Oct 2017 16:08:20 -0400 Subject: [PATCH 030/164] fixed Foe-Razer Regent adding counters to cards that have left the battlefield (fixes #4096) --- Mage.Sets/src/mage/cards/f/FoeRazerRegent.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java index f09aa782e3..888a7e4ca1 100644 --- a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java +++ b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java @@ -67,7 +67,7 @@ public class FoeRazerRegent extends CardImpl { } public FoeRazerRegent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(4); this.toughness = new MageInt(5); @@ -118,8 +118,8 @@ class FoeRazerRegentTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (permanent != null && permanent.getControllerId().equals(getControllerId())) { - for (Effect effect: this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent, game)); } return true; } From 80f21132ebf6bb484fc16f8c491ee2d2bc1612e3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 10 Oct 2017 16:23:03 -0400 Subject: [PATCH 031/164] fixed Nivmagus Elemental being able to infinitely exile copied spells (fixes #4092) --- Mage.Sets/src/mage/cards/n/NivmagusElemental.java | 11 +++++------ .../abilities/costs/common/ExileFromStackCost.java | 9 +++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java index 04a6129f22..946b574a2a 100644 --- a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java +++ b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java @@ -57,22 +57,21 @@ public class NivmagusElemental extends CardImpl { static { filter.add(new ControllerPredicate(TargetController.YOU)); filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY))); + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); } public NivmagusElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U/R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}"); this.subtype.add(SubType.ELEMENTAL); - this.power = new MageInt(1); this.toughness = new MageInt(2); // Exile an instant or sorcery spell you control: Put two +1/+1 counters on Nivmagus Elemental. (That spell won't resolve.) - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)),new ExileFromStackCost(new TargetSpell(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ExileFromStackCost(new TargetSpell(filter))); this.addAbility(ability); - + } public NivmagusElemental(final NivmagusElemental card) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java index 28576b5eed..5f692b1a26 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java @@ -61,10 +61,15 @@ public class ExileFromStackCost extends CostImpl { if (spellToExile == null) { return false; } - spellToExile.moveToExile(null, "", ability.getSourceId(), game); + String spellName = spellToExile.getName(); + if (spellToExile.isCopy()) { + game.getStack().remove(spellToExile); + } else { + spellToExile.moveToExile(null, "", ability.getSourceId(), game); + } paid = true; if (!game.isSimulation()) { - game.informPlayers(player.getLogName() + " exiles " + spellToExile.getName() + " (as costs)"); + game.informPlayers(player.getLogName() + " exiles " + spellName + " (as costs)"); } } } From 4116b58414756afea7e5297f0595c44043892b77 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 10 Oct 2017 16:58:40 -0400 Subject: [PATCH 032/164] fixed Venser, Shaper Savant and other similar cards not properly removing copied spells from the stack (fixes #4072) --- .../common/ReturnToHandTargetEffect.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java index 2ab4c45591..2387fbe024 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java @@ -27,7 +27,9 @@ */ package mage.abilities.effects.common; +import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import java.util.UUID; import mage.MageObject; @@ -38,6 +40,7 @@ import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.game.stack.Spell; import mage.players.Player; import mage.target.Target; import mage.util.CardUtil; @@ -74,12 +77,15 @@ public class ReturnToHandTargetEffect extends OneShotEffect { if (controller == null) { return false; } + List copyIds = new ArrayList<>(); Set cards = new LinkedHashSet<>(); if (multitargetHandling) { for (Target target : source.getTargets()) { for (UUID targetId : target.getTargets()) { MageObject mageObject = game.getObject(targetId); - if (mageObject instanceof Card) { + if (mageObject instanceof Spell && !((Spell) mageObject).isCopy()) { + copyIds.add(targetId); + } else if (mageObject instanceof Card) { cards.add((Card) mageObject); } } @@ -88,10 +94,17 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject mageObject = game.getObject(targetId); if (mageObject != null) { - cards.add((Card) mageObject); + if (mageObject instanceof Spell && !((Spell) mageObject).isCopy()) { + copyIds.add(targetId); + } else { + cards.add((Card) mageObject); + } } } } + for (UUID copyId : copyIds) { + game.getStack().remove(game.getSpell(copyId)); + } return controller.moveCards(cards, Zone.HAND, source, game); } From 2275c80922fd27720234a27d6879af5b7a4a2adc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 10 Oct 2017 18:53:15 -0400 Subject: [PATCH 033/164] fixed the text on several threaten effects --- .../src/mage/cards/a/ActOfAggression.java | 7 +++---- Mage.Sets/src/mage/cards/a/ActOfTreason.java | 9 +++------ .../src/mage/cards/b/BlindWithAnger.java | 13 +++++------- .../src/mage/cards/c/CloakAndDagger.java | 5 +++-- .../src/mage/cards/c/ConqueringManticore.java | 17 ++++++++++++---- .../src/mage/cards/d/DominusOfFealty.java | 7 +++---- .../src/mage/cards/e/EldraziObligator.java | 12 +++++------ .../src/mage/cards/f/FlashConscription.java | 9 ++++++--- Mage.Sets/src/mage/cards/g/Goatnapper.java | 6 +++--- .../src/mage/cards/k/KariZevsExpertise.java | 4 ++-- .../src/mage/cards/m/MetallicMastery.java | 20 ++++++------------- .../src/mage/cards/o/OgreGeargrabber.java | 6 +++--- Mage.Sets/src/mage/cards/s/SlaveOfBolas.java | 6 +++--- Mage.Sets/src/mage/cards/s/SpinalEmbrace.java | 4 ++-- Mage.Sets/src/mage/cards/t/Threaten.java | 8 ++++---- .../src/mage/cards/t/TraitorousBlood.java | 9 ++++----- .../src/mage/cards/t/TraitorousInstinct.java | 9 ++++----- 17 files changed, 73 insertions(+), 78 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ActOfAggression.java b/Mage.Sets/src/mage/cards/a/ActOfAggression.java index 0c17193e5e..5e05507247 100644 --- a/Mage.Sets/src/mage/cards/a/ActOfAggression.java +++ b/Mage.Sets/src/mage/cards/a/ActOfAggression.java @@ -54,12 +54,11 @@ public class ActOfAggression extends CardImpl { } public ActOfAggression(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R/P}{R/P}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R/P}{R/P}"); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public ActOfAggression(final ActOfAggression card) { diff --git a/Mage.Sets/src/mage/cards/a/ActOfTreason.java b/Mage.Sets/src/mage/cards/a/ActOfTreason.java index c402523712..bed4e24e0c 100644 --- a/Mage.Sets/src/mage/cards/a/ActOfTreason.java +++ b/Mage.Sets/src/mage/cards/a/ActOfTreason.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.a; import java.util.UUID; @@ -46,16 +45,14 @@ import mage.target.common.TargetCreaturePermanent; public class ActOfTreason extends CardImpl { public ActOfTreason(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // Gain control of target creature until end of turn. Untap that creature. // It gains haste until end of turn. (It can attack and {T} this turn.) this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public ActOfTreason(final ActOfTreason card) { diff --git a/Mage.Sets/src/mage/cards/b/BlindWithAnger.java b/Mage.Sets/src/mage/cards/b/BlindWithAnger.java index a63a7e97b4..076f4b9666 100644 --- a/Mage.Sets/src/mage/cards/b/BlindWithAnger.java +++ b/Mage.Sets/src/mage/cards/b/BlindWithAnger.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.b; import java.util.UUID; @@ -42,7 +41,6 @@ import mage.constants.SuperType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SupertypePredicate; -import mage.target.Target; import mage.target.common.TargetCreaturePermanent; /** @@ -57,14 +55,13 @@ public class BlindWithAnger extends CardImpl { } public BlindWithAnger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); this.subtype.add(SubType.ARCANE); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - Target target = new TargetCreaturePermanent(filter); - this.getSpellAbility().addTarget(target); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap target nonlegendary creature")); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); } public BlindWithAnger(final BlindWithAnger card) { diff --git a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java index 626aceb445..bf022a10d5 100644 --- a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java +++ b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java @@ -51,18 +51,19 @@ import mage.filter.predicate.mageobject.SubtypePredicate; public class CloakAndDagger extends CardImpl { private static final FilterPermanent filter = new FilterCreaturePermanent("a Rogue creature"); + static { filter.add(new SubtypePredicate(SubType.ROGUE)); } public CloakAndDagger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+0 and has shroud. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0)); - ability.addEffect(new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.EQUIPMENT)); + ability.addEffect(new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has shroud")); this.addAbility(ability); // Whenever a Rogue creature enters the battlefield, you may attach Cloak and Dagger to it. this.addAbility(new EntersBattlefieldAllTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/c/ConqueringManticore.java b/Mage.Sets/src/mage/cards/c/ConqueringManticore.java index 21b369bbd5..64e6ab9ad0 100644 --- a/Mage.Sets/src/mage/cards/c/ConqueringManticore.java +++ b/Mage.Sets/src/mage/cards/c/ConqueringManticore.java @@ -41,6 +41,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; /** @@ -49,8 +52,14 @@ import mage.target.common.TargetCreaturePermanent; */ public class ConqueringManticore extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + public ConqueringManticore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.MANTICORE); this.power = new MageInt(5); @@ -59,9 +68,9 @@ public class ConqueringManticore extends CardImpl { this.addAbility(FlyingAbility.getInstance()); Ability ability = new EntersBattlefieldTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), false); - ability.addEffect(new UntapTargetEffect()); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - ability.addTarget(new TargetCreaturePermanent()); + ability.addEffect(new UntapTargetEffect().setText("Untap that creature")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DominusOfFealty.java b/Mage.Sets/src/mage/cards/d/DominusOfFealty.java index 3572e5c2ea..dd6b778533 100644 --- a/Mage.Sets/src/mage/cards/d/DominusOfFealty.java +++ b/Mage.Sets/src/mage/cards/d/DominusOfFealty.java @@ -51,17 +51,16 @@ import mage.target.TargetPermanent; public class DominusOfFealty extends CardImpl { public DominusOfFealty(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U/R}{U/R}{U/R}{U/R}{U/R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}{U/R}{U/R}{U/R}{U/R}"); this.subtype.add(SubType.SPIRIT); this.subtype.add(SubType.AVATAR); - this.power = new MageInt(4); this.toughness = new MageInt(4); this.addAbility(FlyingAbility.getInstance()); Ability ability = new BeginningOfUpkeepTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), TargetController.YOU, true); - ability.addEffect(new UntapTargetEffect()); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new UntapTargetEffect().setText("If you do, untap it")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and it gains haste until end of turn")); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EldraziObligator.java b/Mage.Sets/src/mage/cards/e/EldraziObligator.java index 79660d4410..e3d9337d31 100644 --- a/Mage.Sets/src/mage/cards/e/EldraziObligator.java +++ b/Mage.Sets/src/mage/cards/e/EldraziObligator.java @@ -55,7 +55,7 @@ import mage.target.common.TargetCreaturePermanent; public class EldraziObligator extends CardImpl { public EldraziObligator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.ELDRAZI); this.power = new MageInt(3); this.toughness = new MageInt(1); @@ -65,15 +65,15 @@ public class EldraziObligator extends CardImpl { // Haste this.addAbility(HasteAbility.getInstance()); - + DoIfCostPaid costPaidEffect = new DoIfCostPaid(new GainControlTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}{C}")); Effect untapEffect = new UntapTargetEffect(); - untapEffect.setText("Untap that creature"); + untapEffect.setText("untap that creature,"); Effect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - hasteEffect.setText("It gains haste until end of turn"); + hasteEffect.setText("and it gains haste until end of turn"); costPaidEffect.addEffect(untapEffect); - costPaidEffect.addEffect(hasteEffect); - + costPaidEffect.addEffect(hasteEffect); + // When you cast Eldrazi Obligator, you may pay {1}{C}. If you do, gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. Ability ability = new CastSourceTriggeredAbility(costPaidEffect); diff --git a/Mage.Sets/src/mage/cards/f/FlashConscription.java b/Mage.Sets/src/mage/cards/f/FlashConscription.java index ae2ec3f576..91e9cf345b 100644 --- a/Mage.Sets/src/mage/cards/f/FlashConscription.java +++ b/Mage.Sets/src/mage/cards/f/FlashConscription.java @@ -59,11 +59,14 @@ public class FlashConscription extends CardImpl { // Untap target creature and gain control of it until end of turn. That creature gains haste until end of turn. If {W} was spent to cast Flash Conscription, the creature gains "Whenever this creature deals combat damage, you gain that much life" until end of turn. this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("That creature gains haste until end of turn")); this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new GainAbilityTargetEffect(new FlashConscriptionTriggeredAbility(), Duration.EndOfTurn), - new ManaWasSpentCondition(ColoredManaSymbol.W), "If {W} was spent to cast {this}, the creature gains \"Whenever this creature deals combat damage, you gain that much life\" until end of turn")); + new ManaWasSpentCondition(ColoredManaSymbol.W), + "If {W} was spent to cast {this}, the creature gains " + + "\"Whenever this creature deals combat damage, you gain that much life\" until end of turn" + )); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/g/Goatnapper.java b/Mage.Sets/src/mage/cards/g/Goatnapper.java index dd0e2dba9a..aaed048196 100644 --- a/Mage.Sets/src/mage/cards/g/Goatnapper.java +++ b/Mage.Sets/src/mage/cards/g/Goatnapper.java @@ -57,7 +57,7 @@ public class Goatnapper extends CardImpl { } public Goatnapper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.ROGUE); @@ -65,8 +65,8 @@ public class Goatnapper extends CardImpl { this.toughness = new MageInt(2); Ability ability = new EntersBattlefieldTriggeredAbility(new UntapTargetEffect(), false); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java b/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java index 44def69dd4..3d978e13d6 100644 --- a/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java +++ b/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java @@ -63,8 +63,8 @@ public class KariZevsExpertise extends CardImpl { // Gain control of target creature or Vehicle until end of turn. Untap it. It gains haste until end of turn. this.getSpellAbility().addTarget(new TargetPermanent(filter)); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gans haste until end of turn.")); // You may cast a card with converted mana cost 2 or less from your hand without paying its mana cost. this.getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(2)); diff --git a/Mage.Sets/src/mage/cards/m/MetallicMastery.java b/Mage.Sets/src/mage/cards/m/MetallicMastery.java index 9849c373d6..a6e3dc76e1 100644 --- a/Mage.Sets/src/mage/cards/m/MetallicMastery.java +++ b/Mage.Sets/src/mage/cards/m/MetallicMastery.java @@ -36,9 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; /** * @@ -46,20 +44,14 @@ import mage.target.TargetPermanent; */ public class MetallicMastery extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifact"); - - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - public MetallicMastery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); - - this.getSpellAbility().addTarget(new TargetPermanent(filter)); + // Gain control of target artifact until end of turn. Untap that artifact. It gains haste until end of turn. + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that artifact")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public MetallicMastery(final MetallicMastery card) { diff --git a/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java b/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java index a4957f0577..ab624558fc 100644 --- a/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java +++ b/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java @@ -62,14 +62,14 @@ public class OgreGeargrabber extends CardImpl { } public OgreGeargrabber(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.OGRE); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(4); this.toughness = new MageInt(4); - Ability ability = new AttacksTriggeredAbility(new OgreGeargrabberEffect1(), false); - ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); + Ability ability = new AttacksTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), false); + ability.addEffect(new OgreGeargrabberEffect1()); ability.addTarget(new TargetPermanent(1, 1, filter, false)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java b/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java index a05a6a3986..9433de0741 100644 --- a/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java +++ b/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java @@ -54,12 +54,12 @@ import mage.target.targetpointer.FixedTarget; public class SlaveOfBolas extends CardImpl { public SlaveOfBolas(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U/R}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U/R}{B}"); // Gain control of target creature. Untap that creature. It gains haste until end of turn. Sacrifice it at the beginning of the next end step. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.getSpellAbility().addEffect(new SlaveOfBolasEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java b/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java index bb1977c5a4..2b708e2376 100644 --- a/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java +++ b/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java @@ -66,7 +66,7 @@ public class SpinalEmbrace extends CardImpl { } public SpinalEmbrace(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}{B}"); // Cast Spinal Embrace only during combat. this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT)); @@ -77,7 +77,7 @@ public class SpinalEmbrace extends CardImpl { Effect effect = new GainControlTargetEffect(Duration.EndOfTurn); effect.setText("and gain control of it"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.getSpellAbility().addEffect(new SpinalEmbraceAddDelayedEffect()); } diff --git a/Mage.Sets/src/mage/cards/t/Threaten.java b/Mage.Sets/src/mage/cards/t/Threaten.java index 6dfbd42c48..99759fa85d 100644 --- a/Mage.Sets/src/mage/cards/t/Threaten.java +++ b/Mage.Sets/src/mage/cards/t/Threaten.java @@ -45,11 +45,11 @@ import mage.target.common.TargetCreaturePermanent; public class Threaten extends CardImpl { public Threaten(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap target creature")); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/t/TraitorousBlood.java b/Mage.Sets/src/mage/cards/t/TraitorousBlood.java index 81f5feb49b..f240d5a7e4 100644 --- a/Mage.Sets/src/mage/cards/t/TraitorousBlood.java +++ b/Mage.Sets/src/mage/cards/t/TraitorousBlood.java @@ -46,15 +46,14 @@ import mage.target.common.TargetCreaturePermanent; public class TraitorousBlood extends CardImpl { public TraitorousBlood(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); // Gain control of target creature until end of turn. Untap it. It gains trample and haste until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn).setText("It gains trample")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and hast until end of turn")); } public TraitorousBlood(final TraitorousBlood card) { diff --git a/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java b/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java index bf08200c80..cda61457d7 100644 --- a/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java +++ b/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java @@ -46,14 +46,13 @@ import mage.target.common.TargetCreaturePermanent; public class TraitorousInstinct extends CardImpl { public TraitorousInstinct(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn).setText("Until end of turn, it gets +2/+0")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and gains haste")); } public TraitorousInstinct(final TraitorousInstinct card) { From 81a1e8152500df87f4aaf6d35a7c3b03fa4b4ca0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 10 Oct 2017 19:27:03 -0400 Subject: [PATCH 034/164] fixed being able to cast spells from an opponents hand when revealed. (fixes #4102) --- Mage/src/main/java/mage/abilities/SpellAbility.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/SpellAbility.java b/Mage/src/main/java/mage/abilities/SpellAbility.java index 7c6228f5ce..f09f246b7f 100644 --- a/Mage/src/main/java/mage/abilities/SpellAbility.java +++ b/Mage/src/main/java/mage/abilities/SpellAbility.java @@ -97,9 +97,11 @@ public class SpellAbility extends ActivatedAbilityImpl { return false; } // fix for Gitaxian Probe and casting opponent's spells - if (!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game) - && !controllerId.equals(playerId) && getZone() != Zone.HAND) { - return false; + if (!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) { + Card card = game.getCard(sourceId); + if (!(card != null && card.getOwnerId() == playerId)) { + return false; + } } // Check if rule modifying events prevent to cast the spell in check playable mode if (this.isCheckPlayableMode()) { From ab632ef1d06e5f5065cc5edcbca89cba1e1529d4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Oct 2017 08:35:33 -0400 Subject: [PATCH 035/164] small fix --- .../abilities/effects/common/ReturnToHandTargetEffect.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java index 2387fbe024..ad80dffa49 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java @@ -83,7 +83,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (Target target : source.getTargets()) { for (UUID targetId : target.getTargets()) { MageObject mageObject = game.getObject(targetId); - if (mageObject instanceof Spell && !((Spell) mageObject).isCopy()) { + if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { copyIds.add(targetId); } else if (mageObject instanceof Card) { cards.add((Card) mageObject); @@ -94,7 +94,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject mageObject = game.getObject(targetId); if (mageObject != null) { - if (mageObject instanceof Spell && !((Spell) mageObject).isCopy()) { + if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { copyIds.add(targetId); } else { cards.add((Card) mageObject); From 9b51694908e6883e9301c80724c67a2062d938d5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Oct 2017 13:00:06 -0400 Subject: [PATCH 036/164] fixed embalm and eternalize sometimes giving the token to the wrong player --- .../mage/abilities/keyword/EmbalmAbility.java | 35 ++++++++------- .../abilities/keyword/EternalizeAbility.java | 45 ++++++++++--------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java index c8a4aefa48..8d082c8076 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java @@ -105,23 +105,24 @@ class EmbalmEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) - token.getColor(game).setColor(ObjectColor.WHITE); - if (!token.hasSubtype(SubType.ZOMBIE, game)) { - token.getSubtype(game).add(0, SubType.ZOMBIE); - } - token.getManaCost().clear(); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); - // Probably it makes sense to remove also the Embalm ability (it's not shown on the token cards). - // Also it can never get active or? But it's not mentioned in the reminder text. - return true; + if (card == null) { + return false; } - - return false; + Player controller = game.getPlayer(card.getOwnerId()); + if (controller == null) { + return false; + } + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.WHITE); + if (!token.hasSubtype(SubType.ZOMBIE, game)) { + token.getSubtype(game).add(0, SubType.ZOMBIE); + } + token.getManaCost().clear(); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); + token.putOntoBattlefield(1, game, source.getSourceId(), controller.getId(), false, false, null); + // Probably it makes sense to remove also the Embalm ability (it's not shown on the token cards). + // Also it can never get active or? But it's not mentioned in the reminder text. + return true; } - } diff --git a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java index dd46c9d9d7..c25c06d639 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java @@ -59,11 +59,11 @@ public class EternalizeAbility extends ActivatedAbilityImpl { this.timing = TimingRule.SORCERY; setRule(cost, card); } - + public EternalizeAbility(Cost cost, Card card, String rule) { this(cost, card); this.rule = rule; - } + } public EternalizeAbility(final EternalizeAbility ability) { super(ability); @@ -110,26 +110,27 @@ class EternalizeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) - token.getColor(game).setColor(ObjectColor.BLACK); - if (!token.hasSubtype(SubType.ZOMBIE, game)) { - token.getSubtype(game).add(0, SubType.ZOMBIE); - } - token.getManaCost().clear(); - token.removePTCDA(); - token.getPower().modifyBaseValue(4); - token.getToughness().modifyBaseValue(4); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); - // Probably it makes sense to remove also the Eternalize ability (it's not shown on the token cards). - // Also it can never get active or? But it's not mentioned in the reminder text. - return true; + if (card == null) { + return false; } - - return false; + Player controller = game.getPlayer(card.getOwnerId()); + if (controller == null) { + return false; + } + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.BLACK); + if (!token.hasSubtype(SubType.ZOMBIE, game)) { + token.getSubtype(game).add(0, SubType.ZOMBIE); + } + token.getManaCost().clear(); + token.removePTCDA(); + token.getPower().modifyBaseValue(4); + token.getToughness().modifyBaseValue(4); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); + token.putOntoBattlefield(1, game, source.getSourceId(), controller.getId(), false, false, null); + // Probably it makes sense to remove also the Eternalize ability (it's not shown on the token cards). + // Also it can never get active or? But it's not mentioned in the reminder text. + return true; } - } From 302e0ff6157f8c989f2b8f3de54bee9a68c30b06 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Oct 2017 13:44:59 -0400 Subject: [PATCH 037/164] added Heroes of the Realm to spoiler data --- Utils/known-sets.txt | 1 + Utils/mtg-cards-data.txt | 3 +++ Utils/mtg-sets-data.txt | 1 + 3 files changed, 5 insertions(+) diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index 1f20dfa9a9..15cf441444 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -90,6 +90,7 @@ Grand Prix|GrandPrix| Guildpact|Guildpact| Guru|Guru| HASCON Promo 2017|HasconPromo2017| +Heroes of the Realm|HeroesOfTheRealm| Homelands|Homelands| Hour of Devastation|HourOfDevastation| Ice Age|IceAge| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 50afc19e1c..1152e94dc2 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32693,3 +32693,6 @@ Mountain|Duel Decks: Mind vs. Might|62|L||Basic Land - Mountain|||{T}: Add {R} t Forest|Duel Decks: Mind vs. Might|63|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| Forest|Duel Decks: Mind vs. Might|64|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| Forest|Duel Decks: Mind vs. Might|65|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| +Chandra, Gremlin Wrangler|Heroes of the Realm|1|M|{2}{R}{R}|Legendary Planeswalker - Chandra|3||+1: Create a 2/2 red Gremlin creature token.$-2:Chandra, Gremlin Wrangler deals X damage to target creature or player, where X is the number of Gremlins you control.| +Dungeon Master|Heroes of the Realm|1|M|{2}{W}{U}|Legendary Planeswalker - Dungeon Master|||+1: Target opponent creates a 1/1 black Skeleton creature token with “When this creature dies, each opponent loses 2 life.”$+1: Roll a d20. If you roll a 1, skip your next turn. If you roll a 12 or higher, draw a card.$-6: You get an adventuring party. (Your party is a 3/3 red Fighter with first strike, a 1/1 white Cleric with lifelink, a 2/2 black Rogue with hexproof, and a 1/1 blue Wizard with flying.)| +Nira, Hellkite Duelist|Heroes of the Realm|3|M|{W}{U}{B}{R}{G}|Legendary Creature — Dragon|6|6|Flash$Flying, trample, haste$When Nira, Hellkite Duelist enters the battlefield, the next time you would lose the game this turn, instead draw three cards and your life total becomes 5.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index f5b538022d..e5bd417a30 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -93,6 +93,7 @@ Gatecrash|GTC| Guru|GUR| Premium Deck Series: Slivers|H09| Homelands|HML| +Heroes of the Realm|HOTR| Planechase|HOP| Hour of Devastation|HOU| Ice Age|ICE| From d7a8e7c7e687bdf7739a4503a90f7923f33493c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 11 Oct 2017 18:38:34 -0400 Subject: [PATCH 038/164] fixed Haunting Wind not working at all (fixes #4104) --- Mage.Sets/src/mage/cards/h/HauntingWind.java | 70 +++++++++++++++----- Mage.Sets/src/mage/cards/p/Powerleech.java | 64 +++++++++++++----- 2 files changed, 102 insertions(+), 32 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HauntingWind.java b/Mage.Sets/src/mage/cards/h/HauntingWind.java index 447bded4d1..4533661fbb 100644 --- a/Mage.Sets/src/mage/cards/h/HauntingWind.java +++ b/Mage.Sets/src/mage/cards/h/HauntingWind.java @@ -29,7 +29,10 @@ package mage.cards.h; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -37,19 +40,20 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; +import mage.target.targetpointer.FixedTarget; /** * - * @author MarcoMarin + * @author TheElk801 */ public class HauntingWind extends CardImpl { public HauntingWind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); // Whenever an artifact becomes tapped or a player activates an artifact's ability without {tap} in its activation cost, Haunting Wind deals 1 damage to that artifact's controller. - - this.addAbility(new AbilityActivatedTriggeredAbility2()); + this.addAbility(new HauntingWindTriggeredAbility()); } public HauntingWind(final HauntingWind card) { @@ -62,36 +66,68 @@ public class HauntingWind extends CardImpl { } } -class AbilityActivatedTriggeredAbility2 extends TriggeredAbilityImpl { +class HauntingWindTriggeredAbility extends TriggeredAbilityImpl { - AbilityActivatedTriggeredAbility2() { - super(Zone.BATTLEFIELD, new DamageControllerEffect(1)); + HauntingWindTriggeredAbility() { + super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); } - AbilityActivatedTriggeredAbility2(final AbilityActivatedTriggeredAbility2 ability) { + HauntingWindTriggeredAbility(final HauntingWindTriggeredAbility ability) { super(ability); } @Override - public AbilityActivatedTriggeredAbility2 copy() { - return new AbilityActivatedTriggeredAbility2(this); + public HauntingWindTriggeredAbility copy() { + return new HauntingWindTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY || - event.getType() == GameEvent.EventType.TAPPED; + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY + || event.getType() == GameEvent.EventType.TAPPED; } @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent isArtifact = game.getPermanent(event.getSourceId()); - return isArtifact != null && isArtifact.isArtifact(); - + if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null) { + return false; + } + boolean triggerable = true; + for (Cost cost : stackAbility.getCosts()) { + if (cost instanceof TapSourceCost) { + triggerable = false; + break; + } + } + if (!triggerable) { + return false; + } + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent.getControllerId(), game)); + } + return true; + } + if (event.getType() == GameEvent.EventType.TAPPED) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent.getControllerId(), game)); + } + return true; + } + return false; } @Override public String getRule() { - return "Whenever an artifact becomes tapped or a player activates an artifact's ability without {tap} in its activation cost, Haunting Wind deals 1 damage to that artifact's controller."; + return "Whenever an artifact becomes tapped or a player activates an artifact's ability without {T} in its activation cost, {this} deals 1 damage to that artifact's controller."; } } diff --git a/Mage.Sets/src/mage/cards/p/Powerleech.java b/Mage.Sets/src/mage/cards/p/Powerleech.java index 6b46809e8e..ed876daebf 100644 --- a/Mage.Sets/src/mage/cards/p/Powerleech.java +++ b/Mage.Sets/src/mage/cards/p/Powerleech.java @@ -29,6 +29,8 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,18 +39,20 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; +import mage.players.Player; /** * - * @author MarcoMarin + * @author TheElk801 */ public class Powerleech extends CardImpl { public Powerleech(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}{G}"); // Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {tap} in its activation cost, you gain 1 life. - this.addAbility(new AbilityActivatedTriggeredAbility3()); + this.addAbility(new PowerleechTriggeredAbility()); } public Powerleech(final Powerleech card) { @@ -60,37 +64,67 @@ public class Powerleech extends CardImpl { return new Powerleech(this); } } -class AbilityActivatedTriggeredAbility3 extends TriggeredAbilityImpl { - AbilityActivatedTriggeredAbility3() { +class PowerleechTriggeredAbility extends TriggeredAbilityImpl { + + PowerleechTriggeredAbility() { super(Zone.BATTLEFIELD, new GainLifeEffect(1)); } - AbilityActivatedTriggeredAbility3(final AbilityActivatedTriggeredAbility3 ability) { + PowerleechTriggeredAbility(final PowerleechTriggeredAbility ability) { super(ability); } @Override - public AbilityActivatedTriggeredAbility3 copy() { - return new AbilityActivatedTriggeredAbility3(this); + public PowerleechTriggeredAbility copy() { + return new PowerleechTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY || - event.getType() == GameEvent.EventType.TAPPED; + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY + || event.getType() == GameEvent.EventType.TAPPED; } @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent isArtifact = game.getPermanent(event.getSourceId()); - return isArtifact != null && isArtifact.isArtifact() && - !isArtifact.getControllerId().equals(this.getControllerId()); - + Player player = game.getPlayer(controllerId); + if (player == null) { + return false; + } + if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null) { + return false; + } + boolean triggerable = true; + for (Cost cost : stackAbility.getCosts()) { + if (cost instanceof TapSourceCost) { + triggerable = false; + break; + } + } + if (!triggerable) { + return false; + } + return player.hasOpponent(permanent.getControllerId(), game); + } + if (event.getType() == GameEvent.EventType.TAPPED) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + return player.hasOpponent(permanent.getControllerId(), game); + } + return false; } @Override public String getRule() { - return "Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {tap} in its activation cost, you gain 1 life."; + return "Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {T} in its activation cost, you gain 1 life."; } } From 0fc3afb235bf9bde31e5aeacd0e6aad9ca43c8fc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 07:56:45 -0400 Subject: [PATCH 039/164] fixed Evangelize not being castable when caster controls no creatures. (fixes #4094) --- .../TargetOpponentsChoicePermanent.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java b/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java index 813ae0951d..5dce07ed4c 100644 --- a/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java +++ b/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java @@ -6,6 +6,7 @@ package mage.target.common; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.constants.Outcome; import mage.filter.FilterPermanent; @@ -49,7 +50,7 @@ public class TargetOpponentsChoicePermanent extends TargetPermanent { if (opponentId != null) { if (permanent != null) { if (source != null) { - boolean canSourceControllerTarget = true; + boolean canSourceControllerTarget = true; if (!isNotTarget()) { if (!permanent.canBeTargetedBy(game.getObject(source.getId()), controllerId, game) || !permanent.canBeTargetedBy(game.getObject(source.getSourceId()), controllerId, game)) { @@ -70,6 +71,33 @@ public class TargetOpponentsChoicePermanent extends TargetPermanent { return super.chooseTarget(outcome, getOpponentId(playerId, source, game), source, game); } + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + MageObject sourceObject = game.getObject(sourceId); + Player player = game.getPlayer(sourceControllerId); + if (sourceObject == null || player == null) { + return false; + } + int counter; + for (UUID oppId : game.getState().getPlayersInRange(player.getId(), game)) { + counter = 0; + Player opp = game.getPlayer(oppId); + if (opp != null && player.hasOpponent(opp.getId(), game)) { + for (Permanent perm : game.getBattlefield().getActivePermanents(opp.getId(), game)) { + if (!targets.containsKey(perm.getId()) + && filter.match(perm, sourceId, opp.getId(), game) + && perm.canBeTargetedBy(sourceObject, sourceControllerId, game)) { + counter++; + if (counter >= minNumberOfTargets) { + return true; + } + } + } + } + } + return false; + } + @Override public TargetOpponentsChoicePermanent copy() { return new TargetOpponentsChoicePermanent(this); From c86d8758668e51d28be73031190d85c3f38d7d0b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:28:55 +0200 Subject: [PATCH 040/164] Typo fix --- Mage.Sets/src/mage/cards/s/Stasis.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/Stasis.java b/Mage.Sets/src/mage/cards/s/Stasis.java index 44923e092f..ef56caaa70 100644 --- a/Mage.Sets/src/mage/cards/s/Stasis.java +++ b/Mage.Sets/src/mage/cards/s/Stasis.java @@ -76,7 +76,7 @@ class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { public SkipUntapStepEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral, false, false); - staticText = "Players skip their uptap steps"; + staticText = "Players skip their untap steps"; } public SkipUntapStepEffect(final SkipUntapStepEffect effect) { From 73773b8bb077b05eab55bd7641c3741cd0235339 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:31:09 +0200 Subject: [PATCH 041/164] Implemented Chaos Harlequin --- .../src/mage/cards/c/ChaosHarlequin.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChaosHarlequin.java diff --git a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java new file mode 100644 index 0000000000..3019e30d82 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java @@ -0,0 +1,107 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author L_J + */ +public class ChaosHarlequin extends CardImpl { + + public ChaosHarlequin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // {R}: Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChaosHarlequinEffect(), new ManaCostsImpl("{R}"))); + } + + public ChaosHarlequin(final ChaosHarlequin card) { + super(card); + } + + @Override + public ChaosHarlequin copy() { + return new ChaosHarlequin(this); + } +} + +class ChaosHarlequinEffect extends OneShotEffect { + + public ChaosHarlequinEffect() { + super(Outcome.Benefit); + this.staticText = "Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn"; + } + + public ChaosHarlequinEffect(final ChaosHarlequinEffect effect) { + super(effect); + } + + @Override + public ChaosHarlequinEffect copy() { + return new ChaosHarlequinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Card card = player.getLibrary().removeFromTop(game); + if (card != null) { + player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(-4, 0, Duration.EndOfTurn), source); + } else { + game.addEffect(new BoostSourceEffect(2, 0, Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} From e11e47e668bbe8587d6f64fa90758775e40a515c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:32:19 +0200 Subject: [PATCH 042/164] Implemented Echo Chamber --- Mage.Sets/src/mage/cards/e/EchoChamber.java | 113 ++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EchoChamber.java diff --git a/Mage.Sets/src/mage/cards/e/EchoChamber.java b/Mage.Sets/src/mage/cards/e/EchoChamber.java new file mode 100644 index 0000000000..7e0263f88a --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EchoChamber.java @@ -0,0 +1,113 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.common.TargetOpponentsChoicePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class EchoChamber extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + + public EchoChamber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // {4}, {tap}: An opponent chooses target creature he or she controls. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step. Activate this ability only any time you could cast a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new EchoChamberCreateTokenEffect(), new GenericManaCost(4)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filter, false, true)); + this.addAbility(ability); + } + + public EchoChamber(final EchoChamber card) { + super(card); + } + + @Override + public EchoChamber copy() { + return new EchoChamber(this); + } +} + +class EchoChamberCreateTokenEffect extends OneShotEffect { + + EchoChamberCreateTokenEffect() { + super(Outcome.Copy); + this.staticText = "An opponent chooses target creature he or she controls. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step"; + } + + EchoChamberCreateTokenEffect(final EchoChamberCreateTokenEffect effect) { + super(effect); + } + + @Override + public EchoChamberCreateTokenEffect copy() { + return new EchoChamberCreateTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent copiedPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + if (copiedPermanent != null) { + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.CREATURE, true); + if (effect.apply(game, source)) { + for (Permanent copyPermanent : effect.getAddedPermanent()) { + ExileTargetEffect exileEffect = new ExileTargetEffect(); + exileEffect.setTargetPointer(new FixedTarget(copyPermanent, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); + } + return true; + } + } + return false; + } +} From 1bd914f26b84f7d7dd58a676419fc3d2ec325767 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:33:28 +0200 Subject: [PATCH 043/164] Implemented Sands of Time --- Mage.Sets/src/mage/cards/s/SandsOfTime.java | 143 ++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SandsOfTime.java diff --git a/Mage.Sets/src/mage/cards/s/SandsOfTime.java b/Mage.Sets/src/mage/cards/s/SandsOfTime.java new file mode 100644 index 0000000000..05f28b163a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SandsOfTime.java @@ -0,0 +1,143 @@ +/* + * 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.s; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author L_J + */ +public class SandsOfTime extends CardImpl { + + public SandsOfTime(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // Each player skips his or her untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipUntapStepEffect())); + + // At the beginning of each player's upkeep, that player simultaneously untaps each tapped artifact, creature, and land he or she controls and taps each untapped artifact, creature, and land he or she controls. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SandsOfTimeEffect(), TargetController.ANY, false)); + } + + public SandsOfTime(final SandsOfTime card) { + super(card); + } + + @Override + public SandsOfTime copy() { + return new SandsOfTime(this); + } +} + +class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { + + public SkipUntapStepEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral, false, false); + staticText = "Players skip their untap steps"; + } + + public SkipUntapStepEffect(final SkipUntapStepEffect effect) { + super(effect); + } + + @Override + public SkipUntapStepEffect copy() { + return new SkipUntapStepEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + return event.getType() == GameEvent.EventType.UNTAP_STEP + && controller != null + && game.getState().getPlayersInRange(controller.getId(), game).contains(event.getPlayerId()); + } +} + +class SandsOfTimeEffect extends OneShotEffect { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND))); + } + + public SandsOfTimeEffect() { + super(Outcome.Neutral); + staticText = "that player simultaneously untaps each tapped artifact, creature, and land he or she controls and taps each untapped artifact, creature, and land he or she controls"; + } + + public SandsOfTimeEffect(SandsOfTimeEffect copy) { + super(copy); + } + + @Override + public SandsOfTimeEffect copy() { + return new SandsOfTimeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPointer.getFirst(game, source), game)) { + if (permanent.isTapped()) { + permanent.untap(game); + } else { + permanent.tap(game); + } + } + return true; + } + return false; + } +} From e529259d3677305acca9fc5e73ad757094bfb6df Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:34:36 +0200 Subject: [PATCH 044/164] Implemented Sands of Time --- Mage.Sets/src/mage/sets/Visions.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index c5ca00bb6e..aae2e5afb1 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -54,7 +54,7 @@ public class Visions extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Aku Djinn", 1, Rarity.RARE, mage.cards.a.AkuDjinn.class)); + cards.add(new SetCardInfo("Aku Djinn", 1, Rarity.RARE, mage.cards.a.AkuDjinn.class)); cards.add(new SetCardInfo("Anvil of Bogardan", 141, Rarity.RARE, mage.cards.a.AnvilOfBogardan.class)); cards.add(new SetCardInfo("Archangel", 101, Rarity.RARE, mage.cards.a.Archangel.class)); cards.add(new SetCardInfo("Army Ants", 126, Rarity.UNCOMMON, mage.cards.a.ArmyAnts.class)); @@ -105,7 +105,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Impulse", 34, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Infantry Veteran", 109, Rarity.COMMON, mage.cards.i.InfantryVeteran.class)); cards.add(new SetCardInfo("Inspiration", 35, Rarity.COMMON, mage.cards.i.Inspiration.class)); - cards.add(new SetCardInfo("Iron-Heart Chimera", 146, Rarity.UNCOMMON, mage.cards.i.IronHeartChimera.class)); + cards.add(new SetCardInfo("Iron-Heart Chimera", 146, Rarity.UNCOMMON, mage.cards.i.IronHeartChimera.class)); cards.add(new SetCardInfo("Jamuraan Lion", 110, Rarity.COMMON, mage.cards.j.JamuraanLion.class)); cards.add(new SetCardInfo("Jungle Basin", 164, Rarity.UNCOMMON, mage.cards.j.JungleBasin.class)); cards.add(new SetCardInfo("Kaervek's Spite", 13, Rarity.RARE, mage.cards.k.KaerveksSpite.class)); @@ -114,10 +114,10 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Keeper of Kookus", 85, Rarity.COMMON, mage.cards.k.KeeperOfKookus.class)); cards.add(new SetCardInfo("King Cheetah", 60, Rarity.COMMON, mage.cards.k.KingCheetah.class)); cards.add(new SetCardInfo("Knight of Valor", 111, Rarity.COMMON, mage.cards.k.KnightOfValor.class)); - cards.add(new SetCardInfo("Knight of the Mists", 36, Rarity.COMMON, mage.cards.k.KnightOfTheMists.class)); - cards.add(new SetCardInfo("Kookus", 85, Rarity.RARE, mage.cards.k.Kookus.class)); - cards.add(new SetCardInfo("Lead-Belly Chimera", 148, Rarity.UNCOMMON, mage.cards.l.LeadBellyChimera.class)); - cards.add(new SetCardInfo("Lichenthrope", 62, Rarity.RARE, mage.cards.l.Lichenthrope.class)); + cards.add(new SetCardInfo("Knight of the Mists", 36, Rarity.COMMON, mage.cards.k.KnightOfTheMists.class)); + cards.add(new SetCardInfo("Kookus", 85, Rarity.RARE, mage.cards.k.Kookus.class)); + cards.add(new SetCardInfo("Lead-Belly Chimera", 148, Rarity.UNCOMMON, mage.cards.l.LeadBellyChimera.class)); + cards.add(new SetCardInfo("Lichenthrope", 62, Rarity.RARE, mage.cards.l.Lichenthrope.class)); cards.add(new SetCardInfo("Lightning Cloud", 87, Rarity.RARE, mage.cards.l.LightningCloud.class)); cards.add(new SetCardInfo("Longbow Archer", 112, Rarity.UNCOMMON, mage.cards.l.LongbowArcher.class)); cards.add(new SetCardInfo("Magma Mine", 149, Rarity.UNCOMMON, mage.cards.m.MagmaMine.class)); @@ -147,8 +147,9 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Retribution of the Meek", 119, Rarity.RARE, mage.cards.r.RetributionOfTheMeek.class)); cards.add(new SetCardInfo("Righteous Aura", 120, Rarity.COMMON, mage.cards.r.RighteousAura.class)); cards.add(new SetCardInfo("River Boa", 68, Rarity.COMMON, mage.cards.r.RiverBoa.class)); - cards.add(new SetCardInfo("Rock Slide", 92, Rarity.COMMON, mage.cards.r.RockSlide.class)); + cards.add(new SetCardInfo("Rock Slide", 92, Rarity.COMMON, mage.cards.r.RockSlide.class)); cards.add(new SetCardInfo("Rowen", 69, Rarity.RARE, mage.cards.r.Rowen.class)); + cards.add(new SetCardInfo("Sands of Time", 153, Rarity.RARE, mage.cards.s.SandsOfTime.class)); cards.add(new SetCardInfo("Scalebane's Elite", 135, Rarity.UNCOMMON, mage.cards.s.ScalebanesElite.class)); cards.add(new SetCardInfo("Shrieking Drake", 43, Rarity.COMMON, mage.cards.s.ShriekingDrake.class)); cards.add(new SetCardInfo("Simoon", 136, Rarity.UNCOMMON, mage.cards.s.Simoon.class)); @@ -171,7 +172,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Teferi's Realm", 44, Rarity.RARE, mage.cards.t.TeferisRealm.class)); cards.add(new SetCardInfo("Tempest Drake", 139, Rarity.UNCOMMON, mage.cards.t.TempestDrake.class)); cards.add(new SetCardInfo("Three Wishes", 45, Rarity.RARE, mage.cards.t.ThreeWishes.class)); - cards.add(new SetCardInfo("Tin-Wing Chimera", 157, Rarity.UNCOMMON, mage.cards.t.TinWingChimera.class)); + cards.add(new SetCardInfo("Tin-Wing Chimera", 157, Rarity.UNCOMMON, mage.cards.t.TinWingChimera.class)); cards.add(new SetCardInfo("Tithe", 123, Rarity.RARE, mage.cards.t.Tithe.class)); cards.add(new SetCardInfo("Tremor", 99, Rarity.COMMON, mage.cards.t.Tremor.class)); cards.add(new SetCardInfo("Triangle of War", 158, Rarity.RARE, mage.cards.t.TriangleOfWar.class)); From 19eebc939ee37f138b72ddd5c66c5da1de844ea6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:35:12 +0200 Subject: [PATCH 045/164] Implemented Echo Chamber --- Mage.Sets/src/mage/sets/Tempest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Tempest.java b/Mage.Sets/src/mage/sets/Tempest.java index ddf3186ae4..eb67ac2a83 100644 --- a/Mage.Sets/src/mage/sets/Tempest.java +++ b/Mage.Sets/src/mage/sets/Tempest.java @@ -97,6 +97,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Dream Cache", 59, Rarity.COMMON, mage.cards.d.DreamCache.class)); cards.add(new SetCardInfo("Dregs of Sorrow", 25, Rarity.RARE, mage.cards.d.DregsOfSorrow.class)); cards.add(new SetCardInfo("Earthcraft", 116, Rarity.RARE, mage.cards.e.Earthcraft.class)); + cards.add(new SetCardInfo("Echo Chamber", 272, Rarity.RARE, mage.cards.e.EchoChamber.class)); cards.add(new SetCardInfo("Eladamri, Lord of Leaves", 117, Rarity.RARE, mage.cards.e.EladamriLordOfLeaves.class)); cards.add(new SetCardInfo("Eladamri's Vineyard", 118, Rarity.RARE, mage.cards.e.EladamrisVineyard.class)); cards.add(new SetCardInfo("Elite Javelineer", 229, Rarity.COMMON, mage.cards.e.EliteJavelineer.class)); @@ -156,7 +157,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Humility", 236, Rarity.RARE, mage.cards.h.Humility.class)); cards.add(new SetCardInfo("Imps' Taunt", 32, Rarity.UNCOMMON, mage.cards.i.ImpsTaunt.class)); cards.add(new SetCardInfo("Insight", 68, Rarity.UNCOMMON, mage.cards.i.Insight.class)); - cards.add(new SetCardInfo("Interdict", 69, Rarity.UNCOMMON, mage.cards.i.Interdict.class)); + cards.add(new SetCardInfo("Interdict", 69, Rarity.UNCOMMON, mage.cards.i.Interdict.class)); cards.add(new SetCardInfo("Intuition", 70, Rarity.RARE, mage.cards.i.Intuition.class)); cards.add(new SetCardInfo("Invulnerability", 237, Rarity.UNCOMMON, mage.cards.i.Invulnerability.class)); cards.add(new SetCardInfo("Island", 313, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -319,7 +320,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 335, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 336, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 337, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tahngarth's Rage", 209, Rarity.UNCOMMON, mage.cards.t.TahngarthsRage.class)); + cards.add(new SetCardInfo("Tahngarth's Rage", 209, Rarity.UNCOMMON, mage.cards.t.TahngarthsRage.class)); cards.add(new SetCardInfo("Talon Sliver", 262, Rarity.COMMON, mage.cards.t.TalonSliver.class)); cards.add(new SetCardInfo("Telethopter", 301, Rarity.UNCOMMON, mage.cards.t.Telethopter.class)); cards.add(new SetCardInfo("Thalakos Dreamsower", 92, Rarity.UNCOMMON, mage.cards.t.ThalakosDreamsower.class)); From f6274206ee42928a01c5fe9358b670f3a50b9b8d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:37:51 +0200 Subject: [PATCH 046/164] Implemented Energy Arc --- Mage.Sets/src/mage/cards/e/EnergyArc.java | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EnergyArc.java diff --git a/Mage.Sets/src/mage/cards/e/EnergyArc.java b/Mage.Sets/src/mage/cards/e/EnergyArc.java new file mode 100644 index 0000000000..654fc01850 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnergyArc.java @@ -0,0 +1,67 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class EnergyArc extends CardImpl { + + public EnergyArc(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}{U}"); + + // Untap any number of target creatures. Prevent all combat damage that would be dealt to and dealt by those creatures this turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); + this.getSpellAbility().addEffect(new UntapTargetEffect()); + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE, true)); + } + + public EnergyArc(final EnergyArc card) { + super(card); + } + + @Override + public EnergyArc copy() { + return new EnergyArc(this); + } +} From 8334338249f4a4e072e2d9e66e96387c645eaed0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:39:09 +0200 Subject: [PATCH 047/164] Implemented Hail Storm --- Mage.Sets/src/mage/cards/h/HailStorm.java | 69 +++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HailStorm.java diff --git a/Mage.Sets/src/mage/cards/h/HailStorm.java b/Mage.Sets/src/mage/cards/h/HailStorm.java new file mode 100644 index 0000000000..a0c52a3e50 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HailStorm.java @@ -0,0 +1,69 @@ +/* + * 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.h; + +import java.util.UUID; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.DamageControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author L_J + */ +public class HailStorm extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public HailStorm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}{G}"); + + // Hail Storm deals 2 damage to each attacking creature and 1 damage to you and each creature you control. + this.getSpellAbility().addEffect(new DamageAllEffect(2, new FilterAttackingCreature())); + this.getSpellAbility().addEffect(new DamageControllerEffect(1)); + this.getSpellAbility().addEffect(new DamageAllEffect(1, filter)); + } + + public HailStorm(final HailStorm card) { + super(card); + } + + @Override + public HailStorm copy() { + return new HailStorm(this); + } +} From aaacb561592517bf70aaf0a1f8aa339d2e4bd5c3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:40:09 +0200 Subject: [PATCH 048/164] Implemented Mishra's Groundbreaker --- .../mage/cards/m/MishrasGroundbreaker.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java diff --git a/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java b/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java new file mode 100644 index 0000000000..d5ab8fe131 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java @@ -0,0 +1,82 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.permanent.token.Token; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author L_J + */ +public class MishrasGroundbreaker extends CardImpl { + + public MishrasGroundbreaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + + // {tap}, Sacrifice Mishra's Groundbreaker: Target land becomes a 3/3 artifact creature that's still a land. (This effect lasts indefinitely.) + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(new MishrasGroundbreakerToken(), false, true, Duration.EndOfGame), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(ability); + } + + public MishrasGroundbreaker(final MishrasGroundbreaker card) { + super(card); + } + + @Override + public MishrasGroundbreaker copy() { + return new MishrasGroundbreaker(this); + } + +} + +class MishrasGroundbreakerToken extends Token { + + public MishrasGroundbreakerToken() { + super("", "3/3 artifact creature"); + this.cardType.add(CardType.ARTIFACT); + this.cardType.add(CardType.CREATURE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + } +} From a48aa1e78e1bd02a60ce61a01774cbda294d9289 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:41:33 +0200 Subject: [PATCH 049/164] Implemented Omen of Fire --- Mage.Sets/src/mage/cards/o/OmenOfFire.java | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OmenOfFire.java diff --git a/Mage.Sets/src/mage/cards/o/OmenOfFire.java b/Mage.Sets/src/mage/cards/o/OmenOfFire.java new file mode 100644 index 0000000000..298366f46d --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OmenOfFire.java @@ -0,0 +1,128 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class OmenOfFire extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("Islands"); + static { + filter.add(new SubtypePredicate(SubType.ISLAND)); + } + + public OmenOfFire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}{R}"); + + // Return all Islands to their owners' hands. + this.getSpellAbility().addEffect(new ReturnToHandFromBattlefieldAllEffect(filter)); + + // Each player sacrifices a Plains or a white permanent for each white permanent he or she controls. + this.getSpellAbility().addEffect(new OmenOfFireEffect()); + } + + public OmenOfFire(final OmenOfFire card) { + super(card); + } + + @Override + public OmenOfFire copy() { + return new OmenOfFire(this); + } +} + +class OmenOfFireEffect extends OneShotEffect { + + private static final FilterPermanent filterWhite1 = new FilterPermanent("Plains or white permanent"); + static { + filterWhite1.add(Predicates.or( + new SubtypePredicate(SubType.PLAINS), + new ColorPredicate(ObjectColor.WHITE))); + } + + private static final FilterPermanent filterWhite2 = new FilterPermanent("white permanent"); + static { + filterWhite2.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public OmenOfFireEffect() { + super(Outcome.Detriment); + this.staticText = "Each player sacrifices a Plains or a white permanent for each white permanent he or she controls"; + } + + public OmenOfFireEffect(final OmenOfFireEffect effect) { + super(effect); + } + + @Override + public OmenOfFireEffect copy() { + return new OmenOfFireEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int whitePermanents = game.getBattlefield().countAll(filterWhite2, playerId, game); + if (whitePermanents > 0) { + Effect effect = new SacrificeEffect(filterWhite1, whitePermanents, ""); + effect.setTargetPointer(new FixedTarget(playerId)); + effect.apply(game, source); + } + } + } + return true; + } + return false; + } +} From b7f3cf2fbff7d5580c873c2c5db077e49167962c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:42:28 +0200 Subject: [PATCH 050/164] Implemented Royal Decree --- Mage.Sets/src/mage/cards/r/RoyalDecree.java | 128 ++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RoyalDecree.java diff --git a/Mage.Sets/src/mage/cards/r/RoyalDecree.java b/Mage.Sets/src/mage/cards/r/RoyalDecree.java new file mode 100644 index 0000000000..542d7db4e2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RoyalDecree.java @@ -0,0 +1,128 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class RoyalDecree extends CardImpl { + + public RoyalDecree(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); + + // Cumulative upkeep-Pay {W}. + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{W}"))); + + // Whenever a Swamp, Mountain, black permanent, or red permanent becomes tapped, Royal Decree deals 1 damage to that permanent's controller. + this.addAbility(new RoyalDecreeAbility()); + } + + public RoyalDecree(final RoyalDecree card) { + super(card); + } + + @Override + public RoyalDecree copy() { + return new RoyalDecree(this); + } +} + +class RoyalDecreeAbility extends TriggeredAbilityImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Swamp, Mountain, black permanent, or red permanent"); + static { + filter.add(Predicates.or( + new SubtypePredicate(SubType.SWAMP), + new SubtypePredicate(SubType.MOUNTAIN), + new ColorPredicate(ObjectColor.BLACK), + new ColorPredicate(ObjectColor.RED))); + } + + public RoyalDecreeAbility() { + super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); + } + + RoyalDecreeAbility(final RoyalDecreeAbility ability) { + super(ability); + } + + @Override + public RoyalDecreeAbility copy() { + return new RoyalDecreeAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TAPPED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { + Player player = game.getPlayer(permanent.getControllerId()); + if (player != null) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(player.getId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a Swamp, Mountain, black permanent, or red permanent becomes tapped, Royal Decree deals 1 damage to that permanent's controller."; + } +} From 885b6ca45848e4359f1dc38ed39dfc5e65d38a00 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:43:33 +0200 Subject: [PATCH 051/164] Implemented Soldevi Heretic --- .../src/mage/cards/s/SoldeviHeretic.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoldeviHeretic.java diff --git a/Mage.Sets/src/mage/cards/s/SoldeviHeretic.java b/Mage.Sets/src/mage/cards/s/SoldeviHeretic.java new file mode 100644 index 0000000000..ac59ef8c8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoldeviHeretic.java @@ -0,0 +1,81 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author L_J + */ +public class SoldeviHeretic extends CardImpl { + + public SoldeviHeretic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {W}, {tap}: Prevent the next 2 damage that would be dealt to target creature this turn. Target opponent may draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn ,2), new ManaCostsImpl("{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + Effect effect = new DrawCardTargetEffect(1, true); + effect.setTargetPointer(new SecondTargetPointer()); + ability.addEffect(effect); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public SoldeviHeretic(final SoldeviHeretic card) { + super(card); + } + + @Override + public SoldeviHeretic copy() { + return new SoldeviHeretic(this); + } +} From fa7fe38225c63de7d129a5d2d8535453afe26f4f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:44:09 +0200 Subject: [PATCH 052/164] Implemented Surge of Strength --- .../src/mage/cards/s/SurgeOfStrength.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SurgeOfStrength.java diff --git a/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java b/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java new file mode 100644 index 0000000000..a6523b8cdd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java @@ -0,0 +1,85 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.dynamicvalue.common.TargetConvertedManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class SurgeOfStrength extends CardImpl { + + private static final FilterCard filter = new FilterCard("a red or green card"); + static{ + filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN))); + } + + public SurgeOfStrength(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}{G}"); + + // As an additional cost to cast Surge of Strength, discard a red or green card. + this.getSpellAbility().addCost(new DiscardTargetCost(new TargetCardInHand(filter))); + + // Target creature gains trample and gets +X/+0 until end of turn, where X is that creature's converted mana cost. + Effect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText("Target creature gains trample"); + this.getSpellAbility().addEffect(effect); + effect = new BoostTargetEffect(new TargetConvertedManaCost(), new StaticValue(0), Duration.EndOfTurn, true); + effect.setText("and gets +X/+0 until end of turn, where X is that creature's converted mana cost"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public SurgeOfStrength(final SurgeOfStrength card) { + super(card); + } + + @Override + public SurgeOfStrength copy() { + return new SurgeOfStrength(this); + } +} From fa476e82f634ecbbb6ff28123c3182ae03e2df13 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:44:55 +0200 Subject: [PATCH 053/164] Implemented Varchild's Crusader --- .../src/mage/cards/v/VarchildsCrusader.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VarchildsCrusader.java diff --git a/Mage.Sets/src/mage/cards/v/VarchildsCrusader.java b/Mage.Sets/src/mage/cards/v/VarchildsCrusader.java new file mode 100644 index 0000000000..64fa6a0c6e --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VarchildsCrusader.java @@ -0,0 +1,83 @@ +/* + * 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.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author L_J + */ +public class VarchildsCrusader extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("except by Walls"); + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.WALL))); + } + + public VarchildsCrusader(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // {0}: Varchild's Crusader can't be blocked this turn except by Walls. Sacrifice Varchild's Crusader at the beginning of the next end step. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesSourceEffect(filter, Duration.EndOfTurn), new GenericManaCost(0)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()))); + this.addAbility(ability); + } + + public VarchildsCrusader(final VarchildsCrusader card) { + super(card); + } + + @Override + public VarchildsCrusader copy() { + return new VarchildsCrusader(this); + } + +} From 1bf00a3d3dba45009c3155657b3008d35e81084c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:45:33 +0200 Subject: [PATCH 054/164] Implemented Whirling Catapult --- .../src/mage/cards/w/WhirlingCatapult.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WhirlingCatapult.java diff --git a/Mage.Sets/src/mage/cards/w/WhirlingCatapult.java b/Mage.Sets/src/mage/cards/w/WhirlingCatapult.java new file mode 100644 index 0000000000..6f943a8593 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WhirlingCatapult.java @@ -0,0 +1,72 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ExileFromTopOfLibraryCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageEverythingEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; + +/** + * + * @author L_J + */ +public class WhirlingCatapult extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public WhirlingCatapult(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + + // {2}, Exile the top two cards of your library: Whirling Catapult deals 1 damage to each creature with flying and each player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(1, filter), new ManaCostsImpl("{2}")); + ability.addCost(new ExileFromTopOfLibraryCost(2)); + this.addAbility(ability); + } + + public WhirlingCatapult(final WhirlingCatapult card) { + super(card); + } + + @Override + public WhirlingCatapult copy() { + return new WhirlingCatapult(this); + } +} From 1c0c9453b684a4aff76f331ba578ddbec6cf1797 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:46:30 +0200 Subject: [PATCH 055/164] Implemented Winter's Night --- Mage.Sets/src/mage/cards/w/WintersNight.java | 80 ++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WintersNight.java diff --git a/Mage.Sets/src/mage/cards/w/WintersNight.java b/Mage.Sets/src/mage/cards/w/WintersNight.java new file mode 100644 index 0000000000..db0cc8e032 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WintersNight.java @@ -0,0 +1,80 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.TapForManaAllTriggeredManaAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AddManaOfAnyTypeProducedEffect; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.ManaEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SetTargetPointer; +import mage.constants.SuperType; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class WintersNight extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("a player taps a snow land"); + { + filter.add(new SupertypePredicate(SuperType.SNOW)); + } + + public WintersNight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}{R}{G}"); + addSuperType(SuperType.WORLD); + + // Whenever a player taps a snow land for mana, that player adds one mana to his or her mana pool of any type that land produced. + // That land doesn't untap during its controller's next untap step. + ManaEffect effect = new AddManaOfAnyTypeProducedEffect(); + effect.setText("that player adds one mana to his or her mana pool of any type that land produced"); + Ability ability = new TapForManaAllTriggeredManaAbility(effect, filter, SetTargetPointer.PERMANENT); + Effect effect2 = new DontUntapInControllersNextUntapStepTargetEffect(); + effect2.setText("That land doesn't untap during its controller's next untap step"); + ability.addEffect(effect2); + this.addAbility(ability); + } + + public WintersNight(final WintersNight card) { + super(card); + } + + @Override + public WintersNight copy() { + return new WintersNight(this); + } +} From 982a8b4059cc21fe1e9a01224f1f5f99384bedf9 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 17:49:50 +0200 Subject: [PATCH 056/164] Implemented lots of cards --- Mage.Sets/src/mage/sets/Alliances.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 83f5324d81..f4967a7168 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -58,6 +58,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Burnout", 101, Rarity.UNCOMMON, mage.cards.b.Burnout.class)); cards.add(new SetCardInfo("Carrier Pigeons", 125, Rarity.COMMON, CarrierPigeons.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Carrier Pigeons", 126, Rarity.COMMON, CarrierPigeons.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Chaos Harlequin", 102, Rarity.RARE, mage.cards.c.ChaosHarlequin.class)); cards.add(new SetCardInfo("Contagion", 4, Rarity.UNCOMMON, mage.cards.c.Contagion.class)); cards.add(new SetCardInfo("Deadly Insect", 64, Rarity.COMMON, mage.cards.d.DeadlyInsect.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deadly Insect", 65, Rarity.COMMON, mage.cards.d.DeadlyInsect.class, NON_FULL_USE_VARIOUS)); @@ -68,6 +69,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Elvish Ranger", 67, Rarity.COMMON, mage.cards.e.ElvishRanger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Elvish Ranger", 68, Rarity.COMMON, mage.cards.e.ElvishRanger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Elvish Spirit Guide", 69, Rarity.UNCOMMON, mage.cards.e.ElvishSpiritGuide.class)); + cards.add(new SetCardInfo("Energy Arc", 190, Rarity.UNCOMMON, mage.cards.e.EnergyArc.class)); cards.add(new SetCardInfo("Enslaved Scout", 104, Rarity.COMMON, EnslavedScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Enslaved Scout", 105, Rarity.COMMON, EnslavedScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Exile", 129, Rarity.RARE, mage.cards.e.Exile.class)); @@ -91,6 +93,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Gorilla War Cry", 109, Rarity.COMMON, mage.cards.g.GorillaWarCry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guerrilla Tactics", 110, Rarity.COMMON, mage.cards.g.GuerrillaTactics.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guerrilla Tactics", 111, Rarity.COMMON, mage.cards.g.GuerrillaTactics.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hail Storm", 79, Rarity.UNCOMMON, mage.cards.h.HailStorm.class)); cards.add(new SetCardInfo("Heart of Yavimaya", 183, Rarity.RARE, mage.cards.h.HeartOfYavimaya.class)); cards.add(new SetCardInfo("Helm of Obedience", 163, Rarity.RARE, mage.cards.h.HelmOfObedience.class)); cards.add(new SetCardInfo("Inheritance", 130, Rarity.UNCOMMON, mage.cards.i.Inheritance.class)); @@ -99,7 +102,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Juniper Order Advocate", 132, Rarity.UNCOMMON, mage.cards.j.JuniperOrderAdvocate.class)); cards.add(new SetCardInfo("Kaysa", 80, Rarity.RARE, mage.cards.k.Kaysa.class)); cards.add(new SetCardInfo("Keeper of Tresserhorn", 14, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); - cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); + cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 184, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); cards.add(new SetCardInfo("Lake of the Dead", 185, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); cards.add(new SetCardInfo("Library of Lat-Nam", 47, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); @@ -108,14 +111,17 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Lim-Dul's Paladin", 191, Rarity.UNCOMMON, mage.cards.l.LimDulsPaladin.class)); cards.add(new SetCardInfo("Lim-Dul's Vault", 192, Rarity.UNCOMMON, mage.cards.l.LimDulsVault.class)); cards.add(new SetCardInfo("Lord of Tresserhorn", 193, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class)); + cards.add(new SetCardInfo("Mishra's Groundbreaker", 165, Rarity.UNCOMMON, mage.cards.m.MishrasGroundbreaker.class)); cards.add(new SetCardInfo("Mystic Compass", 166, Rarity.UNCOMMON, mage.cards.m.MysticCompass.class)); cards.add(new SetCardInfo("Nature's Wrath", 82, Rarity.RARE, mage.cards.n.NaturesWrath.class)); cards.add(new SetCardInfo("Noble Steeds", 140, Rarity.COMMON, mage.cards.n.NobleSteeds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Noble Steeds", 141, Rarity.COMMON, mage.cards.n.NobleSteeds.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Omen of Fire", 112, Rarity.RARE, mage.cards.o.OmenOfFire.class)); cards.add(new SetCardInfo("Phantasmal Fiend", 20, Rarity.COMMON, mage.cards.p.PhantasmalFiend.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phantasmal Fiend", 21, Rarity.COMMON, mage.cards.p.PhantasmalFiend.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phelddagrif", 196, Rarity.RARE, mage.cards.p.Phelddagrif.class)); - cards.add(new SetCardInfo("Phyrexian Boon", 22, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class)); + cards.add(new SetCardInfo("Phyrexian Boon", 22, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Phyrexian Boon", 23, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Devourer", 167, Rarity.RARE, mage.cards.p.PhyrexianDevourer.class)); cards.add(new SetCardInfo("Phyrexian War Beast", 169, Rarity.COMMON, PhyrexianWarBeast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian War Beast", 170, Rarity.COMMON, PhyrexianWarBeast.class, NON_FULL_USE_VARIOUS)); @@ -126,6 +132,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Reprisal", 144, Rarity.COMMON, mage.cards.r.Reprisal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reprisal", 145, Rarity.COMMON, mage.cards.r.Reprisal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ritual of the Machine", 24, Rarity.RARE, mage.cards.r.RitualOfTheMachine.class)); + cards.add(new SetCardInfo("Royal Decree", 146, Rarity.RARE, mage.cards.r.RoyalDecree.class)); cards.add(new SetCardInfo("Royal Herbalist", 147, Rarity.COMMON, RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Royal Herbalist", 148, Rarity.COMMON, RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("School of the Unseen", 186, Rarity.UNCOMMON, mage.cards.s.SchoolOfTheUnseen.class)); @@ -136,6 +143,8 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Soldevi Adnate", 26, Rarity.COMMON, SoldeviAdnate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soldevi Digger", 174, Rarity.RARE, mage.cards.s.SoldeviDigger.class)); cards.add(new SetCardInfo("Soldevi Excavations", 188, Rarity.RARE, mage.cards.s.SoldeviExcavations.class)); + cards.add(new SetCardInfo("Soldevi Heretic", 49, Rarity.COMMON, mage.cards.s.SoldeviHeretic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Soldevi Heretic", 50, Rarity.COMMON, mage.cards.s.SoldeviHeretic.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soldevi Sage", 51, Rarity.COMMON, SoldeviSage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soldevi Sage", 52, Rarity.COMMON, SoldeviSage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soldier of Fortune", 117, Rarity.UNCOMMON, mage.cards.s.SoldierOfFortune.class)); @@ -147,6 +156,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Storm Crow", 55, Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Shaman", 118, Rarity.COMMON, StormShaman.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Shaman", 119, Rarity.UNCOMMON, StormShaman.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Surge of Strength", 197, Rarity.UNCOMMON, mage.cards.s.SurgeOfStrength.class)); cards.add(new SetCardInfo("Sustaining Spirit", 151, Rarity.RARE, mage.cards.s.SustainingSpirit.class)); cards.add(new SetCardInfo("Swamp Mosquito", 30, Rarity.COMMON, SwampMosquito.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp Mosquito", 31, Rarity.COMMON, SwampMosquito.class, NON_FULL_USE_VARIOUS)); @@ -155,6 +165,8 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Tidal Control", 59, Rarity.RARE, mage.cards.t.TidalControl.class)); cards.add(new SetCardInfo("Tornado", 86, Rarity.RARE, mage.cards.t.Tornado.class)); cards.add(new SetCardInfo("Unlikely Alliance", 153, Rarity.UNCOMMON, mage.cards.u.UnlikelyAlliance.class)); + cards.add(new SetCardInfo("Varchild's Crusader", 120, Rarity.COMMON, mage.cards.v.VarchildsCrusader.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Varchild's Crusader", 121, Rarity.COMMON, mage.cards.v.VarchildsCrusader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Varchild's War-Riders", 122, Rarity.RARE, mage.cards.v.VarchildsWarRiders.class)); cards.add(new SetCardInfo("Viscerid Armor", 60, Rarity.COMMON, mage.cards.v.VisceridArmor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Viscerid Armor", 61, Rarity.COMMON, mage.cards.v.VisceridArmor.class, NON_FULL_USE_VARIOUS)); @@ -162,8 +174,10 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Wandering Mage", 198, Rarity.RARE, mage.cards.w.WanderingMage.class)); cards.add(new SetCardInfo("Whip Vine", 89, Rarity.COMMON, WhipVine.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Whip Vine", 90, Rarity.COMMON, WhipVine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Whirling Catapult", 181, Rarity.UNCOMMON, mage.cards.w.WhirlingCatapult.class)); cards.add(new SetCardInfo("Wild Aesthir", 154, Rarity.COMMON, mage.cards.w.WildAesthir.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wild Aesthir", 155, Rarity.COMMON, mage.cards.w.WildAesthir.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Winter's Night", 199, Rarity.RARE, mage.cards.w.WintersNight.class)); cards.add(new SetCardInfo("Yavimaya Ancients", 91, Rarity.COMMON, mage.cards.y.YavimayaAncients.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yavimaya Ancients", 92, Rarity.COMMON, mage.cards.y.YavimayaAncients.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yavimaya Ants", 93, Rarity.UNCOMMON, mage.cards.y.YavimayaAnts.class)); From c3c8148bafca408c500cbbe69c4d72a06858e3bd Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 18:24:32 +0200 Subject: [PATCH 057/164] Create SkipUntapStepEffect.java --- .../effects/common/SkipUntapStepEffect.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java new file mode 100644 index 0000000000..ab30c40f79 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java @@ -0,0 +1,69 @@ +/* + * + * 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.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; + +/** + * + * @author L_J + */ + +public class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { + + public SkipUntapStepEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral, false, false); + staticText = "Players skip their untap steps"; + } + + public SkipUntapStepEffect(final SkipUntapStepEffect effect) { + super(effect); + } + + @Override + public SkipUntapStepEffect copy() { + return new SkipUntapStepEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + return event.getType() == GameEvent.EventType.UNTAP_STEP + && controller != null + && game.getState().getPlayersInRange(controller.getId(), game).contains(event.getPlayerId()); + } +} From 1e11028c797daf8ccdce280281d2af8ca4ac2079 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 18:27:01 +0200 Subject: [PATCH 058/164] Moved SkipUntapStepEffect to common effects --- Mage.Sets/src/mage/cards/s/Stasis.java | 34 ++------------------------ 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/Stasis.java b/Mage.Sets/src/mage/cards/s/Stasis.java index ef56caaa70..cbf628ce7c 100644 --- a/Mage.Sets/src/mage/cards/s/Stasis.java +++ b/Mage.Sets/src/mage/cards/s/Stasis.java @@ -32,22 +32,17 @@ import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.abilities.effects.common.SkipUntapStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; /** * - * @author jeffwadsworth + * @author jeffwadsworth, edited by L_J */ public class Stasis extends CardImpl { @@ -71,28 +66,3 @@ public class Stasis extends CardImpl { return new Stasis(this); } } - -class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { - - public SkipUntapStepEffect() { - super(Duration.WhileOnBattlefield, Outcome.Neutral, false, false); - staticText = "Players skip their untap steps"; - } - - public SkipUntapStepEffect(final SkipUntapStepEffect effect) { - super(effect); - } - - @Override - public SkipUntapStepEffect copy() { - return new SkipUntapStepEffect(this); - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - return event.getType() == GameEvent.EventType.UNTAP_STEP - && controller != null - && game.getState().getPlayersInRange(controller.getId(), game).contains(event.getPlayerId()); - } -} From 70bd3fe6d27ee72c5129efa8a7168d0342c30ea4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 18:27:35 +0200 Subject: [PATCH 059/164] Moved SkipUntapStepEffect to common effects --- Mage.Sets/src/mage/cards/s/SandsOfTime.java | 28 +-------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SandsOfTime.java b/Mage.Sets/src/mage/cards/s/SandsOfTime.java index 05f28b163a..14699d169d 100644 --- a/Mage.Sets/src/mage/cards/s/SandsOfTime.java +++ b/Mage.Sets/src/mage/cards/s/SandsOfTime.java @@ -32,8 +32,8 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SkipUntapStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -45,7 +45,6 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -75,31 +74,6 @@ public class SandsOfTime extends CardImpl { } } -class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { - - public SkipUntapStepEffect() { - super(Duration.WhileOnBattlefield, Outcome.Neutral, false, false); - staticText = "Players skip their untap steps"; - } - - public SkipUntapStepEffect(final SkipUntapStepEffect effect) { - super(effect); - } - - @Override - public SkipUntapStepEffect copy() { - return new SkipUntapStepEffect(this); - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - return event.getType() == GameEvent.EventType.UNTAP_STEP - && controller != null - && game.getState().getPlayersInRange(controller.getId(), game).contains(event.getPlayerId()); - } -} - class SandsOfTimeEffect extends OneShotEffect { private static final FilterControlledPermanent filter = new FilterControlledPermanent(); From c82f38e3df94e1de68be2f334cae216ef8fd99a5 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 18:29:04 +0200 Subject: [PATCH 060/164] (Credit where it's due) --- .../java/mage/abilities/effects/common/SkipUntapStepEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java index ab30c40f79..ed3c8ff666 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapStepEffect.java @@ -40,7 +40,7 @@ import mage.players.Player; /** * - * @author L_J + * @author jeffwadsworth */ public class SkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl { From c26bab3725e00e501758807af64273c0dfa73a03 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 19:32:13 +0200 Subject: [PATCH 061/164] Some fixes --- Mage.Sets/src/mage/sets/Homelands.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 16465d7e0b..cb1bae28dd 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -73,7 +73,6 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Ambush", 78, Rarity.COMMON, mage.cards.a.Ambush.class)); cards.add(new SetCardInfo("Ambush Party", 79, Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush Party", 80, Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("An-Zerrin Ruins", 87, Rarity.RARE, mage.cards.a.AnZerrinRuins.class)); cards.add(new SetCardInfo("Anaba Ancestor", 81, Rarity.RARE, mage.cards.a.AnabaAncestor.class)); cards.add(new SetCardInfo("Anaba Bodyguard", 82, Rarity.COMMON, mage.cards.a.AnabaBodyguard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Anaba Bodyguard", 83, Rarity.COMMON, mage.cards.a.AnabaBodyguard.class, NON_FULL_USE_VARIOUS)); @@ -92,7 +91,8 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Baki's Curse", 27, Rarity.RARE, mage.cards.b.BakisCurse.class)); cards.add(new SetCardInfo("Baron Sengir", 1, Rarity.RARE, mage.cards.b.BaronSengir.class)); cards.add(new SetCardInfo("Black Carriage", 2, Rarity.RARE, mage.cards.b.BlackCarriage.class)); - cards.add(new SetCardInfo("Carapace", 55, Rarity.COMMON, mage.cards.c.Carapace.class)); + cards.add(new SetCardInfo("Carapace", 54, Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Carapace", 55, Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Castle Sengir", 138, Rarity.UNCOMMON, mage.cards.c.CastleSengir.class)); cards.add(new SetCardInfo("Cemetery Gate", 4, Rarity.COMMON, CemeteryGate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cemetery Gate", 5, Rarity.COMMON, CemeteryGate.class, NON_FULL_USE_VARIOUS)); @@ -100,6 +100,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Chandler", 88, Rarity.COMMON, mage.cards.c.Chandler.class)); cards.add(new SetCardInfo("Clockwork Gnomes", 127, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class)); cards.add(new SetCardInfo("Coral Reef", 29, Rarity.COMMON, mage.cards.c.CoralReef.class)); + cards.add(new SetCardInfo("Dark Maze", 30, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dark Maze", 31, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Daughter of Autumn", 56, Rarity.RARE, mage.cards.d.DaughterOfAutumn.class)); cards.add(new SetCardInfo("Death Speakers", 109, Rarity.UNCOMMON, mage.cards.d.DeathSpeakers.class)); @@ -157,7 +158,8 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Serra Aviary", 118, Rarity.RARE, mage.cards.s.SerraAviary.class)); cards.add(new SetCardInfo("Serra Paladin", 121, Rarity.COMMON, mage.cards.s.SerraPaladin.class)); cards.add(new SetCardInfo("Serrated Arrows", 135, Rarity.COMMON, mage.cards.s.SerratedArrows.class)); - cards.add(new SetCardInfo("Shrink", 71, Rarity.COMMON, mage.cards.s.Shrink.class)); + cards.add(new SetCardInfo("Shrink", 70, Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Shrink", 71, Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spectral Bears", 72, Rarity.UNCOMMON, mage.cards.s.SpectralBears.class)); cards.add(new SetCardInfo("Torture", 23, Rarity.COMMON, Torture.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Torture", 24, Rarity.COMMON, Torture.class, NON_FULL_USE_VARIOUS)); From 36fed5d72ec3b7474741804f3a763c44931711f2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 21:28:52 +0200 Subject: [PATCH 062/164] Create TapAttachedCost.java --- .../costs/common/TapAttachedCost.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 Mage/src/main/java/mage/abilities/costs/common/TapAttachedCost.java diff --git a/Mage/src/main/java/mage/abilities/costs/common/TapAttachedCost.java b/Mage/src/main/java/mage/abilities/costs/common/TapAttachedCost.java new file mode 100644 index 0000000000..3cdb97185e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/TapAttachedCost.java @@ -0,0 +1,76 @@ +/* + * 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.abilities.costs.common; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J + */ +public class TapAttachedCost extends CostImpl { + + public TapAttachedCost() { + this.text = "Tap enchanted creature"; + } + + public TapAttachedCost(TapAttachedCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + Permanent attachment = game.getPermanentOrLKIBattlefield(sourceId); + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + if (permanent != null) { + paid = permanent.tap(game); + } + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Permanent attachment = game.getPermanentOrLKIBattlefield(sourceId); + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + if (permanent != null) { + // return true; // Technically the more correct implementation, but all cards using this cost also come with an "untapped" condition + return !permanent.isTapped(); + } + return false; + } + + @Override + public TapAttachedCost copy() { + return new TapAttachedCost(this); + } +} From 87e3d1853526fc20773fb81b3ca05b9454a0f6a7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 21:29:57 +0200 Subject: [PATCH 063/164] Implemented Nature's Chosen --- Mage.Sets/src/mage/cards/n/NaturesChosen.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NaturesChosen.java diff --git a/Mage.Sets/src/mage/cards/n/NaturesChosen.java b/Mage.Sets/src/mage/cards/n/NaturesChosen.java new file mode 100644 index 0000000000..a88eb21457 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NaturesChosen.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; +import mage.abilities.condition.common.AttachedToMatchesFilterCondition; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.common.TapAttachedCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.UntapEnchantedEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author L_J + */ +public class NaturesChosen extends CardImpl { + + private static final FilterPermanent filterPermanent = new FilterPermanent("artifact, creature or land"); + + static { + filterPermanent.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND))); + } + + private static final FilterCreaturePermanent filterWhiteUntappedCreature = new FilterCreaturePermanent(" if enchanted creature is white and is untapped"); + + static { + filterWhiteUntappedCreature.add(new ColorPredicate(ObjectColor.WHITE)); + filterWhiteUntappedCreature.add(Predicates.not(new TappedPredicate())); + } + + public NaturesChosen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + this.subtype.add(SubType.AURA); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // {0}: Untap enchanted creature. Activate this ability only during your turn and only once each turn. + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new GenericManaCost(0), 1, MyTurnCondition.instance)); + + // Tap enchanted creature: Untap target artifact, creature, or land. Activate this ability only if enchanted creature is white and is untapped and only once each turn. + Effect effect = new UntapTargetEffect(); + effect.setText("Untap target artifact, creature, or land"); + LimitedTimesPerTurnActivatedAbility ability2 = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, effect, new TapAttachedCost(), 1, new AttachedToMatchesFilterCondition(filterWhiteUntappedCreature)); + ability2.addTarget(new TargetPermanent(filterPermanent)); + this.addAbility(ability2); + } + + public NaturesChosen(final NaturesChosen card) { + super(card); + } + + @Override + public NaturesChosen copy() { + return new NaturesChosen(this); + } +} From 6e0554adcb1a0515793b0e604967a0730a498959 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 21:31:01 +0200 Subject: [PATCH 064/164] Implemented Nature's Chosen --- Mage.Sets/src/mage/sets/Alliances.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index f4967a7168..e4dcd5d176 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -113,6 +113,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Lord of Tresserhorn", 193, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class)); cards.add(new SetCardInfo("Mishra's Groundbreaker", 165, Rarity.UNCOMMON, mage.cards.m.MishrasGroundbreaker.class)); cards.add(new SetCardInfo("Mystic Compass", 166, Rarity.UNCOMMON, mage.cards.m.MysticCompass.class)); + cards.add(new SetCardInfo("Nature's Chosen", 81, Rarity.UNCOMMON, mage.cards.n.NaturesChosen.class)); cards.add(new SetCardInfo("Nature's Wrath", 82, Rarity.RARE, mage.cards.n.NaturesWrath.class)); cards.add(new SetCardInfo("Noble Steeds", 140, Rarity.COMMON, mage.cards.n.NobleSteeds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Noble Steeds", 141, Rarity.COMMON, mage.cards.n.NobleSteeds.class, NON_FULL_USE_VARIOUS)); From eba43f190528de72c47c74020cdc5d4ad46be4c4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 23:14:09 +0200 Subject: [PATCH 065/164] Create SacrificeAttachedCost.java --- .../costs/common/SacrificeAttachedCost.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachedCost.java diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachedCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachedCost.java new file mode 100644 index 0000000000..713cbdae73 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachedCost.java @@ -0,0 +1,72 @@ +/* + * 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.abilities.costs.common; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J (based on BetaSteward_at_googlemail.com) + */ +public class SacrificeAttachedCost extends CostImpl { + + public SacrificeAttachedCost() { + this.text = "Sacrifice enchanted creature"; + } + + public SacrificeAttachedCost(SacrificeAttachedCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + Permanent attachment = game.getPermanentOrLKIBattlefield(sourceId); + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + if (permanent != null) { + paid = permanent.sacrifice(sourceId, game); + } + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Permanent attachment = game.getPermanentOrLKIBattlefield(sourceId); + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + return permanent != null && game.getPlayer(controllerId).canPaySacrificeCost(permanent, sourceId, controllerId, game); + } + + @Override + public SacrificeAttachedCost copy() { + return new SacrificeAttachedCost(this); + } +} From 919c83d44565c994e248d85d0a4d1cd01766cedc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 23:16:37 +0200 Subject: [PATCH 066/164] Implemented Bloodfire Infusion --- .../src/mage/cards/b/BloodfireInfusion.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BloodfireInfusion.java diff --git a/Mage.Sets/src/mage/cards/b/BloodfireInfusion.java b/Mage.Sets/src/mage/cards/b/BloodfireInfusion.java new file mode 100644 index 0000000000..ba798c3045 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BloodfireInfusion.java @@ -0,0 +1,116 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeAttachedCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author L_J + */ +public class BloodfireInfusion extends CardImpl { + + public BloodfireInfusion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); + this.subtype.add(SubType.AURA); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // {R}, Sacrifice enchanted creature: Bloodfire Infusion deals damage equal to the sacrificed creature's power to each creature. + Effect effect = new DamageAllEffect(new AttachedPermanentPowerCount(), new FilterCreaturePermanent()); + effect.setText("{this} deals damage equal to the sacrificed creature's power to each creature"); + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{R}")); + ability2.addCost(new SacrificeAttachedCost()); + this.addAbility(ability2); + + } + + public BloodfireInfusion(final BloodfireInfusion card) { + super(card); + } + + @Override + public BloodfireInfusion copy() { + return new BloodfireInfusion(this); + } +} + +class AttachedPermanentPowerCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Permanent attachment = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId()); + Permanent permanent = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo()); + if (attachment != null + && permanent != null + && (permanent.getPower().getValue() >= 0)) { + return permanent.getPower().getValue(); + } + return 0; + } + + @Override + public AttachedPermanentPowerCount copy() { + return new AttachedPermanentPowerCount(); + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return "enchanted creature's power"; + } +} From 2274562982bddd0579928fbd399388c52aae99dd Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 12 Oct 2017 23:17:06 +0200 Subject: [PATCH 067/164] Implemented Bloodfire Infusion --- Mage.Sets/src/mage/sets/Apocalypse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Apocalypse.java b/Mage.Sets/src/mage/sets/Apocalypse.java index 77df2f108f..187bc0ff8b 100644 --- a/Mage.Sets/src/mage/sets/Apocalypse.java +++ b/Mage.Sets/src/mage/sets/Apocalypse.java @@ -31,6 +31,7 @@ public class Apocalypse extends ExpansionSet { cards.add(new SetCardInfo("Battlefield Forge", 139, Rarity.RARE, mage.cards.b.BattlefieldForge.class)); cards.add(new SetCardInfo("Bloodfire Colossus", 55, Rarity.RARE, mage.cards.b.BloodfireColossus.class)); cards.add(new SetCardInfo("Bloodfire Dwarf", 56, Rarity.COMMON, mage.cards.b.BloodfireDwarf.class)); + cards.add(new SetCardInfo("Bloodfire Infusion", 57, Rarity.COMMON, mage.cards.b.BloodfireInfusion.class)); cards.add(new SetCardInfo("Bloodfire Kavu", 58, Rarity.UNCOMMON, mage.cards.b.BloodfireKavu.class)); cards.add(new SetCardInfo("Bog Gnarr", 76, Rarity.COMMON, mage.cards.b.BogGnarr.class)); cards.add(new SetCardInfo("Brass Herald", 133, Rarity.UNCOMMON, mage.cards.b.BrassHerald.class)); From a500c8fbdbfcd85d9cf8c09a448f9b3fdc7916a3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:18:42 +0200 Subject: [PATCH 068/164] Integer fix for opponent scouting effect --- Mage.Sets/src/mage/cards/s/SecondSight.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SecondSight.java b/Mage.Sets/src/mage/cards/s/SecondSight.java index 4605a50952..3d9c6ae5a8 100644 --- a/Mage.Sets/src/mage/cards/s/SecondSight.java +++ b/Mage.Sets/src/mage/cards/s/SecondSight.java @@ -111,7 +111,7 @@ class SecondSightEffect extends OneShotEffect { return false; } Cards cards = new CardsImpl(); - int count = Math.min(player.getLibrary().size(), 3); + int count = Math.min(player.getLibrary().size(), 5); for (int i = 0; i < count; i++) { Card card = player.getLibrary().removeFromTop(game); if (card != null) { From 8f8faa7ca10a8b37ab37861e8eb3cd9999d21e52 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:20:38 +0200 Subject: [PATCH 069/164] Changed duration to custom --- Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java b/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java index d5ab8fe131..fd3ea4efac 100644 --- a/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java +++ b/Mage.Sets/src/mage/cards/m/MishrasGroundbreaker.java @@ -53,7 +53,7 @@ public class MishrasGroundbreaker extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); // {tap}, Sacrifice Mishra's Groundbreaker: Target land becomes a 3/3 artifact creature that's still a land. (This effect lasts indefinitely.) - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(new MishrasGroundbreakerToken(), false, true, Duration.EndOfGame), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(new MishrasGroundbreakerToken(), false, true, Duration.Custom), new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetLandPermanent()); this.addAbility(ability); From 10bb8c39fed94315041bd0843515553a2c125ea5 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:21:59 +0200 Subject: [PATCH 070/164] staticText fix --- Mage.Sets/src/mage/cards/c/ChaosHarlequin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java index 3019e30d82..8da3349e7e 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java +++ b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java @@ -75,7 +75,7 @@ class ChaosHarlequinEffect extends OneShotEffect { public ChaosHarlequinEffect() { super(Outcome.Benefit); - this.staticText = "Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn"; + this.staticText = "Exile the top card of your library. If that card is a land card, {this} gets -4/-0 until end of turn. Otherwise, {this} gets +2/+0 until end of turn"; } public ChaosHarlequinEffect(final ChaosHarlequinEffect effect) { From d7b36e1736b155e09fbdea6bbc69dbdc0cbbec67 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:45:26 +0200 Subject: [PATCH 071/164] Text edit --- Mage.Sets/src/mage/cards/h/HailStorm.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HailStorm.java b/Mage.Sets/src/mage/cards/h/HailStorm.java index a0c52a3e50..5ee3672332 100644 --- a/Mage.Sets/src/mage/cards/h/HailStorm.java +++ b/Mage.Sets/src/mage/cards/h/HailStorm.java @@ -54,8 +54,8 @@ public class HailStorm extends CardImpl { // Hail Storm deals 2 damage to each attacking creature and 1 damage to you and each creature you control. this.getSpellAbility().addEffect(new DamageAllEffect(2, new FilterAttackingCreature())); - this.getSpellAbility().addEffect(new DamageControllerEffect(1)); - this.getSpellAbility().addEffect(new DamageAllEffect(1, filter)); + this.getSpellAbility().addEffect(new DamageControllerEffect(1).setText("and 1 damage to you ")); + this.getSpellAbility().addEffect(new DamageAllEffect(1, filter).setText("and each creature you control.")); } public HailStorm(final HailStorm card) { From e4c8aa5f6106d7f5b2c1134b6fea8129d1518c34 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:46:31 +0200 Subject: [PATCH 072/164] Updated cost --- Mage.Sets/src/mage/cards/w/WintersNight.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/w/WintersNight.java b/Mage.Sets/src/mage/cards/w/WintersNight.java index db0cc8e032..115056ee57 100644 --- a/Mage.Sets/src/mage/cards/w/WintersNight.java +++ b/Mage.Sets/src/mage/cards/w/WintersNight.java @@ -55,7 +55,7 @@ public class WintersNight extends CardImpl { } public WintersNight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}{R}{G}"); + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}{G}{W}"); addSuperType(SuperType.WORLD); // Whenever a player taps a snow land for mana, that player adds one mana to his or her mana pool of any type that land produced. From 61f5879d84a4760afdf1d9ffd72e0712991694ab Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:56:01 +0200 Subject: [PATCH 073/164] Text edit and minor cleanup --- Mage.Sets/src/mage/cards/f/Foxfire.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/Foxfire.java b/Mage.Sets/src/mage/cards/f/Foxfire.java index 159fc7a92a..b7a5409ee3 100644 --- a/Mage.Sets/src/mage/cards/f/Foxfire.java +++ b/Mage.Sets/src/mage/cards/f/Foxfire.java @@ -55,8 +55,8 @@ public class Foxfire extends CardImpl { // Untap target attacking creature. Prevent all combat damage that would be dealt to and dealt by that creature this turn. this.getSpellAbility().addTarget(new TargetAttackingCreature()); this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true)); - this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE, true)); + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText("Prevent all combat damage that would be dealt to ")); + this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, true).setText("and dealt by that creature this turn.")); // Draw a card at the beginning of the next turn's upkeep. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)),false)); From f6e7e6d01d66a041aa6d36e87e8ce44b72a880c8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 13 Oct 2017 00:56:08 +0200 Subject: [PATCH 074/164] Text edit and minor cleanup --- Mage.Sets/src/mage/cards/e/EnergyArc.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EnergyArc.java b/Mage.Sets/src/mage/cards/e/EnergyArc.java index 654fc01850..f3c4440db4 100644 --- a/Mage.Sets/src/mage/cards/e/EnergyArc.java +++ b/Mage.Sets/src/mage/cards/e/EnergyArc.java @@ -51,9 +51,9 @@ public class EnergyArc extends CardImpl { // Untap any number of target creatures. Prevent all combat damage that would be dealt to and dealt by those creatures this turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true)); - this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE, true)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap any number of target creatures. ")); + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText("Prevent all combat damage that would be dealt to ")); + this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, true).setText("and dealt by those creatures this turn.")); } public EnergyArc(final EnergyArc card) { From 19552d7a86899ab5edf42a9dd88a5fbcfcf0c069 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 20:54:43 -0400 Subject: [PATCH 075/164] Implemented Kjeldoran Javelineer --- .../src/mage/cards/k/KjeldoranJavelineer.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KjeldoranJavelineer.java diff --git a/Mage.Sets/src/mage/cards/k/KjeldoranJavelineer.java b/Mage.Sets/src/mage/cards/k/KjeldoranJavelineer.java new file mode 100644 index 0000000000..efb114d0b0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KjeldoranJavelineer.java @@ -0,0 +1,81 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +/** + * + * @author TheElk801 + */ +public class KjeldoranJavelineer extends CardImpl { + + public KjeldoranJavelineer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // {T}: Kjeldoran Javelineer deals damage equal to the number of age counters on it to target attacking or blocking creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DamageTargetEffect(new CountersSourceCount(CounterType.AGE)) + .setText("{this} deals damage equal to the number of age counters on it to target attacking or blocking creature."), + new TapSourceCost()); + ability.addTarget(new TargetAttackingOrBlockingCreature()); + this.addAbility(ability); + } + + public KjeldoranJavelineer(final KjeldoranJavelineer card) { + super(card); + } + + @Override + public KjeldoranJavelineer copy() { + return new KjeldoranJavelineer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index fc5fb4fc48..2274bb439f 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -116,6 +116,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Karplusan Strider", 112, Rarity.UNCOMMON, mage.cards.k.KarplusanStrider.class)); cards.add(new SetCardInfo("Karplusan Wolverine", 87, Rarity.COMMON, mage.cards.k.KarplusanWolverine.class)); cards.add(new SetCardInfo("Kjeldoran Gargoyle", 10, Rarity.UNCOMMON, mage.cards.k.KjeldoranGargoyle.class)); + cards.add(new SetCardInfo("Kjeldoran Javelineer", 11, Rarity.COMMON, mage.cards.k.KjeldoranJavelineer.class)); cards.add(new SetCardInfo("Kjeldoran Outrider", 12, Rarity.COMMON, mage.cards.k.KjeldoranOutrider.class)); cards.add(new SetCardInfo("Krovikan Mist", 38, Rarity.COMMON, mage.cards.k.KrovikanMist.class)); cards.add(new SetCardInfo("Krovikan Rot", 63, Rarity.UNCOMMON, mage.cards.k.KrovikanRot.class)); From 7ad481cc0e4fe2bfa870c73a822a1c8290c644ac Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 20:59:28 -0400 Subject: [PATCH 076/164] fixed Pang Tong and Kongming's names --- Mage.Sets/src/mage/sets/PortalThreeKingdoms.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 74a5c7f7ff..4970599957 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -106,7 +106,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Island", 169, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 170, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 171, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kongming, 'Sleeping Dragon'", 9, Rarity.RARE, mage.cards.k.KongmingSleepingDragon.class)); + cards.add(new SetCardInfo("Kongming, \"Sleeping Dragon\"", 9, Rarity.RARE, mage.cards.k.KongmingSleepingDragon.class)); cards.add(new SetCardInfo("Lady Sun", 45, Rarity.RARE, mage.cards.l.LadySun.class)); cards.add(new SetCardInfo("Lady Zhurong, Warrior Queen", 139, Rarity.RARE, mage.cards.l.LadyZhurongWarriorQueen.class)); cards.add(new SetCardInfo("Liu Bei, Lord of Shu", 11, Rarity.RARE, mage.cards.l.LiuBeiLordOfShu.class)); @@ -127,7 +127,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Mountain Bandit", 117, Rarity.COMMON, mage.cards.m.MountainBandit.class)); cards.add(new SetCardInfo("Mystic Denial", 49, Rarity.UNCOMMON, mage.cards.m.MysticDenial.class)); cards.add(new SetCardInfo("Overwhelming Forces", 79, Rarity.RARE, mage.cards.o.OverwhelmingForces.class)); - cards.add(new SetCardInfo("Pang Tong, 'Young Phoenix'", 14, Rarity.RARE, mage.cards.p.PangTongYoungPhoenix.class)); + cards.add(new SetCardInfo("Pang Tong, \"Young Phoenix\"", 14, Rarity.RARE, mage.cards.p.PangTongYoungPhoenix.class)); cards.add(new SetCardInfo("Peach Garden Oath", 15, Rarity.UNCOMMON, mage.cards.p.PeachGardenOath.class)); cards.add(new SetCardInfo("Plains", 166, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 167, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); From f764cc6fedfbebdf2873248a35aade1472b43ea7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 21:10:13 -0400 Subject: [PATCH 077/164] Implemented Renewing Touch --- Mage.Sets/src/mage/cards/p/PipersMelody.java | 3 +- Mage.Sets/src/mage/cards/r/RenewingTouch.java | 94 +++++++++++++++++++ Mage.Sets/src/mage/sets/PortalSecondAge.java | 1 + Mage.Sets/src/mage/sets/Starter1999.java | 1 + 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/RenewingTouch.java diff --git a/Mage.Sets/src/mage/cards/p/PipersMelody.java b/Mage.Sets/src/mage/cards/p/PipersMelody.java index 89ead3a4cb..634952e372 100644 --- a/Mage.Sets/src/mage/cards/p/PipersMelody.java +++ b/Mage.Sets/src/mage/cards/p/PipersMelody.java @@ -30,7 +30,6 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutOnLibraryTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; @@ -50,7 +49,6 @@ public class PipersMelody extends CardImpl { public PipersMelody(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}"); - // Shuffle any number of target creature cards from your graveyard into your library. this.getSpellAbility().addEffect(new PipersMelodyShuffleEffect()); @@ -66,6 +64,7 @@ public class PipersMelody extends CardImpl { return new PipersMelody(this); } } + class PipersMelodyShuffleEffect extends OneShotEffect { PipersMelodyShuffleEffect() { diff --git a/Mage.Sets/src/mage/cards/r/RenewingTouch.java b/Mage.Sets/src/mage/cards/r/RenewingTouch.java new file mode 100644 index 0000000000..119ce3f4fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RenewingTouch.java @@ -0,0 +1,94 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author TheElk801 + */ +public class RenewingTouch extends CardImpl { + + public RenewingTouch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}"); + + // Shuffle any number of target creature cards from your graveyard into your library. + this.getSpellAbility().addEffect(new RenewingTouchEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard"))); + } + + public RenewingTouch(final RenewingTouch card) { + super(card); + } + + @Override + public RenewingTouch copy() { + return new RenewingTouch(this); + } +} + +class RenewingTouchEffect extends OneShotEffect { + + RenewingTouchEffect() { + super(Outcome.Neutral); + this.staticText = "Shuffle any number of target cards from your graveyard into your library"; + } + + RenewingTouchEffect(final RenewingTouchEffect effect) { + super(effect); + } + + @Override + public RenewingTouchEffect copy() { + return new RenewingTouchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.moveCards(new CardsImpl(this.getTargetPointer().getTargets(game, source)), Zone.LIBRARY, source, game); + controller.shuffleLibrary(source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index 1f583f0101..16e6adfa71 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -167,6 +167,7 @@ public class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Raise Dead", 26, Rarity.COMMON, mage.cards.r.RaiseDead.class)); cards.add(new SetCardInfo("Ravenous Rats", 27, Rarity.COMMON, mage.cards.r.RavenousRats.class)); cards.add(new SetCardInfo("Razorclaw Bear", 82, Rarity.RARE, mage.cards.r.RazorclawBear.class)); + cards.add(new SetCardInfo("Renewing Touch", 83, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); cards.add(new SetCardInfo("Return of the Nightstalkers", 28, Rarity.RARE, mage.cards.r.ReturnOfTheNightstalkers.class)); cards.add(new SetCardInfo("Righteous Charge", 140, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); cards.add(new SetCardInfo("Righteous Fury", 141, Rarity.RARE, mage.cards.r.RighteousFury.class)); diff --git a/Mage.Sets/src/mage/sets/Starter1999.java b/Mage.Sets/src/mage/sets/Starter1999.java index 06741af5c6..6f6a511916 100644 --- a/Mage.Sets/src/mage/sets/Starter1999.java +++ b/Mage.Sets/src/mage/sets/Starter1999.java @@ -168,6 +168,7 @@ public class Starter1999 extends ExpansionSet { cards.add(new SetCardInfo("Relearn", 48, Rarity.UNCOMMON, mage.cards.r.Relearn.class)); cards.add(new SetCardInfo("Relentless Assault", 115, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); cards.add(new SetCardInfo("Remove Soul", 49, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); + cards.add(new SetCardInfo("Renewing Touch", 140, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); cards.add(new SetCardInfo("Righteous Charge", 22, Rarity.UNCOMMON, mage.cards.r.RighteousCharge.class)); cards.add(new SetCardInfo("Righteous Fury", 23, Rarity.RARE, mage.cards.r.RighteousFury.class)); cards.add(new SetCardInfo("Royal Falcon", 24, Rarity.COMMON, mage.cards.r.RoyalFalcon.class)); From 90640eee158564a5befafdb8b048dd8b85689558 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 21:42:44 -0400 Subject: [PATCH 078/164] Implemented Winter Blast --- Mage.Sets/src/mage/cards/w/WinterBlast.java | 107 ++++++++++++++++++++ Mage.Sets/src/mage/sets/FifthEdition.java | 1 + Mage.Sets/src/mage/sets/FourthEdition.java | 1 + Mage.Sets/src/mage/sets/Legends.java | 1 + Mage.Sets/src/mage/sets/MastersEdition.java | 1 + 5 files changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WinterBlast.java diff --git a/Mage.Sets/src/mage/cards/w/WinterBlast.java b/Mage.Sets/src/mage/cards/w/WinterBlast.java new file mode 100644 index 0000000000..97a6d3103d --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WinterBlast.java @@ -0,0 +1,107 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class WinterBlast extends CardImpl { + + public WinterBlast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}"); + + // Tap X target creatures. Winter Blast deals 2 damage to each of those creatures with flying. + this.getSpellAbility().addEffect(new WinterBlastEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetCreaturePermanent(xValue)); + } + } + + public WinterBlast(final WinterBlast card) { + super(card); + } + + @Override + public WinterBlast copy() { + return new WinterBlast(this); + } +} + +class WinterBlastEffect extends OneShotEffect { + + WinterBlastEffect() { + super(Outcome.Benefit); + this.staticText = "Tap X target creatures. {this} deals 2 damage to each of those creatures with flying."; + } + + WinterBlastEffect(final WinterBlastEffect effect) { + super(effect); + } + + @Override + public WinterBlastEffect copy() { + return new WinterBlastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int affectedTargets = 0; + for (UUID permanentId : targetPointer.getTargets(game, source)) { + Permanent permanent = game.getPermanent(permanentId); + if (permanent != null) { + permanent.tap(game); + if (permanent.getAbilities().contains(FlyingAbility.getInstance())) { + permanent.damage(2, source.getSourceId(), game, false, true); + } + affectedTargets++; + } + } + return affectedTargets > 0; + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index ec8633bbe7..c04cc7dae8 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -437,6 +437,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Wild Growth", 204, Rarity.COMMON, mage.cards.w.WildGrowth.class)); cards.add(new SetCardInfo("Winds of Change", 275, Rarity.RARE, mage.cards.w.WindsOfChange.class)); cards.add(new SetCardInfo("Wind Spirit", 136, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class)); + cards.add(new SetCardInfo("Winter Blast", 205, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); cards.add(new SetCardInfo("Winter Orb", 408, Rarity.RARE, mage.cards.w.WinterOrb.class)); cards.add(new SetCardInfo("Wolverine Pack", 206, Rarity.UNCOMMON, mage.cards.w.WolverinePack.class)); cards.add(new SetCardInfo("Wooden Sphere", 409, Rarity.UNCOMMON, mage.cards.w.WoodenSphere.class)); diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java index c1a6349a31..f44d101070 100644 --- a/Mage.Sets/src/mage/sets/FourthEdition.java +++ b/Mage.Sets/src/mage/sets/FourthEdition.java @@ -399,6 +399,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("Wild Growth", 173, Rarity.COMMON, mage.cards.w.WildGrowth.class)); cards.add(new SetCardInfo("Will-o'-the-Wisp", 55, Rarity.RARE, mage.cards.w.WillOTheWisp.class)); cards.add(new SetCardInfo("Winds of Change", 250, Rarity.RARE, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter Blast", 174, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); cards.add(new SetCardInfo("Winter Orb", 376, Rarity.RARE, mage.cards.w.WinterOrb.class)); cards.add(new SetCardInfo("Wooden Sphere", 377, Rarity.UNCOMMON, mage.cards.w.WoodenSphere.class)); cards.add(new SetCardInfo("Word of Binding", 56, Rarity.COMMON, mage.cards.w.WordOfBinding.class)); diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 46097a7576..62385b2f40 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -268,6 +268,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("White Mana Battery", 244, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class)); cards.add(new SetCardInfo("Willow Satyr", 126, Rarity.RARE, mage.cards.w.WillowSatyr.class)); cards.add(new SetCardInfo("Winds of Change", 169, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter Blast", 127, Rarity.RARE, mage.cards.w.WinterBlast.class)); cards.add(new SetCardInfo("Wolverine Pack", 128, Rarity.COMMON, mage.cards.w.WolverinePack.class)); cards.add(new SetCardInfo("Xira Arien", 310, Rarity.RARE, mage.cards.x.XiraArien.class)); cards.add(new SetCardInfo("Zephyr Falcon", 86, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEdition.java b/Mage.Sets/src/mage/sets/MastersEdition.java index 9ca7deb821..5adcbf72ba 100644 --- a/Mage.Sets/src/mage/sets/MastersEdition.java +++ b/Mage.Sets/src/mage/sets/MastersEdition.java @@ -239,6 +239,7 @@ public class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Walking Wall", 172, Rarity.UNCOMMON, mage.cards.w.WalkingWall.class)); cards.add(new SetCardInfo("Wanderlust", 137, Rarity.COMMON, mage.cards.w.Wanderlust.class)); cards.add(new SetCardInfo("Winds of Change", 111, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter Blast", 138, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); cards.add(new SetCardInfo("Winter Orb", 173, Rarity.RARE, mage.cards.w.WinterOrb.class)); cards.add(new SetCardInfo("Wyluli Wolf", 139, Rarity.COMMON, mage.cards.w.WyluliWolf.class)); cards.add(new SetCardInfo("Yavimaya Ants", 140, Rarity.UNCOMMON, mage.cards.y.YavimayaAnts.class)); From c2a4f22b56d663d927ba6f64d8b732abf585b0cb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 12 Oct 2017 22:08:59 -0400 Subject: [PATCH 079/164] Implemented Clockwork Swarm --- .../src/mage/cards/c/ClockworkAvian.java | 23 ++- .../src/mage/cards/c/ClockworkBeast.java | 22 ++- .../src/mage/cards/c/ClockworkSwarm.java | 151 ++++++++++++++++++ Mage.Sets/src/mage/sets/Homelands.java | 1 + Mage.Sets/src/mage/sets/MastersEditionIV.java | 1 + 5 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/c/ClockworkSwarm.java diff --git a/Mage.Sets/src/mage/cards/c/ClockworkAvian.java b/Mage.Sets/src/mage/cards/c/ClockworkAvian.java index aeeb82294a..bbdd354c57 100644 --- a/Mage.Sets/src/mage/cards/c/ClockworkAvian.java +++ b/Mage.Sets/src/mage/cards/c/ClockworkAvian.java @@ -69,19 +69,33 @@ public class ClockworkAvian extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // Clockwork Avian enters the battlefield with four +1/+0 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P0.createInstance(4)), "{this} enters the battlefield with four +1/+0 counters on it")); + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P0.createInstance(4)), + "with four +1/+0 counters on it" + )); // At end of combat, if Clockwork Avian attacked or blocked this combat, remove a +1/+0 counter from it. this.addAbility(new ConditionalTriggeredAbility( new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false), AttackedOrBlockedThisCombatSourceCondition.instance, "At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."), - new AttackedOrBlockedThisCombatWatcher()); + new AttackedOrBlockedThisCombatWatcher() + ); // {X}, {tap}: Put up to X +1/+0 counters on Clockwork Avian. This ability can't cause the total number of +1/+0 counters on Clockwork Avian to be greater than four. Activate this ability only during your upkeep. - Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, - new AvianAddCountersSourceEffect(CounterType.P1P0.createInstance(), new ManacostVariableValue(), true, true), new ManaCostsImpl("{X}"), new IsStepCondition(PhaseStep.UPKEEP), null); + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, + new AvianAddCountersSourceEffect( + CounterType.P1P0.createInstance(), + new ManacostVariableValue(), + true, true + ), + new ManaCostsImpl("{X}"), + new IsStepCondition(PhaseStep.UPKEEP), + null + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -100,6 +114,7 @@ class AvianAddCountersSourceEffect extends AddCountersSourceEffect { public AvianAddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers, boolean putOnCard) { super(counter, amount, informPlayers, putOnCard); + staticText = "Put up to X +1/+0 counters on {this}. This ability can't cause the total number of +1/+0 counters on {this} to be greater than four."; } @Override diff --git a/Mage.Sets/src/mage/cards/c/ClockworkBeast.java b/Mage.Sets/src/mage/cards/c/ClockworkBeast.java index 9abe959d4d..07123dda4e 100644 --- a/Mage.Sets/src/mage/cards/c/ClockworkBeast.java +++ b/Mage.Sets/src/mage/cards/c/ClockworkBeast.java @@ -67,18 +67,31 @@ public class ClockworkBeast extends CardImpl { this.toughness = new MageInt(4); // Clockwork Beast enters the battlefield with seven +1/+0 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P0.createInstance(7)), "{this} enters the battlefield with seven +1/+0 counters on it")); + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P0.createInstance(7)), + "with seven +1/+0 counters on it" + )); // At end of combat, if Clockwork Beast attacked or blocked this combat, remove a +1/+0 counter from it. this.addAbility(new ConditionalTriggeredAbility( new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false), AttackedOrBlockedThisCombatSourceCondition.instance, "At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."), - new AttackedOrBlockedThisCombatWatcher()); + new AttackedOrBlockedThisCombatWatcher() + ); // {X}, {tap}: Put up to X +1/+0 counters on Clockwork Beast. This ability can't cause the total number of +1/+0 counters on Clockwork Beast to be greater than seven. Activate this ability only during your upkeep. - Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, - new BeastAddCountersSourceEffect(CounterType.P1P0.createInstance(), new ManacostVariableValue(), true, true), new ManaCostsImpl("{X}"), new IsStepCondition(PhaseStep.UPKEEP), null); + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, + new BeastAddCountersSourceEffect( + CounterType.P1P0.createInstance(), + new ManacostVariableValue(), + true, true + ), + new ManaCostsImpl("{X}"), + new IsStepCondition(PhaseStep.UPKEEP), + null + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -97,6 +110,7 @@ class BeastAddCountersSourceEffect extends AddCountersSourceEffect { public BeastAddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers, boolean putOnCard) { super(counter, amount, informPlayers, putOnCard); + staticText = "Put up to X +1/+0 counters on {this}. This ability can't cause the total number of +1/+0 counters on {this} to be greater than seven."; } @Override diff --git a/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java b/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java new file mode 100644 index 0000000000..37a603166c --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java @@ -0,0 +1,151 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.condition.common.AttackedOrBlockedThisCombatSourceCondition; +import mage.abilities.condition.common.IsStepCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.counters.Counters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; + +/** + * + * @author TheElk801 + */ +public class ClockworkSwarm extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Walls"); + + static { + filter.add(new SubtypePredicate(SubType.WALL)); + } + + public ClockworkSwarm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add(SubType.INSECT); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // Clockwork Swarm enters the battlefield with four +1/+0 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P0.createInstance(4)), + "with four +1/+0 counters on it" + )); + + // Clockwork Swarm can't be blocked by Walls. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + + // At end of combat, if Clockwork Swarm attacked or blocked this combat, remove a +1/+0 counter from it. + this.addAbility(new ConditionalTriggeredAbility( + new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false), + AttackedOrBlockedThisCombatSourceCondition.instance, + "At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."), + new AttackedOrBlockedThisCombatWatcher()); + + // {X}, {tap}: Put up to X +1/+0 counters on Clockwork Swarm. This ability can't cause the total number of +1/+0 counters on Clockwork Swarm to be greater than four. Activate this ability only during your upkeep. + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, + new SwarmAddCountersSourceEffect( + CounterType.P1P0.createInstance(), + new ManacostVariableValue(), + true, true + ), + new ManaCostsImpl("{X}"), + new IsStepCondition(PhaseStep.UPKEEP), + null + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public ClockworkSwarm(final ClockworkSwarm card) { + super(card); + } + + @Override + public ClockworkSwarm copy() { + return new ClockworkSwarm(this); + } +} + +class SwarmAddCountersSourceEffect extends AddCountersSourceEffect { + + public SwarmAddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers, boolean putOnCard) { + super(counter, amount, informPlayers, putOnCard); + staticText = "Put up to X +1/+0 counters on {this}. This ability can't cause the total number of +1/+0 counters on {this} to be greater than four."; + } + + @Override + public boolean apply(Game game, Ability source) { + Counters permCounters = game.getPermanent(source.getSourceId()).getCounters(game); + int countersWas = permCounters.getCount(CounterType.P1P0); + if (countersWas < 4) { + super.apply(game, source); + if (permCounters.getCount(CounterType.P1P0) > 4) { + permCounters.removeCounter(CounterType.P1P0, permCounters.getCount(CounterType.P1P0) - 4); + }//if countersWas < 4 then counter is min(current,4); there is no setCounters function though + }//else this is a rare case of a Beast getting boosted by outside sources. Which is the sole purpose of this if, for the benefit of this rare but not impossible case + return true; + } + + public SwarmAddCountersSourceEffect(final SwarmAddCountersSourceEffect effect) { + super(effect); + } + + @Override + public SwarmAddCountersSourceEffect copy() { + return new SwarmAddCountersSourceEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index cb1bae28dd..6113b95dca 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -99,6 +99,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Chain Stasis", 28, Rarity.RARE, mage.cards.c.ChainStasis.class)); cards.add(new SetCardInfo("Chandler", 88, Rarity.COMMON, mage.cards.c.Chandler.class)); cards.add(new SetCardInfo("Clockwork Gnomes", 127, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class)); + cards.add(new SetCardInfo("Clockwork Swarm", 129, Rarity.COMMON, mage.cards.c.ClockworkSwarm.class)); cards.add(new SetCardInfo("Coral Reef", 29, Rarity.COMMON, mage.cards.c.CoralReef.class)); cards.add(new SetCardInfo("Dark Maze", 30, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dark Maze", 31, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index fb08716493..25979eabb1 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -95,6 +95,7 @@ public class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Clay Statue", 189, Rarity.UNCOMMON, mage.cards.c.ClayStatue.class)); cards.add(new SetCardInfo("Clockwork Avian", 190, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class)); cards.add(new SetCardInfo("Clockwork Gnomes", 191, Rarity.UNCOMMON, mage.cards.c.ClockworkGnomes.class)); + cards.add(new SetCardInfo("Clockwork Swarm", 192, Rarity.COMMON, mage.cards.c.ClockworkSwarm.class)); cards.add(new SetCardInfo("Cloud Dragon", 41, Rarity.RARE, mage.cards.c.CloudDragon.class)); cards.add(new SetCardInfo("Cloud Spirit", 42, Rarity.COMMON, mage.cards.c.CloudSpirit.class)); cards.add(new SetCardInfo("Colossus of Sardia", 193, Rarity.RARE, mage.cards.c.ColossusOfSardia.class)); From 5fdb23380c464724710e16007def107dc63360b2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 13 Oct 2017 08:22:01 -0400 Subject: [PATCH 080/164] Implemented Rite of Ruin --- Mage.Sets/src/mage/cards/r/RiteOfRuin.java | 33 +++++----------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/Mage.Sets/src/mage/cards/r/RiteOfRuin.java b/Mage.Sets/src/mage/cards/r/RiteOfRuin.java index a2bb5c27eb..9086a1ece0 100644 --- a/Mage.Sets/src/mage/cards/r/RiteOfRuin.java +++ b/Mage.Sets/src/mage/cards/r/RiteOfRuin.java @@ -27,8 +27,10 @@ */ package mage.cards.r; +import java.util.*; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.ChoiceImpl; @@ -37,11 +39,7 @@ import mage.constants.Outcome; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetControlledPermanent; - -import java.util.*; /** * @@ -50,8 +48,7 @@ import java.util.*; public class RiteOfRuin extends CardImpl { public RiteOfRuin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{R}{R}"); // Choose an order for artifacts, creatures, and lands. Each player sacrifices one permanent of the first type, sacrifices two of the second type, then sacrifices three of the third type. this.getSpellAbility().addEffect(new RiteOfRuinEffect()); @@ -97,7 +94,9 @@ class RiteOfRuinEffect extends OneShotEffect { LinkedList order = new LinkedList<>(); ChoiceImpl choice = new ChoiceImpl(true); + choice.setMessage("Choose a card type"); choice.setChoices(choices); + while (controller.canRespond() && controller.choose(Outcome.Sacrifice, choice, game) && choices.size() > 1) { order.add(getCardType(choice.getChoice())); choices.remove(choice.getChoice()); @@ -105,29 +104,11 @@ class RiteOfRuinEffect extends OneShotEffect { } order.add(getCardType(choices.iterator().next())); - List sacrifices = new LinkedList<>(); int count = 1; for (CardType cardType : order) { - FilterControlledPermanent filter = new FilterControlledPermanent(cardType + " permanent you control"); + FilterControlledPermanent filter = new FilterControlledPermanent(cardType + " you control"); filter.add(new CardTypePredicate(cardType)); - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - int amount = Math.min(count, game.getBattlefield().countAll(filter, playerId, game)); - TargetControlledPermanent target = new TargetControlledPermanent(amount, amount, filter, false); - Player player = game.getPlayer(playerId); - if (player != null && player.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) { - sacrifices.addAll(target.getTargets()); - } - } - - for (UUID targetId : sacrifices) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - sacrifices.clear(); + new SacrificeAllEffect(count, filter).apply(game, source); count++; } From 5716cb7618cd3132b830c14ca77cf496ad53da32 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 13 Oct 2017 17:59:38 -0400 Subject: [PATCH 081/164] fixed some cards being implemented but not listed and therefore unavailable (Temporal Aperture and Barrin's Spite) --- .../src/mage/cards/c/CrookOfComdemnation.java | 77 ------------------- Mage.Sets/src/mage/sets/Invasion.java | 1 + Mage.Sets/src/mage/sets/UrzasSaga.java | 13 ++-- 3 files changed, 8 insertions(+), 83 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/c/CrookOfComdemnation.java diff --git a/Mage.Sets/src/mage/cards/c/CrookOfComdemnation.java b/Mage.Sets/src/mage/cards/c/CrookOfComdemnation.java deleted file mode 100644 index d53857d8e2..0000000000 --- a/Mage.Sets/src/mage/cards/c/CrookOfComdemnation.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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.c; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ExileSourceCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; -import mage.abilities.effects.common.ExileTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.target.common.TargetCardInGraveyard; - -/** - * - * @author jeffwadsworth - */ -public class CrookOfComdemnation extends CardImpl { - - private UUID exileId = UUID.randomUUID(); - - public CrookOfComdemnation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - - - // {1}, {t}: Exile target card from a graveyard. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new ManaCostsImpl("{1}")); - ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetCardInGraveyard()); - this.addAbility(ability); - - // {1}, Exile Crook of Condemnation: Exile all cards from all graveyards. - Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileGraveyardAllPlayersEffect(), new ManaCostsImpl("{1}")); - ability2.addCost(new ExileSourceCost()); - this.addAbility(ability2); - - } - - public CrookOfComdemnation(final CrookOfComdemnation card) { - super(card); - } - - @Override - public CrookOfComdemnation copy() { - return new CrookOfComdemnation(this); - } -} diff --git a/Mage.Sets/src/mage/sets/Invasion.java b/Mage.Sets/src/mage/sets/Invasion.java index 945576131b..1a287d0fe7 100644 --- a/Mage.Sets/src/mage/sets/Invasion.java +++ b/Mage.Sets/src/mage/sets/Invasion.java @@ -75,6 +75,7 @@ public class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Aura Mutation", 232, Rarity.RARE, mage.cards.a.AuraMutation.class)); cards.add(new SetCardInfo("Aura Shards", 233, Rarity.UNCOMMON, mage.cards.a.AuraShards.class)); cards.add(new SetCardInfo("Backlash", 234, Rarity.UNCOMMON, mage.cards.b.Backlash.class)); + cards.add(new SetCardInfo("Barrin's Spite", 235, Rarity.RARE, mage.cards.b.BarrinsSpite.class)); cards.add(new SetCardInfo("Barrin's Unmaking", 46, Rarity.COMMON, mage.cards.b.BarrinsUnmaking.class)); cards.add(new SetCardInfo("Benalish Emissary", 5, Rarity.UNCOMMON, mage.cards.b.BenalishEmissary.class)); cards.add(new SetCardInfo("Benalish Heralds", 6, Rarity.UNCOMMON, mage.cards.b.BenalishHeralds.class)); diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index bda4d931a5..3968d93c04 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -176,10 +176,10 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Grafted Skullcap", 296, Rarity.RARE, mage.cards.g.GraftedSkullcap.class)); cards.add(new SetCardInfo("Greater Good", 257, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Great Whale", 77, Rarity.RARE, mage.cards.g.GreatWhale.class)); - cards.add(new SetCardInfo("Greener Pastures", 258, Rarity.RARE, mage.cards.g.GreenerPastures.class)); + cards.add(new SetCardInfo("Greener Pastures", 258, Rarity.RARE, mage.cards.g.GreenerPastures.class)); cards.add(new SetCardInfo("Guma", 197, Rarity.UNCOMMON, mage.cards.g.Guma.class)); cards.add(new SetCardInfo("Hawkeater Moth", 259, Rarity.UNCOMMON, mage.cards.h.HawkeaterMoth.class)); - cards.add(new SetCardInfo("Headlong Rush", 198, Rarity.COMMON, mage.cards.h.HeadlongRush.class)); + cards.add(new SetCardInfo("Headlong Rush", 198, Rarity.COMMON, mage.cards.h.HeadlongRush.class)); cards.add(new SetCardInfo("Healing Salve", 16, Rarity.COMMON, mage.cards.h.HealingSalve.class)); cards.add(new SetCardInfo("Heat Ray", 199, Rarity.COMMON, mage.cards.h.HeatRay.class)); cards.add(new SetCardInfo("Herald of Serra", 17, Rarity.RARE, mage.cards.h.HeraldOfSerra.class)); @@ -187,10 +187,10 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Hibernation", 79, Rarity.UNCOMMON, mage.cards.h.Hibernation.class)); cards.add(new SetCardInfo("Hidden Ancients", 260, Rarity.UNCOMMON, mage.cards.h.HiddenAncients.class)); cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); - cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); + cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); - cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); + cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); cards.add(new SetCardInfo("Horseshoe Crab", 80, Rarity.COMMON, mage.cards.h.HorseshoeCrab.class)); cards.add(new SetCardInfo("Humble", 18, Rarity.UNCOMMON, mage.cards.h.Humble.class)); cards.add(new SetCardInfo("Hush", 266, Rarity.COMMON, mage.cards.h.Hush.class)); @@ -266,7 +266,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Skirge", 152, Rarity.COMMON, mage.cards.r.RavenousSkirge.class)); cards.add(new SetCardInfo("Raze", 207, Rarity.COMMON, mage.cards.r.Raze.class)); cards.add(new SetCardInfo("Recantation", 91, Rarity.RARE, mage.cards.r.Recantation.class)); - cards.add(new SetCardInfo("Reclusive Wight", 153, Rarity.UNCOMMON, mage.cards.r.ReclusiveWight.class)); + cards.add(new SetCardInfo("Reclusive Wight", 153, Rarity.UNCOMMON, mage.cards.r.ReclusiveWight.class)); cards.add(new SetCardInfo("Redeem", 33, Rarity.UNCOMMON, mage.cards.r.Redeem.class)); cards.add(new SetCardInfo("Reflexes", 208, Rarity.COMMON, mage.cards.r.Reflexes.class)); cards.add(new SetCardInfo("Rejuvenate", 271, Rarity.COMMON, mage.cards.r.Rejuvenate.class)); @@ -315,7 +315,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Smoldering Crater", 328, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); cards.add(new SetCardInfo("Sneak Attack", 218, Rarity.RARE, mage.cards.s.SneakAttack.class)); cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class)); - cards.add(new SetCardInfo("Songstitcher", 52, Rarity.UNCOMMON, mage.cards.s.Songstitcher.class)); + cards.add(new SetCardInfo("Songstitcher", 52, Rarity.UNCOMMON, mage.cards.s.Songstitcher.class)); cards.add(new SetCardInfo("Spined Fluke", 160, Rarity.UNCOMMON, mage.cards.s.SpinedFluke.class)); cards.add(new SetCardInfo("Spire Owl", 98, Rarity.COMMON, mage.cards.s.SpireOwl.class)); cards.add(new SetCardInfo("Spreading Algae", 274, Rarity.UNCOMMON, mage.cards.s.SpreadingAlgae.class)); @@ -330,6 +330,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Symbiosis", 275, Rarity.COMMON, mage.cards.s.Symbiosis.class)); cards.add(new SetCardInfo("Tainted Aether", 161, Rarity.RARE, mage.cards.t.TaintedAether.class)); cards.add(new SetCardInfo("Telepathy", 102, Rarity.UNCOMMON, mage.cards.t.Telepathy.class)); + cards.add(new SetCardInfo("Temporal Aperture", 310, Rarity.RARE, mage.cards.t.TemporalAperture.class)); cards.add(new SetCardInfo("Thran Quarry", 329, Rarity.RARE, mage.cards.t.ThranQuarry.class)); cards.add(new SetCardInfo("Thran Turbine", 311, Rarity.UNCOMMON, mage.cards.t.ThranTurbine.class)); cards.add(new SetCardInfo("Thundering Giant", 221, Rarity.UNCOMMON, mage.cards.t.ThunderingGiant.class)); From bf237b7df87f795a905d2e5084608deef58b4fad Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:18:16 +0200 Subject: [PATCH 082/164] Implemented Breath of Dreams --- .../src/mage/cards/b/BreathOfDreams.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BreathOfDreams.java diff --git a/Mage.Sets/src/mage/cards/b/BreathOfDreams.java b/Mage.Sets/src/mage/cards/b/BreathOfDreams.java new file mode 100644 index 0000000000..a9ff1064d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BreathOfDreams.java @@ -0,0 +1,75 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author L_J + */ +public class BreathOfDreams extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Green creatures"); + + static{ + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + public BreathOfDreams(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}"); + + // Cumulative upkeep-Pay {U}. + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{U}"))); + + // Green creatures have "Cumulative upkeep {1}." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}")), Duration.WhileOnBattlefield, filter))); + } + + public BreathOfDreams(final BreathOfDreams card) { + super(card); + } + + @Override + public BreathOfDreams copy() { + return new BreathOfDreams(this); + } +} From 543c2827b728608cc61f632a9bc2b33a469ebe03 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:19:09 +0200 Subject: [PATCH 083/164] Implemented Earthlore --- Mage.Sets/src/mage/cards/e/Earthlore.java | 104 ++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/Earthlore.java diff --git a/Mage.Sets/src/mage/cards/e/Earthlore.java b/Mage.Sets/src/mage/cards/e/Earthlore.java new file mode 100644 index 0000000000..f8e6998447 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/Earthlore.java @@ -0,0 +1,104 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.AttachedToMatchesFilterCondition; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapAttachedCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterBlockingCreature; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class Earthlore extends CardImpl { + + private static final FilterControlledPermanent filterLand = new FilterControlledPermanent("land you control"); + + static { + filterLand.add(new CardTypePredicate(CardType.LAND)); + } + + private static final FilterPermanent filterUntapped = new FilterPermanent("enchanted land is untapped"); + + static { + filterUntapped.add(Predicates.not(new TappedPredicate())); + } + + public Earthlore(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + this.subtype.add(SubType.AURA); + + // Enchant land you control + TargetPermanent auraTarget = new TargetControlledPermanent(filterLand); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Tap enchanted land: Target blocking creature gets +1/+2 until end of turn. Activate this ability only if enchanted land is untapped. + Cost cost = new TapAttachedCost(); + cost.setText("Tap enchanted land"); + Ability ability2 = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, + new BoostTargetEffect(1, 2, Duration.EndOfTurn), cost, new AttachedToMatchesFilterCondition(filterUntapped)); + ability2.addTarget(new TargetCreaturePermanent(new FilterBlockingCreature("blocking creature"))); + this.addAbility(ability2); + + } + + public Earthlore(final Earthlore card) { + super(card); + } + + @Override + public Earthlore copy() { + return new Earthlore(this); + } +} From db0b079dbde49d9d2a1ba632adc1f6c8927752d8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:19:46 +0200 Subject: [PATCH 084/164] Implemented Essence Flare --- Mage.Sets/src/mage/cards/e/EssenceFlare.java | 80 ++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EssenceFlare.java diff --git a/Mage.Sets/src/mage/cards/e/EssenceFlare.java b/Mage.Sets/src/mage/cards/e/EssenceFlare.java new file mode 100644 index 0000000000..9ee6f7246d --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EssenceFlare.java @@ -0,0 +1,80 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.BoostCounter; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox & L_J + */ +public class EssenceFlare extends CardImpl { + + public EssenceFlare(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature gets +2/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 0))); + // At the beginning of the upkeep of enchanted creature's controller, put a -0/-1 counter on that creature. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersAttachedEffect(new BoostCounter(0, -1), "that creature"), + TargetController.CONTROLLER_ATTACHED_TO, false)); + } + + public EssenceFlare(final EssenceFlare card) { + super(card); + } + + @Override + public EssenceFlare copy() { + return new EssenceFlare(this); + } +} From fe8207fec70c0bb3a00a70be0c56648cef86e6df Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:21:03 +0200 Subject: [PATCH 085/164] Implemented Krovikan Plague --- .../src/mage/cards/k/KrovikanPlague.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KrovikanPlague.java diff --git a/Mage.Sets/src/mage/cards/k/KrovikanPlague.java b/Mage.Sets/src/mage/cards/k/KrovikanPlague.java new file mode 100644 index 0000000000..7597a464d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KrovikanPlague.java @@ -0,0 +1,102 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.condition.common.AttachedToMatchesFilterCondition; +import mage.abilities.costs.common.TapAttachedCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.counters.BoostCounter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author L_J + */ +public class KrovikanPlague extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("enchanted creature is untapped"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + } + + public KrovikanPlague(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + this.subtype.add(SubType.AURA); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Krovikan Plague enters the battlefield, draw a card at the beginning of the next turn's upkeep. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1), Duration.OneUse)), false)); + + // Tap enchanted creature: Tap enchanted creature: Krovikan Plague deals 1 damage to target creature or player. Put a -0/-1 counter on enchanted creature. Activate this ability only if enchanted creature is untapped. + Ability ability2 = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, + new DamageTargetEffect(1), new TapAttachedCost(), new AttachedToMatchesFilterCondition(filter)); + ability2.addEffect(new AddCountersAttachedEffect(new BoostCounter(0, -1),"enchanted creature")); + ability2.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability2); + + } + + public KrovikanPlague(final KrovikanPlague card) { + super(card); + } + + @Override + public KrovikanPlague copy() { + return new KrovikanPlague(this); + } +} From 84c168e9286c04d6627fcb4b12388d80fdfc2d81 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:22:08 +0200 Subject: [PATCH 086/164] Implemented Reality Twist --- Mage.Sets/src/mage/cards/r/RealityTwist.java | 158 +++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RealityTwist.java diff --git a/Mage.Sets/src/mage/cards/r/RealityTwist.java b/Mage.Sets/src/mage/cards/r/RealityTwist.java new file mode 100644 index 0000000000..ce44c138fb --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RealityTwist.java @@ -0,0 +1,158 @@ +/* + * 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.r; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.Choice; +import mage.choices.ChoiceColor; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author emerald000 & L_J + */ +public class RealityTwist extends CardImpl { + + public RealityTwist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}{U}"); + + // Cumulative upkeep-Pay {1}{U}{U}. + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}{U}{U}"))); + + // If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealityTwistEffect())); + } + + public RealityTwist(final RealityTwist card) { + super(card); + } + + @Override + public RealityTwist copy() { + return new RealityTwist(this); + } +} + +class RealityTwistEffect extends ReplacementEffectImpl { + + RealityTwistEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type"; + } + + RealityTwistEffect(final RealityTwistEffect effect) { + super(effect); + } + + @Override + public RealityTwistEffect copy() { + return new RealityTwistEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent permanent = game.getPermanent(event.getSourceId()); + Choice choice = new ChoiceColor(true); + choice.getChoices().clear(); + choice.setMessage("Pick a color to produce"); + if (permanent.hasSubtype(SubType.PLAINS, game)) { + choice.getChoices().add("Red"); + } + if (permanent.hasSubtype(SubType.SWAMP, game)) { + choice.getChoices().add("Green"); + } + if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { + choice.getChoices().add("White"); + } + if (permanent.hasSubtype(SubType.FOREST, game)) { + choice.getChoices().add("Black"); + } + String chosenColor; + if (choice.getChoices().size() == 1) { + chosenColor = choice.getChoices().iterator().next(); + } else { + controller.choose(Outcome.PutManaInPool, choice, game); + chosenColor = choice.getChoice(); + } + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + int amount = mana.count(); + switch (chosenColor) { + case "White": + mana.setToMana(Mana.WhiteMana(amount)); + break; + case "Black": + mana.setToMana(Mana.BlackMana(amount)); + break; + case "Red": + mana.setToMana(Mana.RedMana(amount)); + break; + case "Green": + mana.setToMana(Mana.GreenMana(amount)); + break; + } + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent permanent = game.getPermanent(event.getSourceId()); + return permanent != null + && (permanent.hasSubtype(SubType.PLAINS, game) + || permanent.hasSubtype(SubType.SWAMP, game) + || permanent.hasSubtype(SubType.MOUNTAIN, game) + || permanent.hasSubtype(SubType.FOREST, game)); + } +} From 7871b3324d068b1603c0696e856732bce2d5e5a6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:22:58 +0200 Subject: [PATCH 087/164] Implemented Withering Wisps --- .../src/mage/cards/w/WitheringWisps.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WitheringWisps.java diff --git a/Mage.Sets/src/mage/cards/w/WitheringWisps.java b/Mage.Sets/src/mage/cards/w/WitheringWisps.java new file mode 100644 index 0000000000..e59ec2c7a0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WitheringWisps.java @@ -0,0 +1,149 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.OnEventTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.CreatureCountCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DamageEverythingEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.util.CardUtil; + +/** + * + * @author L_J + */ +public class WitheringWisps extends CardImpl { + + private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice {this}."; + + public WitheringWisps(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}{B}"); + + // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Withering Wisps. + TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); + this.addAbility(new ConditionalTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText)); + + // {B}: Withering Wisps deals 1 damage to each creature and each player. Activate this ability no more times each turn than the number of snow Swamps you control. + this.addAbility(new WitheringWispsActivatedAbility()); + } + + public WitheringWisps(final WitheringWisps card) { + super(card); + } + + @Override + public WitheringWisps copy() { + return new WitheringWisps(this); + } +} + +class WitheringWispsActivatedAbility extends ActivatedAbilityImpl { + + static class ActivationInfo { + + public int turnNum; + public int activationCounter; + + public ActivationInfo(int turnNum, int activationCounter) { + this.turnNum = turnNum; + this.activationCounter = activationCounter; + } + } + + private static final FilterPermanent filter = new FilterPermanent("snow lands you control"); + { + filter.add(new SupertypePredicate(SuperType.SNOW)); + filter.add(new SubtypePredicate(SubType.SWAMP)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + private int maxActivationsPerTurn(Game game) { + return game.getBattlefield().getAllActivePermanents(filter, game).size(); + } + + public WitheringWispsActivatedAbility() { + super(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{B}")); + + } + + public WitheringWispsActivatedAbility(final WitheringWispsActivatedAbility ability) { + super(ability); + } + + protected boolean hasMoreActivationsThisTurn(Game game) { + if (this.maxActivationsPerTurn(game) > 0) { + ActivationInfo activationInfo = getActivationInfo(game); + return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < this.maxActivationsPerTurn(game); + } + return false; + } + + private ActivationInfo getActivationInfo(Game game) { + Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); + Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); + if (turnNum == null || activationCount == null) { + return null; + } + return new ActivationInfo(turnNum, activationCount); + } + + @Override + public boolean resolve(Game game) { + return super.resolve(game); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder(super.getRule()).append(" Activate this ability no more times each turn than the number of snow Swamps you control."); + return sb.toString(); + } + + @Override + public WitheringWispsActivatedAbility copy() { + return new WitheringWispsActivatedAbility(this); + } +} From c9c41c694da6d48a5d3b7f3a65ab49ebb8b8b801 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:27:02 +0200 Subject: [PATCH 088/164] Implemented some cards --- Mage.Sets/src/mage/sets/IceAge.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index ab2a279101..6fc1a0ccdc 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -77,6 +77,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Blue Scarab", 233, Rarity.UNCOMMON, mage.cards.b.BlueScarab.class)); cards.add(new SetCardInfo("Brainstorm", 61, Rarity.COMMON, mage.cards.b.Brainstorm.class)); cards.add(new SetCardInfo("Brand of Ill Omen", 177, Rarity.RARE, mage.cards.b.BrandOfIllOmen.class)); + cards.add(new SetCardInfo("Breath of Dreams", 62, Rarity.UNCOMMON, mage.cards.b.BreathOfDreams.class)); cards.add(new SetCardInfo("Brine Shaman", 3, Rarity.COMMON, mage.cards.b.BrineShaman.class)); cards.add(new SetCardInfo("Brown Ouphe", 116, Rarity.COMMON, mage.cards.b.BrownOuphe.class)); cards.add(new SetCardInfo("Brushland", 327, Rarity.RARE, mage.cards.b.Brushland.class)); @@ -109,6 +110,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Disenchant", 244, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Drift of the Dead", 11, Rarity.UNCOMMON, mage.cards.d.DriftOfTheDead.class)); cards.add(new SetCardInfo("Dwarven Armory", 182, Rarity.RARE, mage.cards.d.DwarvenArmory.class)); + cards.add(new SetCardInfo("Earthlore", 119, Rarity.COMMON, mage.cards.e.Earthlore.class)); cards.add(new SetCardInfo("Earthlink", 363, Rarity.RARE, mage.cards.e.Earthlink.class)); cards.add(new SetCardInfo("Elder Druid", 120, Rarity.RARE, mage.cards.e.ElderDruid.class)); cards.add(new SetCardInfo("Elemental Augury", 364, Rarity.RARE, mage.cards.e.ElementalAugury.class)); @@ -116,6 +118,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Energy Storm", 248, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 67, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 183, Rarity.COMMON, mage.cards.e.Errantry.class)); + cards.add(new SetCardInfo("Essence Flare", 69, Rarity.COMMON, mage.cards.e.EssenceFlare.class)); cards.add(new SetCardInfo("Fanatical Fever", 122, Rarity.UNCOMMON, mage.cards.f.FanaticalFever.class)); cards.add(new SetCardInfo("Fear", 12, Rarity.COMMON, mage.cards.f.Fear.class)); cards.add(new SetCardInfo("Fiery Justice", 366, Rarity.RARE, mage.cards.f.FieryJustice.class)); @@ -254,6 +257,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Rally", 272, Rarity.COMMON, mage.cards.r.Rally.class)); cards.add(new SetCardInfo("Ray of Command", 92, Rarity.COMMON, mage.cards.r.RayOfCommand.class)); cards.add(new SetCardInfo("Ray of Erasure", 93, Rarity.COMMON, mage.cards.r.RayOfErasure.class)); + cards.add(new SetCardInfo("Reality Twist", 94, Rarity.RARE, mage.cards.r.RealityTwist.class)); cards.add(new SetCardInfo("Reclamation", 378, Rarity.RARE, mage.cards.r.Reclamation.class)); cards.add(new SetCardInfo("Red Scarab", 273, Rarity.UNCOMMON, mage.cards.r.RedScarab.class)); cards.add(new SetCardInfo("Regeneration", 147, Rarity.COMMON, mage.cards.r.Regeneration.class)); @@ -326,6 +330,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Wild Growth", 165, Rarity.COMMON, mage.cards.w.WildGrowth.class)); cards.add(new SetCardInfo("Wind Spirit", 106, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class)); cards.add(new SetCardInfo("Wings of Aesthir", 383, Rarity.UNCOMMON, mage.cards.w.WingsOfAesthir.class)); + cards.add(new SetCardInfo("Withering Wisps", 56, Rarity.UNCOMMON, mage.cards.w.WitheringWisps.class)); cards.add(new SetCardInfo("Woolly Mammoths", 166, Rarity.COMMON, mage.cards.w.WoollyMammoths.class)); cards.add(new SetCardInfo("Word of Blasting", 224, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.class)); cards.add(new SetCardInfo("Wrath of Marit Lage", 109, Rarity.RARE, mage.cards.w.WrathOfMaritLage.class)); From 91f9d4416d1797bd53b8988734977bb3483166d9 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:27:08 +0200 Subject: [PATCH 089/164] Implemented some cards --- Mage.Sets/src/mage/sets/MastersEditionII.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 12dda96464..f5e4a5efa7 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -76,7 +76,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Armored Griffin", 5, Rarity.COMMON, mage.cards.a.ArmoredGriffin.class)); cards.add(new SetCardInfo("Armor of Faith", 4, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class)); cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, ArmorThrull.class)); - cards.add(new SetCardInfo("Ashen Ghoul", 78, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); + cards.add(new SetCardInfo("Ashen Ghoul", 78, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); cards.add(new SetCardInfo("Aurochs", 153, Rarity.COMMON, mage.cards.a.Aurochs.class)); cards.add(new SetCardInfo("Aysen Bureaucrats", 6, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class)); cards.add(new SetCardInfo("Aysen Crusader", 7, Rarity.UNCOMMON, mage.cards.a.AysenCrusader.class)); @@ -110,7 +110,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Drift of the Dead", 86, Rarity.COMMON, mage.cards.d.DriftOfTheDead.class)); cards.add(new SetCardInfo("Dwarven Ruins", 227, Rarity.UNCOMMON, mage.cards.d.DwarvenRuins.class)); cards.add(new SetCardInfo("Dystopia", 88, Rarity.RARE, mage.cards.d.Dystopia.class)); - cards.add(new SetCardInfo("Earthlink", 192, Rarity.RARE, mage.cards.e.Earthlink.class)); + cards.add(new SetCardInfo("Earthlink", 192, Rarity.RARE, mage.cards.e.Earthlink.class)); cards.add(new SetCardInfo("Ebon Praetor", 89, Rarity.RARE, mage.cards.e.EbonPraetor.class)); cards.add(new SetCardInfo("Ebon Stronghold", 228, Rarity.UNCOMMON, mage.cards.e.EbonStronghold.class)); cards.add(new SetCardInfo("Elemental Augury", 193, Rarity.RARE, mage.cards.e.ElementalAugury.class)); @@ -122,6 +122,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 47, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 124, Rarity.COMMON, mage.cards.e.Errantry.class)); + cards.add(new SetCardInfo("Essence Flare", 48, Rarity.COMMON, mage.cards.e.EssenceFlare.class)); cards.add(new SetCardInfo("Farrel's Mantle", 13, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class)); cards.add(new SetCardInfo("Farrel's Zealot", 14, Rarity.UNCOMMON, FarrelsZealot.class)); cards.add(new SetCardInfo("Feral Thallid", 161, Rarity.COMMON, mage.cards.f.FeralThallid.class)); @@ -163,7 +164,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Karplusan Giant", 133, Rarity.UNCOMMON, mage.cards.k.KarplusanGiant.class)); cards.add(new SetCardInfo("Kaysa", 170, Rarity.RARE, mage.cards.k.Kaysa.class)); cards.add(new SetCardInfo("Kjeldoran Dead", 98, Rarity.COMMON, mage.cards.k.KjeldoranDead.class)); - cards.add(new SetCardInfo("Kjeldoran Home Guard", 22, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); + cards.add(new SetCardInfo("Kjeldoran Home Guard", 22, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 233, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); cards.add(new SetCardInfo("Knight of Stromgald", 99, Rarity.UNCOMMON, mage.cards.k.KnightOfStromgald.class)); cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class)); @@ -186,7 +187,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Orcish Cannoneers", 138, Rarity.UNCOMMON, mage.cards.o.OrcishCannoneers.class)); cards.add(new SetCardInfo("Orcish Captain", 139, Rarity.UNCOMMON, mage.cards.o.OrcishCaptain.class)); cards.add(new SetCardInfo("Orcish Lumberjack", 142, Rarity.COMMON, mage.cards.o.OrcishLumberjack.class)); - cards.add(new SetCardInfo("Orcish Squatters", 143, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); + cards.add(new SetCardInfo("Orcish Squatters", 143, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); cards.add(new SetCardInfo("Orcish Veteran", 144, Rarity.COMMON, OrcishVeteran.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 25, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 26, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); @@ -216,7 +217,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Sibilant Spirit", 67, Rarity.RARE, mage.cards.s.SibilantSpirit.class)); cards.add(new SetCardInfo("Skeleton Ship", 197, Rarity.RARE, mage.cards.s.SkeletonShip.class)); cards.add(new SetCardInfo("Skull Catapult", 219, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); - cards.add(new SetCardInfo("Snow Fortress", 220, Rarity.UNCOMMON, mage.cards.s.SnowFortress.class)); + cards.add(new SetCardInfo("Snow Fortress", 220, Rarity.UNCOMMON, mage.cards.s.SnowFortress.class)); cards.add(new SetCardInfo("Snow-Covered Forest", 245, Rarity.LAND, mage.cards.s.SnowCoveredForest.class)); cards.add(new SetCardInfo("Snow-Covered Island", 242, Rarity.LAND, mage.cards.s.SnowCoveredIsland.class)); cards.add(new SetCardInfo("Snow-Covered Mountain", 244, Rarity.LAND, mage.cards.s.SnowCoveredMountain.class)); @@ -257,6 +258,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Whiteout", 185, Rarity.COMMON, mage.cards.w.Whiteout.class)); cards.add(new SetCardInfo("Wind Spirit", 75, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class)); cards.add(new SetCardInfo("Wings of Aesthir", 199, Rarity.UNCOMMON, mage.cards.w.WingsOfAesthir.class)); + cards.add(new SetCardInfo("Withering Wisps", 114, Rarity.UNCOMMON, mage.cards.w.WitheringWisps.class)); cards.add(new SetCardInfo("Wolf Pack", 187, Rarity.RARE, mage.cards.w.WolfPack.class)); cards.add(new SetCardInfo("Woolly Mammoths", 188, Rarity.COMMON, mage.cards.w.WoollyMammoths.class)); cards.add(new SetCardInfo("Yavimaya Ancients", 190, Rarity.UNCOMMON, mage.cards.y.YavimayaAncients.class)); From 1b562ab89322c721213bb761e7d65284b6b89039 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 01:27:33 +0200 Subject: [PATCH 090/164] Implemented Krovikan Plague --- Mage.Sets/src/mage/sets/Alliances.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index e4dcd5d176..6144a6e8bb 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -104,6 +104,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Keeper of Tresserhorn", 14, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 184, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); + cards.add(new SetCardInfo("Krovikan Plague", 16, Rarity.UNCOMMON, mage.cards.k.KrovikanPlague.class)); cards.add(new SetCardInfo("Lake of the Dead", 185, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); cards.add(new SetCardInfo("Library of Lat-Nam", 47, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); cards.add(new SetCardInfo("Lim-Dul's High Guard", 17, Rarity.COMMON, LimDulsHighGuard.class, NON_FULL_USE_VARIOUS)); From 81875d19dc9549389eb23cd019278524bea60da4 Mon Sep 17 00:00:00 2001 From: igoudt Date: Sat, 14 Oct 2017 10:07:17 +0200 Subject: [PATCH 091/164] revert cardtextpredicate to fix issue #4091 --- .../predicate/other/CardTextPredicate.java | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java index 2f6559a6d7..36cf356ce4 100644 --- a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java @@ -29,10 +29,13 @@ package mage.filter.predicate.other; import mage.cards.Card; import mage.cards.SplitCard; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.predicate.Predicate; import mage.game.Game; /** + * * @author North */ public class CardTextPredicate implements Predicate { @@ -61,31 +64,53 @@ public class CardTextPredicate implements Predicate { //separate by spaces String[] tokens = text.toLowerCase().split(" "); - boolean found = false; for (String token : tokens) { + boolean found = false; if (!token.isEmpty()) { // then try to find in rules if (inRules) { if (input.isSplitCard()) { - found = ((SplitCard) input).getLeftHalfCard().getRules(game).stream().anyMatch(rule -> rule.toLowerCase().contains(token.toLowerCase())); - found |= ((SplitCard) input).getRightHalfCard().getRules(game).stream().anyMatch(rule -> rule.toLowerCase().contains(token.toLowerCase())); - - } else { - found = input.getRules(game).stream().anyMatch(rule -> rule.toLowerCase().contains(token.toLowerCase())); + for (String rule : ((SplitCard) input).getLeftHalfCard().getRules(game)) { + if (rule.toLowerCase().contains(token)) { + found = true; + break; + } + } + for (String rule : ((SplitCard) input).getRightHalfCard().getRules(game)) { + if (rule.toLowerCase().contains(token)) { + found = true; + break; + } + } + } + for (String rule : input.getRules(game)) { + if (rule.toLowerCase().contains(token)) { + found = true; + break; + } } } if (inTypes) { - found |= input.getSubtype(game).stream().anyMatch(s -> s.toString().equalsIgnoreCase(token)); - found |= input.getSuperType().stream().anyMatch(s -> s.toString().equalsIgnoreCase(token)); + for (SubType subType : input.getSubtype(game)) { + if (subType.toString().equalsIgnoreCase(token)) { + found = true; + break; + } + } + for (SuperType superType : input.getSuperType()) { + if (superType.toString().equalsIgnoreCase(token)) { + found = true; + break; + } + } } } - if (found) { - break; + if (!found) { + return false; } - } - return found; + return true; } @Override From f7cd19fe7c9e3835b465fae299c802c100d8f3cc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:20:39 +0200 Subject: [PATCH 092/164] Implemented Essence Filter --- Mage.Sets/src/mage/cards/e/EssenceFilter.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EssenceFilter.java diff --git a/Mage.Sets/src/mage/cards/e/EssenceFilter.java b/Mage.Sets/src/mage/cards/e/EssenceFilter.java new file mode 100644 index 0000000000..173ec2d5c3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EssenceFilter.java @@ -0,0 +1,108 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 & L_J + */ +public class EssenceFilter extends CardImpl { + + public EssenceFilter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}{G}"); + + // Destroy all enchantments or all nonwhite enchantments. + this.getSpellAbility().addEffect(new EssenceFilterEffect()); + } + + public EssenceFilter(final EssenceFilter card) { + super(card); + } + + @Override + public EssenceFilter copy() { + return new EssenceFilter(this); + } +} + +class EssenceFilterEffect extends OneShotEffect { + + private static final FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("nonwhite enchantments"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.WHITE))); + } + + public EssenceFilterEffect() { + super(Outcome.Detriment); + this.staticText = "Destroy all enchantments or all nonwhite enchantments"; + } + + public EssenceFilterEffect(final EssenceFilterEffect effect) { + super(effect); + } + + @Override + public EssenceFilterEffect copy() { + return new EssenceFilterEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.chooseUse(outcome, "Destroy all enchantments? (otherwise all nonwhite enchantments are destroyed)", source, game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterEnchantmentPermanent(), controller.getId(), source.getSourceId(), game)) { + permanent.destroy(source.getSourceId(), game, false); + } + } else { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, controller.getId(), source.getSourceId(), game)) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } + return false; + } +} From 6b44fd1b13bb29a5ed88cbcc63a4c4f5e48b67d3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:21:21 +0200 Subject: [PATCH 093/164] Implemented Ovinomancer --- Mage.Sets/src/mage/cards/o/Ovinomancer.java | 127 ++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/Ovinomancer.java diff --git a/Mage.Sets/src/mage/cards/o/Ovinomancer.java b/Mage.Sets/src/mage/cards/o/Ovinomancer.java new file mode 100644 index 0000000000..e712246b3e --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/Ovinomancer.java @@ -0,0 +1,127 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SheepToken; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class Ovinomancer extends CardImpl { + + private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("basic lands"); + + static { + filter.add(new SupertypePredicate(SuperType.BASIC)); + } + + public Ovinomancer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // When Ovinomancer enters the battlefield, sacrifice it unless you return three basic lands you control to their owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(3, 3, filter, true))))); + + // {T}, Return Ovinomancer to its owner's hand: Destroy target creature. It can't be regenerated. That creature's controller creates a 0/1 green Sheep creature token. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new TapSourceCost()); + ability.addEffect(new OvinomancerEffect()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public Ovinomancer(final Ovinomancer card) { + super(card); + } + + @Override + public Ovinomancer copy() { + return new Ovinomancer(this); + } +} + +class OvinomancerEffect extends OneShotEffect { + + public OvinomancerEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "That creature's controller creates a 0/1 green Sheep creature token"; + } + + public OvinomancerEffect(final OvinomancerEffect effect) { + super(effect); + } + + @Override + public OvinomancerEffect copy() { + return new OvinomancerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID targetId = getTargetPointer().getFirst(game, source); + if (targetId != null) { + Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); + if (permanent != null) { + UUID controllerId = permanent.getControllerId(); + if (controllerId != null) { + new SheepToken().putOntoBattlefield(1, game, source.getSourceId(), controllerId); + return true; + } + } + } + return false; + } +} From 5735515a31af05710faee21520e36e90fdb81ad2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:22:53 +0200 Subject: [PATCH 094/164] Implemented Ovinomancer --- .../mage/game/permanent/token/SheepToken.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Mage/src/main/java/mage/game/permanent/token/SheepToken.java diff --git a/Mage/src/main/java/mage/game/permanent/token/SheepToken.java b/Mage/src/main/java/mage/game/permanent/token/SheepToken.java new file mode 100644 index 0000000000..5d20d01cd9 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/SheepToken.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author L_J + */ +public class SheepToken extends Token { + + public SheepToken() { + super("Sheep", "0/1 green Sheep creature token"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.SHEEP); + power = new MageInt(0); + toughness = new MageInt(1); + } +} From e99c4e975b64a3a635bb98c188dc398bb9fbd478 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:24:13 +0200 Subject: [PATCH 095/164] Implemented Spike Tiller --- Mage.Sets/src/mage/cards/s/SpikeTiller.java | 99 +++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpikeTiller.java diff --git a/Mage.Sets/src/mage/cards/s/SpikeTiller.java b/Mage.Sets/src/mage/cards/s/SpikeTiller.java new file mode 100644 index 0000000000..f34e199014 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpikeTiller.java @@ -0,0 +1,99 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.permanent.token.Token; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author L_J + */ +public class SpikeTiller extends CardImpl { + + public SpikeTiller(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}"); + this.subtype.add(SubType.SPIKE); + + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Spike Tiller enters the battlefield with three +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it")); + + // {2}, Remove a +1/+1 counter from Spike Tiller: Put a +1/+1 counter on target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)); + ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // {2}, Remove a +1/+1 counter from Spike Tiller: Target land becomes a 2/2 creature that's still a land. Put a +1/+1 counter on it. + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(new SpikeTillerToken(), false, true, Duration.EndOfGame).setText("Target land becomes a 2/2 creature that's still a land. "), new GenericManaCost(2)); + ability2.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); + ability2.addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()).setText("Put a +1/+1 counter on it.")); + ability2.addTarget(new TargetLandPermanent()); + this.addAbility(ability2); + } + + public SpikeTiller(final SpikeTiller card) { + super(card); + } + + @Override + public SpikeTiller copy() { + return new SpikeTiller(this); + } +} + +class SpikeTillerToken extends Token { + + public SpikeTillerToken() { + super("", "2/2 creature"); + cardType.add(CardType.CREATURE); + power = new MageInt(2); + toughness = new MageInt(2); + } +} From aef315700315e295f7645cf2948d45ed88065866 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:25:08 +0200 Subject: [PATCH 096/164] Implemented Treacherous Urge --- .../src/mage/cards/t/TreacherousUrge.java | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TreacherousUrge.java diff --git a/Mage.Sets/src/mage/cards/t/TreacherousUrge.java b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java new file mode 100644 index 0000000000..399ebf0dba --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java @@ -0,0 +1,136 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class TreacherousUrge extends CardImpl { + + public TreacherousUrge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{B}"); + this.subtype.add(SubType.ARCANE); + + // Target opponent reveals his or her hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step. + this.getSpellAbility().addEffect(new TreacherousUrgeEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + public TreacherousUrge(final TreacherousUrge card) { + super(card); + } + + @Override + public TreacherousUrge copy() { + return new TreacherousUrge(this); + } +} + +class TreacherousUrgeEffect extends OneShotEffect { + + private static final FilterCreatureCard filter = new FilterCreatureCard(); + + public TreacherousUrgeEffect() { + super(Outcome.Benefit); + this.staticText = "Target opponent reveals his or her hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step"; + } + + public TreacherousUrgeEffect(final TreacherousUrgeEffect effect) { + super(effect); + } + + @Override + public TreacherousUrgeEffect copy() { + return new TreacherousUrgeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (opponent != null && sourceObject != null) { + opponent.revealCards(sourceObject.getName(), opponent.getHand(), game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int cardsHand = opponent.getHand().count(filter, game); + Card card = null; + if (cardsHand > 0) { + TargetCard target = new TargetCard(Zone.HAND, filter); + if (controller.choose(Outcome.Benefit, opponent.getHand(), target, game)) { + card = opponent.getHand().get(target.getFirstTarget(), game); + if (card != null) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName(), source.getControllerId()); + sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } + } + } + return false; + } + } + } + return true; + } + return false; + } +} From 7e9a40791bc82af36ed0b71c51d2cdf0b7b12457 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:26:12 +0200 Subject: [PATCH 097/164] Implemented Essence Filter --- Mage.Sets/src/mage/sets/IceAge.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 6fc1a0ccdc..2f96059ac1 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -118,6 +118,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Energy Storm", 248, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 67, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 183, Rarity.COMMON, mage.cards.e.Errantry.class)); + cards.add(new SetCardInfo("Essence Filter", 121, Rarity.COMMON, mage.cards.e.EssenceFilter.class)); cards.add(new SetCardInfo("Essence Flare", 69, Rarity.COMMON, mage.cards.e.EssenceFlare.class)); cards.add(new SetCardInfo("Fanatical Fever", 122, Rarity.UNCOMMON, mage.cards.f.FanaticalFever.class)); cards.add(new SetCardInfo("Fear", 12, Rarity.COMMON, mage.cards.f.Fear.class)); From 05d018fd81c16883d09ba169f3162a84ea4616cc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:27:02 +0200 Subject: [PATCH 098/164] Implemented Essence Filter --- Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index f5e4a5efa7..2b276c52b3 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -122,6 +122,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 47, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 124, Rarity.COMMON, mage.cards.e.Errantry.class)); + cards.add(new SetCardInfo("Essence Filter", 160, Rarity.UNCOMMON, mage.cards.e.EssenceFilter.class)); cards.add(new SetCardInfo("Essence Flare", 48, Rarity.COMMON, mage.cards.e.EssenceFlare.class)); cards.add(new SetCardInfo("Farrel's Mantle", 13, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class)); cards.add(new SetCardInfo("Farrel's Zealot", 14, Rarity.UNCOMMON, FarrelsZealot.class)); From 8913b1506e3beb414eca91b16e953072957fbdbe Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:27:45 +0200 Subject: [PATCH 099/164] Implemented Ovinomancer --- Mage.Sets/src/mage/sets/Visions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index aae2e5afb1..06465ba0d5 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -130,6 +130,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Necromancy", 14, Rarity.UNCOMMON, mage.cards.n.Necromancy.class)); cards.add(new SetCardInfo("Necrosavant", 15, Rarity.RARE, mage.cards.n.Necrosavant.class)); cards.add(new SetCardInfo("Nekrataal", 16, Rarity.UNCOMMON, mage.cards.n.Nekrataal.class)); + cards.add(new SetCardInfo("Ovinomancer", 39, Rarity.UNCOMMON, mage.cards.o.Ovinomancer.class)); cards.add(new SetCardInfo("Panther Warriors", 65, Rarity.COMMON, mage.cards.p.PantherWarriors.class)); cards.add(new SetCardInfo("Parapet", 114, Rarity.COMMON, mage.cards.p.Parapet.class)); cards.add(new SetCardInfo("Phyrexian Marauder", 151, Rarity.RARE, mage.cards.p.PhyrexianMarauder.class)); From dc3e6dfea6a6b02f3095f4ce248f581a94e08dea Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:28:49 +0200 Subject: [PATCH 100/164] Implemented Ovinomancer & added missing cards --- Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java index 7ba5c96d1f..6702f567dd 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java +++ b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java @@ -52,6 +52,7 @@ public class TimeSpiralTimeshifted extends ExpansionSet { this.hasBasicLands = false; cards.add(new SetCardInfo("Akroma, Angel of Wrath", 1, Rarity.COMMON, mage.cards.a.AkromaAngelOfWrath.class)); cards.add(new SetCardInfo("Arena", 117, Rarity.SPECIAL, mage.cards.a.Arena.class)); + cards.add(new SetCardInfo("Assault // Battery", 106, Rarity.SPECIAL, mage.cards.a.AssaultBattery.class)); cards.add(new SetCardInfo("Auratog", 2, Rarity.COMMON, mage.cards.a.Auratog.class)); cards.add(new SetCardInfo("Avalanche Riders", 55, Rarity.COMMON, mage.cards.a.AvalancheRiders.class)); cards.add(new SetCardInfo("Avatar of Woe", 37, Rarity.SPECIAL, mage.cards.a.AvatarOfWoe.class)); @@ -94,6 +95,7 @@ public class TimeSpiralTimeshifted extends ExpansionSet { cards.add(new SetCardInfo("Ghost Ship", 21, Rarity.SPECIAL, mage.cards.g.GhostShip.class)); cards.add(new SetCardInfo("Goblin Snowman", 64, Rarity.UNCOMMON, mage.cards.g.GoblinSnowman.class)); cards.add(new SetCardInfo("Grinning Totem", 110, Rarity.SPECIAL, mage.cards.g.GrinningTotem.class)); + cards.add(new SetCardInfo("Hail Storm", 79, Rarity.SPECIAL, mage.cards.h.HailStorm.class)); cards.add(new SetCardInfo("Hunting Moa", 80, Rarity.COMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Icatian Javelineers", 10, Rarity.SPECIAL, IcatianJavelineers.class)); cards.add(new SetCardInfo("Jasmine Boreal", 93, Rarity.COMMON, mage.cards.j.JasmineBoreal.class)); @@ -114,6 +116,7 @@ public class TimeSpiralTimeshifted extends ExpansionSet { cards.add(new SetCardInfo("Nicol Bolas", 98, Rarity.SPECIAL, mage.cards.n.NicolBolas.class)); cards.add(new SetCardInfo("Orcish Librarian", 66, Rarity.SPECIAL, mage.cards.o.OrcishLibrarian.class)); cards.add(new SetCardInfo("Orgg", 67, Rarity.SPECIAL, mage.cards.o.Orgg.class)); + cards.add(new SetCardInfo("Ovinomancer", 27, Rarity.SPECIAL, mage.cards.o.Ovinomancer.class)); cards.add(new SetCardInfo("Pandemonium", 68, Rarity.SPECIAL, mage.cards.p.Pandemonium.class)); cards.add(new SetCardInfo("Pendelhaven", 120, Rarity.COMMON, mage.cards.p.Pendelhaven.class)); cards.add(new SetCardInfo("Pirate Ship", 28, Rarity.SPECIAL, mage.cards.p.PirateShip.class)); From 8444237189e75736bd3dad238869576817d038d7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:29:39 +0200 Subject: [PATCH 101/164] Implemented Spike Tiller --- Mage.Sets/src/mage/sets/TimeSpiral.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/sets/TimeSpiral.java b/Mage.Sets/src/mage/sets/TimeSpiral.java index 645e5ec3d2..900cf73069 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiral.java +++ b/Mage.Sets/src/mage/sets/TimeSpiral.java @@ -73,8 +73,8 @@ public class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Deep-Sea Kraken", 56, Rarity.RARE, mage.cards.d.DeepSeaKraken.class)); cards.add(new SetCardInfo("Dementia Sliver", 236, Rarity.UNCOMMON, mage.cards.d.DementiaSliver.class)); cards.add(new SetCardInfo("Demonic Collusion", 103, Rarity.RARE, mage.cards.d.DemonicCollusion.class)); - cards.add(new SetCardInfo("Detainment Spell", 12, Rarity.COMMON, mage.cards.d.DetainmentSpell.class)); - cards.add(new SetCardInfo("Divine Congregation", 13, Rarity.COMMON, mage.cards.d.DivineCongregation.class)); + cards.add(new SetCardInfo("Detainment Spell", 12, Rarity.COMMON, mage.cards.d.DetainmentSpell.class)); + cards.add(new SetCardInfo("Divine Congregation", 13, Rarity.COMMON, mage.cards.d.DivineCongregation.class)); cards.add(new SetCardInfo("Draining Whelk", 57, Rarity.RARE, mage.cards.d.DrainingWhelk.class)); cards.add(new SetCardInfo("Dralnu, Lich Lord", 237, Rarity.RARE, mage.cards.d.DralnuLichLord.class)); cards.add(new SetCardInfo("Dread Return", 104, Rarity.UNCOMMON, mage.cards.d.DreadReturn.class)); @@ -101,7 +101,7 @@ public class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Flamecore Elemental", 154, Rarity.COMMON, mage.cards.f.FlamecoreElemental.class)); cards.add(new SetCardInfo("Fledgling Mawcor", 63, Rarity.UNCOMMON, mage.cards.f.FledglingMawcor.class)); cards.add(new SetCardInfo("Flickering Spirit", 17, Rarity.COMMON, mage.cards.f.FlickeringSpirit.class)); - cards.add(new SetCardInfo("Flowstone Channeler", 155, Rarity.COMMON, mage.cards.f.FlowstoneChanneler.class)); + cards.add(new SetCardInfo("Flowstone Channeler", 155, Rarity.COMMON, mage.cards.f.FlowstoneChanneler.class)); cards.add(new SetCardInfo("Fool's Demise", 64, Rarity.UNCOMMON, mage.cards.f.FoolsDemise.class)); cards.add(new SetCardInfo("Forest", 298, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 299, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); @@ -246,6 +246,7 @@ public class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Spectral Force", 217, Rarity.RARE, mage.cards.s.SpectralForce.class)); cards.add(new SetCardInfo("Spell Burst", 79, Rarity.UNCOMMON, mage.cards.s.SpellBurst.class)); cards.add(new SetCardInfo("Spiketail Drakeling", 80, Rarity.COMMON, mage.cards.s.SpiketailDrakeling.class)); + cards.add(new SetCardInfo("Spike Tiller", 218, Rarity.RARE, mage.cards.s.SpikeTiller.class)); cards.add(new SetCardInfo("Spinneret Sliver", 219, Rarity.COMMON, mage.cards.s.SpinneretSliver.class)); cards.add(new SetCardInfo("Spirit Loop", 42, Rarity.UNCOMMON, mage.cards.s.SpiritLoop.class)); cards.add(new SetCardInfo("Sporesower Thallid", 220, Rarity.UNCOMMON, mage.cards.s.SporesowerThallid.class)); @@ -307,8 +308,8 @@ public class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Volcanic Awakening", 186, Rarity.UNCOMMON, mage.cards.v.VolcanicAwakening.class)); cards.add(new SetCardInfo("Walk the Aeons", 93, Rarity.RARE, mage.cards.w.WalkTheAeons.class)); cards.add(new SetCardInfo("Watcher Sliver", 45, Rarity.COMMON, mage.cards.w.WatcherSliver.class)); - cards.add(new SetCardInfo("Weathered Bodyguards", 46, Rarity.RARE, mage.cards.w.WeatheredBodyguards.class)); - cards.add(new SetCardInfo("Weatherseed Totem", 268, Rarity.UNCOMMON, mage.cards.w.WeatherseedTotem.class)); + cards.add(new SetCardInfo("Weathered Bodyguards", 46, Rarity.RARE, mage.cards.w.WeatheredBodyguards.class)); + cards.add(new SetCardInfo("Weatherseed Totem", 268, Rarity.UNCOMMON, mage.cards.w.WeatherseedTotem.class)); cards.add(new SetCardInfo("Wheel of Fate", 187, Rarity.RARE, mage.cards.w.WheelOfFate.class)); cards.add(new SetCardInfo("Wipe Away", 94, Rarity.UNCOMMON, mage.cards.w.WipeAway.class)); cards.add(new SetCardInfo("Word of Seizing", 188, Rarity.RARE, mage.cards.w.WordOfSeizing.class)); From a134962e830f9d3316cf98a2b19f496f251d2c09 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 10:30:05 +0200 Subject: [PATCH 102/164] Implemented Treacherous Urge --- Mage.Sets/src/mage/sets/PlanarChaos.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/PlanarChaos.java b/Mage.Sets/src/mage/sets/PlanarChaos.java index a3e52b2ad7..d68966c157 100644 --- a/Mage.Sets/src/mage/sets/PlanarChaos.java +++ b/Mage.Sets/src/mage/sets/PlanarChaos.java @@ -123,7 +123,7 @@ public class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Kavu Predator", 132, Rarity.UNCOMMON, mage.cards.k.KavuPredator.class)); cards.add(new SetCardInfo("Keen Sense", 152, Rarity.UNCOMMON, mage.cards.k.KeenSense.class)); cards.add(new SetCardInfo("Keldon Marauders", 102, Rarity.COMMON, mage.cards.k.KeldonMarauders.class)); - cards.add(new SetCardInfo("Kor Dirge", 87, Rarity.UNCOMMON, mage.cards.k.KorDirge.class)); + cards.add(new SetCardInfo("Kor Dirge", 87, Rarity.UNCOMMON, mage.cards.k.KorDirge.class)); cards.add(new SetCardInfo("Lavacore Elemental", 103, Rarity.UNCOMMON, mage.cards.l.LavacoreElemental.class)); cards.add(new SetCardInfo("Life and Limb", 133, Rarity.RARE, mage.cards.l.LifeAndLimb.class)); cards.add(new SetCardInfo("Magus of the Arena", 104, Rarity.RARE, mage.cards.m.MagusOfTheArena.class)); @@ -200,11 +200,12 @@ public class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Timbermare", 140, Rarity.RARE, mage.cards.t.Timbermare.class)); cards.add(new SetCardInfo("Timecrafting", 109, Rarity.UNCOMMON, mage.cards.t.Timecrafting.class)); cards.add(new SetCardInfo("Torchling", 110, Rarity.RARE, mage.cards.t.Torchling.class)); + cards.add(new SetCardInfo("Treacherous Urge", 82, Rarity.UNCOMMON, mage.cards.t.TreacherousUrge.class)); cards.add(new SetCardInfo("Uktabi Drake", 141, Rarity.COMMON, mage.cards.u.UktabiDrake.class)); cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", 165, Rarity.RARE, mage.cards.u.UrborgTombOfYawgmoth.class)); cards.add(new SetCardInfo("Utopia Vow", 142, Rarity.COMMON, mage.cards.u.UtopiaVow.class)); cards.add(new SetCardInfo("Vampiric Link", 92, Rarity.COMMON, mage.cards.v.VampiricLink.class)); - cards.add(new SetCardInfo("Veiling Oddity", 51, Rarity.COMMON, mage.cards.v.VeilingOddity.class)); + cards.add(new SetCardInfo("Veiling Oddity", 51, Rarity.COMMON, mage.cards.v.VeilingOddity.class)); cards.add(new SetCardInfo("Venarian Glimmer", 52, Rarity.UNCOMMON, mage.cards.v.VenarianGlimmer.class)); cards.add(new SetCardInfo("Vitaspore Thallid", 143, Rarity.COMMON, mage.cards.v.VitasporeThallid.class)); cards.add(new SetCardInfo("Voidstone Gargoyle", 21, Rarity.RARE, mage.cards.v.VoidstoneGargoyle.class)); From ee3784dcc7c5ef6aaa6da1a9ad75b5f80f26ef80 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 14 Oct 2017 14:43:12 +0200 Subject: [PATCH 103/164] Removed subtype rudiment --- Mage.Sets/src/mage/cards/t/TreacherousUrge.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/TreacherousUrge.java b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java index 399ebf0dba..edaa9445bc 100644 --- a/Mage.Sets/src/mage/cards/t/TreacherousUrge.java +++ b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java @@ -41,7 +41,6 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; @@ -61,7 +60,6 @@ public class TreacherousUrge extends CardImpl { public TreacherousUrge(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{B}"); - this.subtype.add(SubType.ARCANE); // Target opponent reveals his or her hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step. this.getSpellAbility().addEffect(new TreacherousUrgeEffect()); From 79d4c07d20f5b64cf9e1b7f081dc256b469ba7a1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 14 Oct 2017 08:42:13 -0400 Subject: [PATCH 104/164] updated how Withering Wisps and limited use activated abilities are implemented --- .../src/mage/cards/w/WitheringWisps.java | 54 ++++--------------- .../mage/abilities/ActivatedAbilityImpl.java | 16 ++++-- 2 files changed, 21 insertions(+), 49 deletions(-) diff --git a/Mage.Sets/src/mage/cards/w/WitheringWisps.java b/Mage.Sets/src/mage/cards/w/WitheringWisps.java index e59ec2c7a0..016f2091e0 100644 --- a/Mage.Sets/src/mage/cards/w/WitheringWisps.java +++ b/Mage.Sets/src/mage/cards/w/WitheringWisps.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.TriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.CreatureCountCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalTriggeredAbility; @@ -50,7 +49,6 @@ import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.util.CardUtil; /** * @@ -61,7 +59,7 @@ public class WitheringWisps extends CardImpl { private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice {this}."; public WitheringWisps(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}"); // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Withering Wisps. TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); @@ -83,63 +81,31 @@ public class WitheringWisps extends CardImpl { class WitheringWispsActivatedAbility extends ActivatedAbilityImpl { - static class ActivationInfo { + private static final FilterPermanent filter = new FilterPermanent("snow Swamps you control"); - public int turnNum; - public int activationCounter; - - public ActivationInfo(int turnNum, int activationCounter) { - this.turnNum = turnNum; - this.activationCounter = activationCounter; - } - } - - private static final FilterPermanent filter = new FilterPermanent("snow lands you control"); - { + static { filter.add(new SupertypePredicate(SuperType.SNOW)); filter.add(new SubtypePredicate(SubType.SWAMP)); filter.add(new ControllerPredicate(TargetController.YOU)); } - - private int maxActivationsPerTurn(Game game) { + + @Override + public int getMaxActivationsPerTurn(Game game) { return game.getBattlefield().getAllActivePermanents(filter, game).size(); } - + public WitheringWispsActivatedAbility() { super(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{B}")); - + } public WitheringWispsActivatedAbility(final WitheringWispsActivatedAbility ability) { super(ability); } - - protected boolean hasMoreActivationsThisTurn(Game game) { - if (this.maxActivationsPerTurn(game) > 0) { - ActivationInfo activationInfo = getActivationInfo(game); - return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < this.maxActivationsPerTurn(game); - } - return false; - } - - private ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); - if (turnNum == null || activationCount == null) { - return null; - } - return new ActivationInfo(turnNum, activationCount); - } - - @Override - public boolean resolve(Game game) { - return super.resolve(game); - } - + @Override public String getRule() { - StringBuilder sb = new StringBuilder(super.getRule()).append(" Activate this ability no more times each turn than the number of snow Swamps you control."); - return sb.toString(); + return super.getRule() + " Activate this ability no more times each turn than the number of snow Swamps you control."; } @Override diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index cb8d83d483..0c63d4595b 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -54,7 +54,7 @@ import mage.util.CardUtil; */ public abstract class ActivatedAbilityImpl extends AbilityImpl implements ActivatedAbility { - static class ActivationInfo { + protected static class ActivationInfo { public int turnNum; public int activationCounter; @@ -276,11 +276,13 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } protected boolean hasMoreActivationsThisTurn(Game game) { - if (maxActivationsPerTurn == Integer.MAX_VALUE) { + if (getMaxActivationsPerTurn(game) == Integer.MAX_VALUE) { return true; } ActivationInfo activationInfo = getActivationInfo(game); - return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; + return activationInfo == null + || activationInfo.turnNum != game.getTurnNum() + || activationInfo.activationCounter < getMaxActivationsPerTurn(game); } @Override @@ -307,7 +309,11 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa this.maxActivationsPerTurn = maxActivationsPerTurn; } - private ActivationInfo getActivationInfo(Game game) { + public int getMaxActivationsPerTurn(Game game) { + return maxActivationsPerTurn; + } + + protected ActivationInfo getActivationInfo(Game game) { Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); if (turnNum == null || activationCount == null) { @@ -316,7 +322,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return new ActivationInfo(turnNum, activationCount); } - private void setActivationInfo(ActivationInfo activationInfo, Game game) { + protected void setActivationInfo(ActivationInfo activationInfo, Game game) { game.getState().setValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); game.getState().setValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game), activationInfo.activationCounter); } From 5fbdca0b28a7b02e975f97b4f4887a4f1bd00a54 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:17:22 +0200 Subject: [PATCH 105/164] Fixed blocker selection bug The prior version didn't allow you to pick blockers if you weren't the attacking player (for example, in an EDH game if you activate this during another players turn and you're not the defender) --- Mage.Sets/src/mage/cards/b/BrutalHordechief.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java index 9add26359b..3311459c09 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java +++ b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java @@ -151,7 +151,11 @@ class BrutalHordechiefReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getPlayerId().equals(source.getControllerId()); + Player blockController = game.getPlayer(source.getControllerId()); + if (blockController != null) { + return true; + } + return false; } @Override From f5569f9c0a0b53472a713c62a0e3178ce4642164 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:20:14 +0200 Subject: [PATCH 106/164] Implemented Master Warcraft There's still line 190 left to fix... --- .../src/mage/cards/m/MasterWarcraft.java | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MasterWarcraft.java diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java new file mode 100644 index 0000000000..4ad9242b8a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -0,0 +1,249 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.condition.common.BeforeAttackersAreDeclaredCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.RequirementEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect; +import mage.abilities.effects.common.combat.CantAttackTargetEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class MasterWarcraft extends CardImpl { + + public MasterWarcraft(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R/W}{R/W}"); + + // Cast Master Warcraft only before attackers are declared. + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeAttackersAreDeclaredCondition.instance)); + + // You choose which creatures attack this turn. + this.getSpellAbility().addEffect(new MasterWarcraftChooseAttackersEffect().setText("You choose which creatures attack this turn.")); + + // You choose which creatures block this turn and how those creatures block. + this.getSpellAbility().addEffect(new MasterWarcraftChooseBlockersEffect().setText("You choose which creatures block this turn and how those creatures block.")); + } + + public MasterWarcraft(final MasterWarcraft card) { + super(card); + } + + @Override + public MasterWarcraft copy() { + return new MasterWarcraft(this); + } +} + +class MasterWarcraftChooseAttackersEffect extends ReplacementEffectImpl { + + public MasterWarcraftChooseAttackersEffect() { + super(Duration.EndOfTurn, Outcome.Benefit); + this.staticText = "You choose which creatures attack this turn."; + } + + public MasterWarcraftChooseAttackersEffect(final MasterWarcraftChooseAttackersEffect effect) { + super(effect); + } + + @Override + public MasterWarcraftChooseAttackersEffect copy() { + return new MasterWarcraftChooseAttackersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player chooser = game.getPlayer(source.getControllerId()); + if (chooser != null) { + new MasterWarcraftAttackEffect().apply(game, source); // Master Warcraft imposes its effect right before the attackers being declared... + } + return false; // ...and then resumes the attack declaration + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARING_ATTACKERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player chooser = game.getPlayer(source.getControllerId()); + Player attackingPlayer = game.getPlayer(game.getCombat().getAttackingPlayerId()); + if (chooser != null && attackingPlayer != null && !attackingPlayer.getAvailableAttackers(game).isEmpty()) { + return true; + } + return false; + } +} + +class MasterWarcraftAttackEffect extends OneShotEffect { + + MasterWarcraftAttackEffect() { + super(Outcome.Benefit); + } + + MasterWarcraftAttackEffect(final MasterWarcraftAttackEffect effect) { + super(effect); + } + + @Override + public MasterWarcraftAttackEffect copy() { + return new MasterWarcraftAttackEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Target target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"), true); + if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { + if (target.getTargets().contains(permanent.getId())) { + RequirementEffect effect = new AttacksIfAbleTargetEffect(Duration.EndOfCombat); + effect.setText(""); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } else { + RestrictionEffect effect = new MasterWarcraftCantAttackRestrictionEffect(); + effect.setText(""); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + } + return true; + } + } + return false; + } +} + +class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { + + MasterWarcraftCantAttackRestrictionEffect() { + super(Duration.EndOfCombat); + } + + MasterWarcraftCantAttackRestrictionEffect(final MasterWarcraftCantAttackRestrictionEffect effect) { + super(effect); + } + + @Override + public MasterWarcraftCantAttackRestrictionEffect copy() { + return new MasterWarcraftCantAttackRestrictionEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + // TODO: Make Master Warcraft still respect "This must attack if able" clauses + return this.getTargetPointer().getFirst(game, source).equals(permanent.getId()); + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public String getText(Mode mode) { + return "Unless {this} must attack, {this} can't attack."; + } +} + +class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { + + public MasterWarcraftChooseBlockersEffect() { + super(Duration.EndOfTurn, Outcome.Benefit); + staticText = "You choose which creatures block this turn and how those creatures block."; + } + + public MasterWarcraftChooseBlockersEffect(final MasterWarcraftChooseBlockersEffect effect) { + super(effect); + } + + @Override + public MasterWarcraftChooseBlockersEffect copy() { + return new MasterWarcraftChooseBlockersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARING_BLOCKERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player blockController = game.getPlayer(source.getControllerId()); + if (blockController != null) { + return true; + } + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player blockController = game.getPlayer(source.getControllerId()); + if (blockController != null) { + game.getCombat().selectBlockers(blockController, game); + return true; + } + return false; + } +} From 9563ea84be4ea631882deddf13c898d8ab31086f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:21:34 +0200 Subject: [PATCH 107/164] Implemented Master Warcraft --- Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java index 8bea79044a..f2884e0aa5 100644 --- a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java +++ b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java @@ -213,6 +213,7 @@ public class RavnicaCityOfGuilds extends ExpansionSet { cards.add(new SetCardInfo("Loxodon Hierarch", 214, Rarity.RARE, mage.cards.l.LoxodonHierarch.class)); cards.add(new SetCardInfo("Lurking Informant", 249, Rarity.COMMON, mage.cards.l.LurkingInformant.class)); cards.add(new SetCardInfo("Mark of Eviction", 58, Rarity.UNCOMMON, mage.cards.m.MarkOfEviction.class)); + cards.add(new SetCardInfo("Master Warcraft", 250, Rarity.RARE, mage.cards.m.MasterWarcraft.class)); cards.add(new SetCardInfo("Mausoleum Turnkey", 94, Rarity.UNCOMMON, mage.cards.m.MausoleumTurnkey.class)); cards.add(new SetCardInfo("Mindleech Mass", 215, Rarity.RARE, mage.cards.m.MindleechMass.class)); cards.add(new SetCardInfo("Mindmoil", 135, Rarity.RARE, mage.cards.m.Mindmoil.class)); From cc95002beeaa8a585f8b0ea844de116728ce1cfd Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:23:18 +0200 Subject: [PATCH 108/164] Implemented Master Warcraft --- Mage.Sets/src/mage/sets/Commander.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Commander.java b/Mage.Sets/src/mage/sets/Commander.java index a87566d11e..3460d42679 100644 --- a/Mage.Sets/src/mage/sets/Commander.java +++ b/Mage.Sets/src/mage/sets/Commander.java @@ -210,6 +210,7 @@ public class Commander extends ExpansionSet { cards.add(new SetCardInfo("Malfegor", 208, Rarity.MYTHIC, mage.cards.m.Malfegor.class)); cards.add(new SetCardInfo("Mana-Charged Dragon", 129, Rarity.RARE, mage.cards.m.ManaChargedDragon.class)); cards.add(new SetCardInfo("Martyr's Bond", 19, Rarity.RARE, mage.cards.m.MartyrsBond.class)); + cards.add(new SetCardInfo("Master Warcraft", 209, Rarity.RARE, mage.cards.m.MasterWarcraft.class)); cards.add(new SetCardInfo("Memory Erosion", 50, Rarity.RARE, mage.cards.m.MemoryErosion.class)); cards.add(new SetCardInfo("Minds Aglow", 51, Rarity.RARE, mage.cards.m.MindsAglow.class)); cards.add(new SetCardInfo("Molten Slagheap", 282, Rarity.UNCOMMON, mage.cards.m.MoltenSlagheap.class)); From 5e25d77eda5cb5734cb5e68120de48300e89fd8e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:23:26 +0200 Subject: [PATCH 109/164] Implemented Master Warcraft --- Mage.Sets/src/mage/sets/CommanderAnthology.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/CommanderAnthology.java b/Mage.Sets/src/mage/sets/CommanderAnthology.java index fc943136b2..7142cee09a 100644 --- a/Mage.Sets/src/mage/sets/CommanderAnthology.java +++ b/Mage.Sets/src/mage/sets/CommanderAnthology.java @@ -207,6 +207,7 @@ public class CommanderAnthology extends ExpansionSet { cards.add(new SetCardInfo("Malfegor", 184, Rarity.MYTHIC, mage.cards.m.Malfegor.class)); cards.add(new SetCardInfo("Mana-Charged Dragon", 84, Rarity.RARE, mage.cards.m.ManaChargedDragon.class)); cards.add(new SetCardInfo("Masked Admirers", 127, Rarity.UNCOMMON, mage.cards.m.MaskedAdmirers.class)); + cards.add(new SetCardInfo("Master Warcraft", 202, Rarity.RARE, mage.cards.m.MasterWarcraft.class)); cards.add(new SetCardInfo("Mazirek, Kraul Death Priest", 185, Rarity.MYTHIC, mage.cards.m.MazirekKraulDeathPriest.class)); cards.add(new SetCardInfo("Meren of Clan Nel Toth", 186, Rarity.MYTHIC, mage.cards.m.MerenOfClanNelToth.class)); cards.add(new SetCardInfo("Mirror Entity", 16, Rarity.RARE, mage.cards.m.MirrorEntity.class)); From 56d93b0def77825c3f8edbc395e643de581ab0a6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 16:41:15 +0200 Subject: [PATCH 110/164] Imports cleanup --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 4ad9242b8a..6cbe123eac 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; import mage.abilities.condition.common.BeforeAttackersAreDeclaredCondition; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; @@ -39,8 +38,6 @@ import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect; -import mage.abilities.effects.common.combat.CantAttackTargetEffect; -import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; From 4155b30af33d66dfa0e39e5e8abf12129bc0378f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 23:20:27 +0200 Subject: [PATCH 111/164] Added missing "mustn't must attack" clause & some text fixes --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 6cbe123eac..4c9cae6674 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -27,7 +27,7 @@ */ package mage.cards.m; -import java.util.UUID; +import java.util.*; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; @@ -64,10 +64,10 @@ public class MasterWarcraft extends CardImpl { this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeAttackersAreDeclaredCondition.instance)); // You choose which creatures attack this turn. - this.getSpellAbility().addEffect(new MasterWarcraftChooseAttackersEffect().setText("You choose which creatures attack this turn.")); + this.getSpellAbility().addEffect(new MasterWarcraftChooseAttackersEffect()); // You choose which creatures block this turn and how those creatures block. - this.getSpellAbility().addEffect(new MasterWarcraftChooseBlockersEffect().setText("You choose which creatures block this turn and how those creatures block.")); + this.getSpellAbility().addEffect(new MasterWarcraftChooseBlockersEffect()); } public MasterWarcraft(final MasterWarcraft card) { @@ -84,7 +84,7 @@ class MasterWarcraftChooseAttackersEffect extends ReplacementEffectImpl { public MasterWarcraftChooseAttackersEffect() { super(Duration.EndOfTurn, Outcome.Benefit); - this.staticText = "You choose which creatures attack this turn."; + this.staticText = "You choose which creatures attack this turn"; } public MasterWarcraftChooseAttackersEffect(final MasterWarcraftChooseAttackersEffect effect) { @@ -184,7 +184,12 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - // TODO: Make Master Warcraft still respect "This must attack if able" clauses + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { + RequirementEffect effect = entry.getKey(); + if (effect.mustAttack(game)) { + return false; + } + } return this.getTargetPointer().getFirst(game, source).equals(permanent.getId()); } @@ -203,7 +208,7 @@ class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { public MasterWarcraftChooseBlockersEffect() { super(Duration.EndOfTurn, Outcome.Benefit); - staticText = "You choose which creatures block this turn and how those creatures block."; + staticText = "You choose which creatures block this turn and how those creatures block"; } public MasterWarcraftChooseBlockersEffect(final MasterWarcraftChooseBlockersEffect effect) { From 6400a401d4eac4744b324fccc16520701055fcf4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 15 Oct 2017 23:26:11 +0200 Subject: [PATCH 112/164] Oversight fix --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 4c9cae6674..7216c62d05 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -183,14 +183,14 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } @Override - public boolean applies(Permanent permanent, Ability source, Game game) { + public boolean applies(Permanent creature, Ability source, Game game) { for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { RequirementEffect effect = entry.getKey(); if (effect.mustAttack(game)) { return false; } } - return this.getTargetPointer().getFirst(game, source).equals(permanent.getId()); + return this.getTargetPointer().getFirst(game, source).equals(creature.getId()); } @Override From e967c3951322f26cbd25ded5c489bdcbbccd2e62 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 15 Oct 2017 20:07:08 -0400 Subject: [PATCH 113/164] fixed Mana Maze not allowing colorless spells to be cast (fixes #4112) --- Mage.Sets/src/mage/cards/m/ManaMaze.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/ManaMaze.java b/Mage.Sets/src/mage/cards/m/ManaMaze.java index 9730300223..02038f0e61 100644 --- a/Mage.Sets/src/mage/cards/m/ManaMaze.java +++ b/Mage.Sets/src/mage/cards/m/ManaMaze.java @@ -53,11 +53,10 @@ import mage.watchers.Watcher; public class ManaMaze extends CardImpl { public ManaMaze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); // Players can't cast spells that share a color with the spell most recently cast this turn. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ManaMazeEffect()), new LastSpellCastWatcher()); - } public ManaMaze(final ManaMaze card) { @@ -91,9 +90,8 @@ class ManaMazeEffect extends ContinuousRuleModifyingEffectImpl { Card card = game.getCard(event.getSourceId()); if (card != null) { LastSpellCastWatcher watcher = (LastSpellCastWatcher) game.getState().getWatchers().get(LastSpellCastWatcher.class.getSimpleName()); - if (watcher != null - && watcher.lastSpellCast != null) { - return card.getColor(game).contains(watcher.lastSpellCast.getColor(game)); + if (watcher != null && watcher.lastSpellCast != null) { + return !card.getColor(game).intersection(watcher.lastSpellCast.getColor(game)).isColorless(); } } return false; From f6c76026e80b8096b66f0db41e24b701b7317e6d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 15 Oct 2017 20:15:32 -0400 Subject: [PATCH 114/164] fixed Gate to the Afterlife not triggering correctly --- Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java index bae5b782c8..1f1879647e 100644 --- a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java +++ b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java @@ -29,7 +29,7 @@ package mage.cards.g; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.condition.common.CardsInControllerGraveCondition; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; @@ -75,15 +75,17 @@ public class GateToTheAfterlife extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Whenever a nontoken creature you control dies, you gain 1 life. Then you may draw a card. If you do, discard a card. - Ability ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility(new GainLifeEffect(1), false, filter, false, true); + Ability ability = new DiesCreatureTriggeredAbility(new GainLifeEffect(1), false, filter, false); Effect effect = new DrawDiscardControllerEffect(1, 1, true); effect.setText("Then you may draw a card. If you do, discard a card"); ability.addEffect(effect); this.addAbility(ability); // {2}, {T}, Sacrifice Gate to the Afterlife: Search your graveyard, hand, and/or library for a card named God-Pharaoh's Gift and put it onto the battlefield. If you seearch your library this way, shuffle it. Activate this ability only if there are six or more creature cards in your graveyard. - ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, - new GateToTheAfterlifeEffect(), new GenericManaCost(2), new CardsInControllerGraveCondition(6, new FilterCreatureCard())); + ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, new GateToTheAfterlifeEffect(), new GenericManaCost(2), + new CardsInControllerGraveCondition(6, new FilterCreatureCard()) + ); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); From 1c258c6b9f776e59efef7e3eaa7138fa9b4693ef Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 15 Oct 2017 20:48:26 -0400 Subject: [PATCH 115/164] fixed Lightmine Field damaging creatures which weren't declared as attackers (fixes #4111) --- .../src/mage/cards/l/LightmineField.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/l/LightmineField.java b/Mage.Sets/src/mage/cards/l/LightmineField.java index 2b4b8aaf72..7f9e081f62 100644 --- a/Mage.Sets/src/mage/cards/l/LightmineField.java +++ b/Mage.Sets/src/mage/cards/l/LightmineField.java @@ -27,10 +27,15 @@ */ package mage.cards.l; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -49,7 +54,7 @@ import mage.game.permanent.Permanent; public class LightmineField extends CardImpl { public LightmineField(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // Whenever one or more creatures attack, Lightmine Field deals damage to each of those creatures equal to the number of attacking creatures. this.addAbility(new LightmineFieldTriggeredAbility()); @@ -87,7 +92,17 @@ class LightmineFieldTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return !game.getCombat().getAttackers().isEmpty(); + Set attackSet = new HashSet<>(); + for (UUID attackerId : game.getCombat().getAttackers()) { + Permanent attacker = game.getPermanent(attackerId); + if (attacker != null) { + attackSet.add(new MageObjectReference(attacker, game)); + } + } + for (Effect effect : getEffects()) { + effect.setValue("Lightmine Field", attackSet); + } + return !attackSet.isEmpty(); } @Override @@ -116,9 +131,11 @@ class LightmineFieldEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { List attackers = game.getCombat().getAttackers(); int damage = attackers.size(); + Set attackSet = (Set) getValue("Lightmine Field"); if (!attackers.isEmpty()) { - for (UUID attacker : attackers) { - Permanent creature = game.getPermanent(attacker); + for (Iterator it = attackSet.iterator(); it.hasNext();) { + MageObjectReference attacker = it.next(); + Permanent creature = attacker.getPermanent(game); if (creature != null) { creature.damage(damage, source.getSourceId(), game, false, true); } From 587e8a75ef0e1df15f1d857231223bef3b9e2d54 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 17:04:04 -0400 Subject: [PATCH 116/164] fixed phased-out permanents not being invalid targets upon resolution --- Mage/src/main/java/mage/filter/FilterPermanent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/filter/FilterPermanent.java b/Mage/src/main/java/mage/filter/FilterPermanent.java index 287c4df445..1f4acaa17a 100644 --- a/Mage/src/main/java/mage/filter/FilterPermanent.java +++ b/Mage/src/main/java/mage/filter/FilterPermanent.java @@ -73,7 +73,7 @@ public class FilterPermanent extends FilterObject implements FilterIn @Override public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - if (!this.match(permanent, game)) { + if (!permanent.isPhasedIn() || !this.match(permanent, game)) { return false; } From 457269cb1205914ec8a28a4bab7f702d2a5b3f91 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 18:12:57 -0400 Subject: [PATCH 117/164] fixed some range of influence issues --- Mage.Sets/src/mage/cards/e/EnsnaringBridge.java | 10 +++++----- Mage.Sets/src/mage/cards/p/PriceOfGlory.java | 16 ++++++++++------ Mage/src/main/java/mage/players/PlayerImpl.java | 7 ++++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java b/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java index ba74af82a2..d0d676f67f 100644 --- a/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java +++ b/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java @@ -47,7 +47,7 @@ import mage.players.Player; public class EnsnaringBridge extends CardImpl { public EnsnaringBridge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Creatures with power greater than the number of cards in your hand can't attack. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EnsnaringBridgeRestrictionEffect())); @@ -63,7 +63,6 @@ public class EnsnaringBridge extends CardImpl { } } - class EnsnaringBridgeRestrictionEffect extends RestrictionEffect { public EnsnaringBridgeRestrictionEffect() { @@ -78,10 +77,11 @@ class EnsnaringBridgeRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - return permanent.getPower().getValue() > controller.getHand().size(); + if (controller == null) { + return false; } - return false; + return controller.getInRange().contains(permanent.getControllerId()) + && permanent.getPower().getValue() > controller.getHand().size(); } @Override diff --git a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java index 35e30e70bf..8f039fcdad 100644 --- a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java +++ b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java @@ -50,8 +50,7 @@ import mage.target.targetpointer.FixedTarget; public class PriceOfGlory extends CardImpl { public PriceOfGlory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); // Whenever a player taps a land for mana, if it's not that player's turn, destroy that land. this.addAbility(new PriceOfGloryAbility()); @@ -86,11 +85,16 @@ class PriceOfGloryAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanent(event.getSourceId()); + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (permanent == null) { - permanent = (Permanent) game.getLastKnownInformation(event.getSourceId(), Zone.BATTLEFIELD); + return false; } - if (permanent != null && permanent.isLand() + Player player = game.getPlayer(controllerId); + if (player == null) { + return false; + } + if (permanent.isLand() + && player.getInRange().contains(permanent.getControllerId()) && !permanent.getControllerId().equals(game.getActivePlayerId())) { // intervening if clause getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId())); return true; @@ -125,7 +129,7 @@ class PriceOfGloryEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Permanent land = game.getPermanentOrLKIBattlefield(this.targetPointer.getFirst(game, source)); - if (land != null && !land.getControllerId().equals(game.getActivePlayerId())) { // intervening if clause has to be checked again + if (land != null && !land.getControllerId().equals(game.getActivePlayerId())) { // intervening if clause has to be checked again land.destroy(source.getSourceId(), game, false); } return true; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 1567246fda..dac2bddf9a 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -3484,9 +3484,10 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean hasOpponent(UUID playerToCheckId, Game game - ) { - return !this.getId().equals(playerToCheckId) && game.isOpponent(this, playerToCheckId); + public boolean hasOpponent(UUID playerToCheckId, Game game) { + return !this.getId().equals(playerToCheckId) + && game.isOpponent(this, playerToCheckId) + && getInRange().contains(playerToCheckId); } @Override From 6605c212e4c3237772dac7c6c6e8a9ee308c6281 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 17 Oct 2017 02:30:12 +0400 Subject: [PATCH 118/164] Update AjaniTest.java typo comment --- .../test/java/org/mage/test/cards/planeswalker/AjaniTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/AjaniTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/AjaniTest.java index 7e0b24aa51..6a341d7b9b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/AjaniTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/AjaniTest.java @@ -81,7 +81,7 @@ public class AjaniTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Kor Ally", 2); assertPermanentCount(playerA, "Oath of Gideon", 1); assertPermanentCount(playerA, "Ajani Goldmane", 1); - assertCounterCount("Ajani Goldmane", CounterType.LOYALTY, 6); // 5 + 1 = 5 + assertCounterCount("Ajani Goldmane", CounterType.LOYALTY, 6); // 4 + 1 + 1 = 6 assertLife(playerA, 22); assertLife(playerB, 20); From e65d3429059741ac6412856b41e4ee8f9700fb30 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 18:29:35 -0400 Subject: [PATCH 119/164] Implemented Imperial Edict --- Mage.Sets/src/mage/cards/i/ImperialEdict.java | 106 ++++++++++++++++++ .../src/mage/sets/PortalThreeKingdoms.java | 1 + 2 files changed, 107 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/ImperialEdict.java diff --git a/Mage.Sets/src/mage/cards/i/ImperialEdict.java b/Mage.Sets/src/mage/cards/i/ImperialEdict.java new file mode 100644 index 0000000000..90179d846b --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ImperialEdict.java @@ -0,0 +1,106 @@ +/* + * 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.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class ImperialEdict extends CardImpl { + + public ImperialEdict(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + // Target opponent chooses a creature he or she controls. Destroy it. + this.getSpellAbility().addEffect(new ImperialEdictEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + public ImperialEdict(final ImperialEdict card) { + super(card); + } + + @Override + public ImperialEdict copy() { + return new ImperialEdict(this); + } +} + +class ImperialEdictEffect extends OneShotEffect { + + ImperialEdictEffect() { + super(Outcome.Benefit); + this.staticText = "Target opponent chooses a creature he or she controls. Destroy it."; + } + + ImperialEdictEffect(final ImperialEdictEffect effect) { + super(effect); + } + + @Override + public ImperialEdictEffect copy() { + return new ImperialEdictEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null) { + return false; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + filter.add(new ControllerIdPredicate(player.getId())); + Target target = new TargetPermanent(1, 1, filter, true); + if (target.canChoose(source.getSourceId(), player.getId(), game)) { + while (!target.isChosen() && target.canChoose(player.getId(), game) && player.canRespond()) { + player.chooseTarget(Outcome.DestroyPermanent, target, source, game); + } + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 4970599957..7721b87843 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -100,6 +100,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Huang Zhong, Shu General", 8, Rarity.RARE, mage.cards.h.HuangZhongShuGeneral.class)); cards.add(new SetCardInfo("Hua Tuo, Honored Physician", 137, Rarity.RARE, mage.cards.h.HuaTuoHonoredPhysician.class)); cards.add(new SetCardInfo("Hunting Cheetah", 138, Rarity.UNCOMMON, mage.cards.h.HuntingCheetah.class)); + cards.add(new SetCardInfo("Imperial Edict", 77, Rarity.COMMON, mage.cards.i.ImperialEdict.class)); cards.add(new SetCardInfo("Imperial Recruiter", 113, Rarity.UNCOMMON, mage.cards.i.ImperialRecruiter.class)); cards.add(new SetCardInfo("Imperial Seal", 78, Rarity.RARE, mage.cards.i.ImperialSeal.class)); cards.add(new SetCardInfo("Independent Troops", 114, Rarity.COMMON, mage.cards.i.IndependentTroops.class)); From 0f4a61e737c59dce4fa431566d67324e13718930 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 18:32:29 -0400 Subject: [PATCH 120/164] Implemented Wei Assassins --- Mage.Sets/src/mage/cards/w/WeiAssassins.java | 116 ++++++++++++++++++ .../src/mage/sets/PortalThreeKingdoms.java | 1 + 2 files changed, 117 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WeiAssassins.java diff --git a/Mage.Sets/src/mage/cards/w/WeiAssassins.java b/Mage.Sets/src/mage/cards/w/WeiAssassins.java new file mode 100644 index 0000000000..282f9b0dc0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WeiAssassins.java @@ -0,0 +1,116 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class WeiAssassins extends CardImpl { + + public WeiAssassins(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Wei Assassins enters the battlefield, target opponent chooses a creature he or she controls. Destroy it. + Ability ability = new EntersBattlefieldTriggeredAbility(new WeiAssassinsEffect(), false); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public WeiAssassins(final WeiAssassins card) { + super(card); + } + + @Override + public WeiAssassins copy() { + return new WeiAssassins(this); + } +} + +class WeiAssassinsEffect extends OneShotEffect { + + WeiAssassinsEffect() { + super(Outcome.Benefit); + this.staticText = "target opponent chooses a creature he or she controls. Destroy it."; + } + + WeiAssassinsEffect(final WeiAssassinsEffect effect) { + super(effect); + } + + @Override + public WeiAssassinsEffect copy() { + return new WeiAssassinsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null) { + return false; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + filter.add(new ControllerIdPredicate(player.getId())); + Target target = new TargetPermanent(1, 1, filter, true); + if (target.canChoose(source.getSourceId(), player.getId(), game)) { + while (!target.isChosen() && target.canChoose(player.getId(), game) && player.canRespond()) { + player.chooseTarget(Outcome.DestroyPermanent, target, source, game); + } + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 7721b87843..2705ebde52 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -183,6 +183,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Volunteer Militia", 30, Rarity.COMMON, mage.cards.v.VolunteerMilitia.class)); cards.add(new SetCardInfo("Warrior's Oath", 124, Rarity.RARE, mage.cards.w.WarriorsOath.class)); cards.add(new SetCardInfo("Wei Ambush Force", 85, Rarity.COMMON, mage.cards.w.WeiAmbushForce.class)); + cards.add(new SetCardInfo("Wei Assassins", 86, Rarity.UNCOMMON, mage.cards.w.WeiAssassins.class)); cards.add(new SetCardInfo("Wei Elite Companions", 87, Rarity.UNCOMMON, mage.cards.w.WeiEliteCompanions.class)); cards.add(new SetCardInfo("Wei Infantry", 88, Rarity.COMMON, mage.cards.w.WeiInfantry.class)); cards.add(new SetCardInfo("Wei Night Raiders", 89, Rarity.UNCOMMON, mage.cards.w.WeiNightRaiders.class)); From ba31763a7ad6da933a441f6deb036cc4c5464720 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:05:39 -0400 Subject: [PATCH 121/164] Implemented Rally the Troops --- .../src/mage/cards/r/RallyTheTroops.java | 72 ++++++++++++++++ Mage.Sets/src/mage/sets/PortalSecondAge.java | 1 + .../src/mage/sets/PortalThreeKingdoms.java | 1 + .../common/AttackedThisStepCondition.java | 52 ++++++++++++ .../common/PlayerAttackedStepWatcher.java | 82 +++++++++++++++++++ 5 files changed, 208 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RallyTheTroops.java create mode 100644 Mage/src/main/java/mage/abilities/condition/common/AttackedThisStepCondition.java create mode 100644 Mage/src/main/java/mage/watchers/common/PlayerAttackedStepWatcher.java diff --git a/Mage.Sets/src/mage/cards/r/RallyTheTroops.java b/Mage.Sets/src/mage/cards/r/RallyTheTroops.java new file mode 100644 index 0000000000..4974b7b806 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RallyTheTroops.java @@ -0,0 +1,72 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.filter.StaticFilters; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class RallyTheTroops extends CardImpl { + + public RallyTheTroops(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Cast Rally the Troops only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Untap all creatures you control. + this.getSpellAbility().addEffect(new UntapAllControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURES)); + } + + public RallyTheTroops(final RallyTheTroops card) { + super(card); + } + + @Override + public RallyTheTroops copy() { + return new RallyTheTroops(this); + } +} diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index 16e6adfa71..b73ec75ef0 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -165,6 +165,7 @@ public class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Raiding Nightstalker", 24, Rarity.COMMON, mage.cards.r.RaidingNightstalker.class)); cards.add(new SetCardInfo("Rain of Daggers", 25, Rarity.RARE, mage.cards.r.RainOfDaggers.class)); cards.add(new SetCardInfo("Raise Dead", 26, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Rally the Troops", 139, Rarity.UNCOMMON, mage.cards.r.RallyTheTroops.class)); cards.add(new SetCardInfo("Ravenous Rats", 27, Rarity.COMMON, mage.cards.r.RavenousRats.class)); cards.add(new SetCardInfo("Razorclaw Bear", 82, Rarity.RARE, mage.cards.r.RazorclawBear.class)); cards.add(new SetCardInfo("Renewing Touch", 83, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 2705ebde52..89c183628d 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -135,6 +135,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Plains", 168, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Poison Arrow", 80, Rarity.UNCOMMON, mage.cards.p.PoisonArrow.class)); cards.add(new SetCardInfo("Preemptive Strike", 50, Rarity.COMMON, mage.cards.p.PreemptiveStrike.class)); + cards.add(new SetCardInfo("Rally the Troops", 16, Rarity.UNCOMMON, mage.cards.r.RallyTheTroops.class)); cards.add(new SetCardInfo("Ravages of War", 17, Rarity.RARE, mage.cards.r.RavagesOfWar.class)); cards.add(new SetCardInfo("Ravaging Horde", 118, Rarity.UNCOMMON, mage.cards.r.RavagingHorde.class)); cards.add(new SetCardInfo("Red Cliffs Armada", 51, Rarity.UNCOMMON, mage.cards.r.RedCliffsArmada.class)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/AttackedThisStepCondition.java b/Mage/src/main/java/mage/abilities/condition/common/AttackedThisStepCondition.java new file mode 100644 index 0000000000..7ecc8fb53c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/AttackedThisStepCondition.java @@ -0,0 +1,52 @@ +/* + * 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.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * @author LevelX2 + */ +public enum AttackedThisStepCondition implements Condition { + + instance; + + @Override + public boolean apply(Game game, Ability source) { + PlayerAttackedStepWatcher watcher = (PlayerAttackedStepWatcher) game.getState().getWatchers().get(PlayerAttackedStepWatcher.class.getSimpleName()); + return watcher != null + && watcher.getNumberAttackingCurrentStep(source.getControllerId()) > 0; + } + + public String toString() { + return "during the declare attackers step and only if you've been attacked this step."; + } +} diff --git a/Mage/src/main/java/mage/watchers/common/PlayerAttackedStepWatcher.java b/Mage/src/main/java/mage/watchers/common/PlayerAttackedStepWatcher.java new file mode 100644 index 0000000000..03f56c9beb --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/PlayerAttackedStepWatcher.java @@ -0,0 +1,82 @@ +/* + * 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.watchers.common; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +/** + * @author LevelX2 + */ +public class PlayerAttackedStepWatcher extends Watcher { + + // With how many creatures attacked this player this turn + private final Map playerAttacked = new HashMap<>(); + + public PlayerAttackedStepWatcher() { + super(PlayerAttackedWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public PlayerAttackedStepWatcher(final PlayerAttackedStepWatcher watcher) { + super(watcher); + for (Map.Entry entry : watcher.playerAttacked.entrySet()) { + this.playerAttacked.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public PlayerAttackedStepWatcher copy() { + return new PlayerAttackedStepWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DECLARE_ATTACKERS_STEP_POST) { + playerAttacked.clear(); + } + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { + playerAttacked.putIfAbsent(event.getTargetId(), 0); + playerAttacked.compute(event.getTargetId(), (p, amount) -> amount + 1); + } + } + + @Override + public void reset() { + super.reset(); + playerAttacked.clear(); + } + + public int getNumberAttackingCurrentStep(UUID playerId) { + return playerAttacked.getOrDefault(playerId, 0); + } +} From ed8de87226c5a7474efe114426d385ec5cacb026 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:10:13 -0400 Subject: [PATCH 122/164] Implemented Eightfold Maze --- Mage.Sets/src/mage/cards/e/EightfoldMaze.java | 73 +++++++++++++++++++ .../src/mage/sets/MastersEditionIII.java | 1 + .../src/mage/sets/PortalThreeKingdoms.java | 1 + 3 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EightfoldMaze.java diff --git a/Mage.Sets/src/mage/cards/e/EightfoldMaze.java b/Mage.Sets/src/mage/cards/e/EightfoldMaze.java new file mode 100644 index 0000000000..293c3b0792 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EightfoldMaze.java @@ -0,0 +1,73 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.target.common.TargetAttackingCreature; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class EightfoldMaze extends CardImpl { + + public EightfoldMaze(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Cast Eightfold Maze only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Destroy target attacking creature. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public EightfoldMaze(final EightfoldMaze card) { + super(card); + } + + @Override + public EightfoldMaze copy() { + return new EightfoldMaze(this); + } +} diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index a46ec0ceb0..a9a8ee82a1 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -103,6 +103,7 @@ public class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Disharmony", 95, Rarity.UNCOMMON, mage.cards.d.Disharmony.class)); cards.add(new SetCardInfo("Divine Intervention", 8, Rarity.RARE, mage.cards.d.DivineIntervention.class)); cards.add(new SetCardInfo("Dong Zhou, the Tyrant", 96, Rarity.RARE, mage.cards.d.DongZhouTheTyrant.class)); + cards.add(new SetCardInfo("Eightfold Maze", 9, Rarity.UNCOMMON, mage.cards.e.EightfoldMaze.class)); cards.add(new SetCardInfo("Elves of Deep Shadow", 116, Rarity.COMMON, mage.cards.e.ElvesOfDeepShadow.class)); cards.add(new SetCardInfo("Evil Presence", 64, Rarity.COMMON, mage.cards.e.EvilPresence.class)); cards.add(new SetCardInfo("Exorcist", 10, Rarity.UNCOMMON, mage.cards.e.Exorcist.class)); diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 89c183628d..416798faf9 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -80,6 +80,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Desperate Charge", 74, Rarity.UNCOMMON, mage.cards.d.DesperateCharge.class)); cards.add(new SetCardInfo("Diaochan, Artful Beauty", 108, Rarity.RARE, mage.cards.d.DiaochanArtfulBeauty.class)); cards.add(new SetCardInfo("Dong Zhou, the Tyrant", 109, Rarity.RARE, mage.cards.d.DongZhouTheTyrant.class)); + cards.add(new SetCardInfo("Eightfold Maze", 2, Rarity.RARE, mage.cards.e.EightfoldMaze.class)); cards.add(new SetCardInfo("Empty City Ruse", 3, Rarity.UNCOMMON, mage.cards.e.EmptyCityRuse.class)); cards.add(new SetCardInfo("Exhaustion", 42, Rarity.RARE, mage.cards.e.Exhaustion.class)); cards.add(new SetCardInfo("Extinguish", 43, Rarity.COMMON, mage.cards.e.Extinguish.class)); From 5dc58c23ed29022b13637c3f4ab10391462c7e99 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:13:03 -0400 Subject: [PATCH 123/164] Implemented Champion's Victory --- .../src/mage/cards/c/ChampionsVictory.java | 73 +++++++++++++++++++ .../src/mage/sets/PortalThreeKingdoms.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChampionsVictory.java diff --git a/Mage.Sets/src/mage/cards/c/ChampionsVictory.java b/Mage.Sets/src/mage/cards/c/ChampionsVictory.java new file mode 100644 index 0000000000..a3d2222ee2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChampionsVictory.java @@ -0,0 +1,73 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.target.common.TargetAttackingCreature; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class ChampionsVictory extends CardImpl { + + public ChampionsVictory(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + + // Cast Champion's Victory only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Return target attacking creature to its owner's hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public ChampionsVictory(final ChampionsVictory card) { + super(card); + } + + @Override + public ChampionsVictory copy() { + return new ChampionsVictory(this); + } +} diff --git a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java index 416798faf9..bc64a4afe9 100644 --- a/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java +++ b/Mage.Sets/src/mage/sets/PortalThreeKingdoms.java @@ -68,6 +68,7 @@ public class PortalThreeKingdoms extends ExpansionSet { cards.add(new SetCardInfo("Cao Cao, Lord of Wei", 68, Rarity.RARE, mage.cards.c.CaoCaoLordOfWei.class)); cards.add(new SetCardInfo("Cao Ren, Wei Commander", 69, Rarity.RARE, mage.cards.c.CaoRenWeiCommander.class)); cards.add(new SetCardInfo("Capture of Jingzhou", 38, Rarity.RARE, mage.cards.c.CaptureOfJingzhou.class)); + cards.add(new SetCardInfo("Champion's Victory", 39, Rarity.UNCOMMON, mage.cards.c.ChampionsVictory.class)); cards.add(new SetCardInfo("Coercion", 70, Rarity.UNCOMMON, mage.cards.c.Coercion.class)); cards.add(new SetCardInfo("Control of the Court", 105, Rarity.UNCOMMON, mage.cards.c.ControlOfTheCourt.class)); cards.add(new SetCardInfo("Corrupt Court Official", 71, Rarity.UNCOMMON, mage.cards.c.CorruptCourtOfficial.class)); From c624cf9e5e0c5a820793e51d10d1535e37c744c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:16:30 -0400 Subject: [PATCH 124/164] Implemented Assassin's Blade --- .../src/mage/cards/a/AssassinsBlade.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/Portal.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AssassinsBlade.java diff --git a/Mage.Sets/src/mage/cards/a/AssassinsBlade.java b/Mage.Sets/src/mage/cards/a/AssassinsBlade.java new file mode 100644 index 0000000000..88c4ebf61d --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AssassinsBlade.java @@ -0,0 +1,85 @@ +/* + * 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.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class AssassinsBlade extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack attacking creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + filter.add(new AttackingPredicate()); + } + + public AssassinsBlade(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // Cast Assassin's Blade only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Destroy target nonblack attacking creature. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public AssassinsBlade(final AssassinsBlade card) { + super(card); + } + + @Override + public AssassinsBlade copy() { + return new AssassinsBlade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index 7551940ca8..93a720e123 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -71,6 +71,7 @@ public class Portal extends ExpansionSet { cards.add(new SetCardInfo("Armageddon", 167, Rarity.RARE, mage.cards.a.Armageddon.class)); cards.add(new SetCardInfo("Armored Pegasus", 168, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); cards.add(new SetCardInfo("Arrogant Vampire", 1, Rarity.UNCOMMON, mage.cards.a.ArrogantVampire.class)); + cards.add(new SetCardInfo("Assassin's Blade", 2, Rarity.UNCOMMON, mage.cards.a.AssassinsBlade.class)); cards.add(new SetCardInfo("Balance of Power", 42, Rarity.RARE, mage.cards.b.BalanceOfPower.class)); cards.add(new SetCardInfo("Baleful Stare", 43, Rarity.UNCOMMON, mage.cards.b.BalefulStare.class)); cards.add(new SetCardInfo("Bee Sting", 83, Rarity.UNCOMMON, mage.cards.b.BeeSting.class)); From 940a28daf2cd0425e054d889acc907f7f6d6fbc1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:19:53 -0400 Subject: [PATCH 125/164] Implemented Command of Unsummoning --- .../mage/cards/c/CommandOfUnsummoning.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/Portal.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CommandOfUnsummoning.java diff --git a/Mage.Sets/src/mage/cards/c/CommandOfUnsummoning.java b/Mage.Sets/src/mage/cards/c/CommandOfUnsummoning.java new file mode 100644 index 0000000000..9ea9c2069f --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CommandOfUnsummoning.java @@ -0,0 +1,74 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.filter.common.FilterAttackingCreature; +import mage.target.common.TargetAttackingCreature; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class CommandOfUnsummoning extends CardImpl { + + public CommandOfUnsummoning(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + // Cast Command of Unsummoning only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Return one or two target attacking creatures to their owner's hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setText("Return one or two target attacking creatures to their owner's hand.")); + this.getSpellAbility().addTarget(new TargetAttackingCreature(1, 2, new FilterAttackingCreature(), false)); + } + + public CommandOfUnsummoning(final CommandOfUnsummoning card) { + super(card); + } + + @Override + public CommandOfUnsummoning copy() { + return new CommandOfUnsummoning(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index 93a720e123..9f7cc244ca 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -95,6 +95,7 @@ public class Portal extends ExpansionSet { cards.add(new SetCardInfo("Cloud Dragon", 46, Rarity.RARE, mage.cards.c.CloudDragon.class)); cards.add(new SetCardInfo("Cloud Pirates", 47, Rarity.COMMON, mage.cards.c.CloudPirates.class)); cards.add(new SetCardInfo("Cloud Spirit", 48, Rarity.UNCOMMON, mage.cards.c.CloudSpirit.class)); + cards.add(new SetCardInfo("Command of Unsummoning", 49, Rarity.UNCOMMON, mage.cards.c.CommandOfUnsummoning.class)); cards.add(new SetCardInfo("Coral Eel", 50, Rarity.COMMON, mage.cards.c.CoralEel.class)); cards.add(new SetCardInfo("Craven Giant", 126, Rarity.COMMON, mage.cards.c.CravenGiant.class)); cards.add(new SetCardInfo("Craven Knight", 7, Rarity.COMMON, mage.cards.c.CravenKnight.class)); From e7520967fda8b077aba0f6e6f8497d51093b9e75 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:22:38 -0400 Subject: [PATCH 126/164] Implemented Defiant Stand --- Mage.Sets/src/mage/cards/d/DefiantStand.java | 76 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Portal.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DefiantStand.java diff --git a/Mage.Sets/src/mage/cards/d/DefiantStand.java b/Mage.Sets/src/mage/cards/d/DefiantStand.java new file mode 100644 index 0000000000..cc089e3303 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DefiantStand.java @@ -0,0 +1,76 @@ +/* + * 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.d; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class DefiantStand extends CardImpl { + + public DefiantStand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Cast Defiant Stand only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Target creature gets +1/+3 until end of turn. Untap that creature. + this.getSpellAbility().addEffect(new BoostTargetEffect(1, 3, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public DefiantStand(final DefiantStand card) { + super(card); + } + + @Override + public DefiantStand copy() { + return new DefiantStand(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index 9f7cc244ca..e39c63572d 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -102,6 +102,7 @@ public class Portal extends ExpansionSet { cards.add(new SetCardInfo("Cruel Bargain", 8, Rarity.RARE, mage.cards.c.CruelBargain.class)); cards.add(new SetCardInfo("Cruel Tutor", 9, Rarity.RARE, mage.cards.c.CruelTutor.class)); cards.add(new SetCardInfo("Deep-Sea Serpent", 52, Rarity.UNCOMMON, mage.cards.d.DeepSeaSerpent.class)); + cards.add(new SetCardInfo("Defiant Stand", 174, Rarity.UNCOMMON, mage.cards.d.DefiantStand.class)); cards.add(new SetCardInfo("Deja Vu", 53, Rarity.COMMON, mage.cards.d.DejaVu.class)); cards.add(new SetCardInfo("Desert Drake", 127, Rarity.UNCOMMON, mage.cards.d.DesertDrake.class)); cards.add(new SetCardInfo("Devastation", 128, Rarity.RARE, mage.cards.d.Devastation.class)); From 433195efe833036793d1b61083b6f0b3a1d5737c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:25:26 -0400 Subject: [PATCH 127/164] Implemented Scorching Winds --- .../src/mage/cards/s/ScorchingWinds.java | 72 +++++++++++++++++++ Mage.Sets/src/mage/sets/Portal.java | 1 + 2 files changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ScorchingWinds.java diff --git a/Mage.Sets/src/mage/cards/s/ScorchingWinds.java b/Mage.Sets/src/mage/cards/s/ScorchingWinds.java new file mode 100644 index 0000000000..3c5bd2a76c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScorchingWinds.java @@ -0,0 +1,72 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.DamageAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.filter.common.FilterAttackingCreature; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class ScorchingWinds extends CardImpl { + + public ScorchingWinds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + + // Cast Scorching Winds only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Scorching Winds deals 1 damage to each attacking creature. + this.getSpellAbility().addEffect(new DamageAllEffect(1, new FilterAttackingCreature())); + } + + public ScorchingWinds(final ScorchingWinds card) { + super(card); + } + + @Override + public ScorchingWinds copy() { + return new ScorchingWinds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index e39c63572d..e8d0ad4852 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -217,6 +217,7 @@ public class Portal extends ExpansionSet { cards.add(new SetCardInfo("Sacred Knight", 186, Rarity.COMMON, mage.cards.s.SacredKnight.class)); cards.add(new SetCardInfo("Sacred Nectar", 187, Rarity.COMMON, mage.cards.s.SacredNectar.class)); cards.add(new SetCardInfo("Scorching Spear", 154, Rarity.COMMON, mage.cards.s.ScorchingSpear.class)); + cards.add(new SetCardInfo("Scorching Winds", 155, Rarity.UNCOMMON, mage.cards.s.ScorchingWinds.class)); cards.add(new SetCardInfo("Seasoned Marshal", 188, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); cards.add(new SetCardInfo("Serpent Assassin", 31, Rarity.RARE, mage.cards.s.SerpentAssassin.class)); cards.add(new SetCardInfo("Serpent Warrior", 32, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); From a8f2c07fa6394b2336e2041e13b0602d019a477c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:27:25 -0400 Subject: [PATCH 128/164] Implemented Treetop Defense --- .../src/mage/cards/t/TreetopDefense.java | 73 +++++++++++++++++++ Mage.Sets/src/mage/sets/Portal.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TreetopDefense.java diff --git a/Mage.Sets/src/mage/cards/t/TreetopDefense.java b/Mage.Sets/src/mage/cards/t/TreetopDefense.java new file mode 100644 index 0000000000..c144df4dd7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TreetopDefense.java @@ -0,0 +1,73 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class TreetopDefense extends CardImpl { + + public TreetopDefense(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Cast Treetop Defense only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Creatures you control gain reach until end of turn. + this.getSpellAbility().addEffect(new GainAbilityControlledEffect(ReachAbility.getInstance(), Duration.EndOfTurn)); + } + + public TreetopDefense(final TreetopDefense card) { + super(card); + } + + @Override + public TreetopDefense copy() { + return new TreetopDefense(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index e8d0ad4852..8c15c619ed 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -252,6 +252,7 @@ public class Portal extends ExpansionSet { cards.add(new SetCardInfo("Tidal Surge", 75, Rarity.COMMON, mage.cards.t.TidalSurge.class)); cards.add(new SetCardInfo("Time Ebb", 76, Rarity.COMMON, mage.cards.t.TimeEbb.class)); cards.add(new SetCardInfo("Touch of Brilliance", 77, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); + cards.add(new SetCardInfo("Treetop Defense", 116, Rarity.RARE, mage.cards.t.TreetopDefense.class)); cards.add(new SetCardInfo("Undying Beast", 36, Rarity.COMMON, mage.cards.u.UndyingBeast.class)); cards.add(new SetCardInfo("Untamed Wilds", 117, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); cards.add(new SetCardInfo("Valorous Charge", 196, Rarity.UNCOMMON, mage.cards.v.ValorousCharge.class)); From 837db99952eeca58fe380d7dcc5ec0016f85a01c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 16 Oct 2017 20:28:23 -0400 Subject: [PATCH 129/164] Implemented Remove --- Mage.Sets/src/mage/cards/r/Remove.java | 73 ++++++++++++++++++++ Mage.Sets/src/mage/sets/PortalSecondAge.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/Remove.java diff --git a/Mage.Sets/src/mage/cards/r/Remove.java b/Mage.Sets/src/mage/cards/r/Remove.java new file mode 100644 index 0000000000..fa859c91a1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Remove.java @@ -0,0 +1,73 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; +import mage.target.common.TargetAttackingCreature; +import mage.watchers.common.PlayerAttackedStepWatcher; + +/** + * + * @author TheElk801 + */ +public class Remove extends CardImpl { + + public Remove(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + + // Cast Remove only during the declare attackers step and only if you've been attacked this step. + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast {this} only during the declare attackers step and only if you've been attacked this step." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); + + // Return target attacking creature to its owner's hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public Remove(final Remove card) { + super(card); + } + + @Override + public Remove copy() { + return new Remove(this); + } +} diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index b73ec75ef0..ced4eb2baf 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -168,6 +168,7 @@ public class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Rally the Troops", 139, Rarity.UNCOMMON, mage.cards.r.RallyTheTroops.class)); cards.add(new SetCardInfo("Ravenous Rats", 27, Rarity.COMMON, mage.cards.r.RavenousRats.class)); cards.add(new SetCardInfo("Razorclaw Bear", 82, Rarity.RARE, mage.cards.r.RazorclawBear.class)); + cards.add(new SetCardInfo("Remove", 43, Rarity.UNCOMMON, mage.cards.r.Remove.class)); cards.add(new SetCardInfo("Renewing Touch", 83, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); cards.add(new SetCardInfo("Return of the Nightstalkers", 28, Rarity.RARE, mage.cards.r.ReturnOfTheNightstalkers.class)); cards.add(new SetCardInfo("Righteous Charge", 140, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); From e65eefe5ab89982dc651d02f99dac77b2d18f1ca Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 17 Oct 2017 17:01:10 +0200 Subject: [PATCH 130/164] Rewrote a lot of code ...to handle multiple conflicting instances of Master Warcraft (still yet to rewrite the blocker effect) --- .../src/mage/cards/m/MasterWarcraft.java | 86 +++++++++++++------ 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 7216c62d05..cfbf33e8c1 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.condition.common.BeforeAttackersAreDeclaredCondition; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.RequirementEffect; @@ -58,7 +59,7 @@ import mage.target.targetpointer.FixedTarget; public class MasterWarcraft extends CardImpl { public MasterWarcraft(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R/W}{R/W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R/W}{R/W}"); // Cast Master Warcraft only before attackers are declared. this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeAttackersAreDeclaredCondition.instance)); @@ -80,11 +81,11 @@ public class MasterWarcraft extends CardImpl { } } -class MasterWarcraftChooseAttackersEffect extends ReplacementEffectImpl { +class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectImpl { public MasterWarcraftChooseAttackersEffect() { - super(Duration.EndOfTurn, Outcome.Benefit); - this.staticText = "You choose which creatures attack this turn"; + super(Duration.EndOfTurn, Outcome.Benefit, false, false); + staticText = "You choose which creatures attack this turn"; } public MasterWarcraftChooseAttackersEffect(final MasterWarcraftChooseAttackersEffect effect) { @@ -101,15 +102,6 @@ class MasterWarcraftChooseAttackersEffect extends ReplacementEffectImpl { return true; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player chooser = game.getPlayer(source.getControllerId()); - if (chooser != null) { - new MasterWarcraftAttackEffect().apply(game, source); // Master Warcraft imposes its effect right before the attackers being declared... - } - return false; // ...and then resumes the attack declaration - } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.DECLARING_ATTACKERS; @@ -120,9 +112,19 @@ class MasterWarcraftChooseAttackersEffect extends ReplacementEffectImpl { Player chooser = game.getPlayer(source.getControllerId()); Player attackingPlayer = game.getPlayer(game.getCombat().getAttackingPlayerId()); if (chooser != null && attackingPlayer != null && !attackingPlayer.getAvailableAttackers(game).isEmpty()) { - return true; + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { + // Clears previous instances of "should attack" effects + // ("shouldn't attack" effects don't need cleaning because MasterWarcraftMustAttackRequirementEffect overrides them) + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(permanent, false, game).entrySet()) { + RequirementEffect effect = entry.getKey(); + if (effect instanceof MasterWarcraftMustAttackRequirementEffect) { + effect.discard(); + } + } + } + new MasterWarcraftAttackEffect().apply(game, source); // Master Warcraft imposes its effect right before the attackers being declared... } - return false; + return false; // ...and then resumes the attack declaration for the active player as normal } } @@ -145,20 +147,28 @@ class MasterWarcraftAttackEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { + // TODO: find a way to undo creature selection Target target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"), true); if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { + + // Choose creatures that will be attacking this combat if (target.getTargets().contains(permanent.getId())) { - RequirementEffect effect = new AttacksIfAbleTargetEffect(Duration.EndOfCombat); + RequirementEffect effect = new MasterWarcraftMustAttackRequirementEffect(); effect.setText(""); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); + // TODO: find a better way to report attackers to game log + // game.informPlayers(controller.getLogName() + " has decided that " + permanent.getLogName() + " should attack this combat if able"); + + // All other creatures can't attack } else { RestrictionEffect effect = new MasterWarcraftCantAttackRestrictionEffect(); effect.setText(""); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); } + } return true; } @@ -167,6 +177,30 @@ class MasterWarcraftAttackEffect extends OneShotEffect { } } +class MasterWarcraftMustAttackRequirementEffect extends AttacksIfAbleTargetEffect { + + MasterWarcraftMustAttackRequirementEffect() { + super(Duration.EndOfCombat); + } + + MasterWarcraftMustAttackRequirementEffect(final MasterWarcraftMustAttackRequirementEffect effect) { + super(effect); + } + + @Override + public MasterWarcraftMustAttackRequirementEffect copy() { + return new MasterWarcraftMustAttackRequirementEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + if (discarded) { + return false; + } + return this.getTargetPointer().getTargets(game, source).contains(permanent.getId()); + } +} + class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { MasterWarcraftCantAttackRestrictionEffect() { @@ -183,18 +217,18 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } @Override - public boolean applies(Permanent creature, Ability source, Game game) { - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { - RequirementEffect effect = entry.getKey(); - if (effect.mustAttack(game)) { - return false; - } - } - return this.getTargetPointer().getFirst(game, source).equals(creature.getId()); + public boolean applies(Permanent permanent, Ability source, Game game) { + return this.getTargetPointer().getFirst(game, source).equals(permanent.getId()); } @Override - public boolean canAttack(Game game) { + public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) { + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, false, game).entrySet()) { + RequirementEffect effect = entry.getKey(); + if (effect.mustAttack(game)) { + return true; + } + } return false; } @@ -204,7 +238,7 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } } -class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { +class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { // TODO: replace this with ContinuousRuleModifyingEffectImpl public MasterWarcraftChooseBlockersEffect() { super(Duration.EndOfTurn, Outcome.Benefit); From 474048bcbc1603a69782961a535669591c304d21 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 17 Oct 2017 14:02:47 -0400 Subject: [PATCH 131/164] fixed implementation of Confusion in the Ranks --- .../src/mage/cards/c/ConfusionInTheRanks.java | 63 ++++++++++--------- .../src/main/java/mage/target/TargetImpl.java | 10 +-- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java b/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java index 9ce9bb67b4..b22e6a0da9 100644 --- a/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java +++ b/Mage.Sets/src/mage/cards/c/ConfusionInTheRanks.java @@ -60,21 +60,25 @@ public class ConfusionInTheRanks extends CardImpl { filter.add(Predicates.or( new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.ENCHANTMENT))); + new CardTypePredicate(CardType.ENCHANTMENT) + )); } private final UUID originalId; public ConfusionInTheRanks(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}"); // Whenever an artifact, creature, or enchantment enters the battlefield, its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents. Ability ability = new EntersBattlefieldAllTriggeredAbility( Zone.BATTLEFIELD, - new ExchangeControlTargetEffect(Duration.EndOfGame, "its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents"), - filter, - false, - SetTargetPointer.PERMANENT, - null); + new ExchangeControlTargetEffect( + Duration.EndOfGame, + "its controller chooses target permanent " + + "another player controls that shares a card type with it. " + + "Exchange control of those permanents" + ), + filter, false, SetTargetPointer.PERMANENT, null + ); ability.addTarget(new TargetPermanent()); originalId = ability.getOriginalId(); this.addAbility(ability); @@ -92,28 +96,31 @@ public class ConfusionInTheRanks extends CardImpl { for (Effect effect : ability.getEffects()) { enteringPermanentId = effect.getTargetPointer().getFirst(game, ability); } - if (enteringPermanentId != null) { - Permanent enteringPermanent = game.getPermanent(enteringPermanentId); - if (enteringPermanent != null) { - ability.setControllerId(enteringPermanent.getControllerId()); - ability.getTargets().clear(); - FilterPermanent filterTarget = new FilterPermanent(); - String message = ""; - filterTarget.add(Predicates.not(new ControllerIdPredicate(enteringPermanent.getControllerId()))); - Set cardTypesPredicates = new HashSet<>(1); - for (CardType cardTypeEntering : enteringPermanent.getCardType()) { - cardTypesPredicates.add(new CardTypePredicate(cardTypeEntering)); - if (!message.isEmpty()) { - message += "or "; - } - message += cardTypeEntering.toString().toLowerCase() + ' '; - } - filterTarget.add(Predicates.or(cardTypesPredicates)); - message += "you do not control"; - filterTarget.setMessage(message); - ability.getTargets().add(new TargetPermanent(filterTarget)); - } + if (enteringPermanentId == null) { + return; } + Permanent enteringPermanent = game.getPermanent(enteringPermanentId); + if (enteringPermanent == null) { + return; + } + ability.getTargets().clear(); + FilterPermanent filterTarget = new FilterPermanent(); + String message = ""; + filterTarget.add(Predicates.not(new ControllerIdPredicate(enteringPermanent.getControllerId()))); + Set cardTypesPredicates = new HashSet<>(1); + for (CardType cardTypeEntering : enteringPermanent.getCardType()) { + cardTypesPredicates.add(new CardTypePredicate(cardTypeEntering)); + if (!message.isEmpty()) { + message += "or "; + } + message += cardTypeEntering.toString().toLowerCase() + ' '; + } + filterTarget.add(Predicates.or(cardTypesPredicates)); + message += "you don't control"; + filterTarget.setMessage(message); + TargetPermanent target = new TargetPermanent(filterTarget); + target.setTargetController(enteringPermanent.getControllerId()); + ability.getTargets().add(target); } } diff --git a/Mage/src/main/java/mage/target/TargetImpl.java b/Mage/src/main/java/mage/target/TargetImpl.java index 3dbe7568cc..fb4aa7f6b8 100644 --- a/Mage/src/main/java/mage/target/TargetImpl.java +++ b/Mage/src/main/java/mage/target/TargetImpl.java @@ -128,11 +128,11 @@ public abstract class TargetImpl implements Target { @Override public String getMessage() { String suffix = ""; - if (targetController != null) { - // Hint for the selecting player that the targets must be valid from the point of the ability controller - // e.g. select opponent text may be misleading otherwise - suffix = " (target controlling!)"; - } +// if (targetController != null) { +// // Hint for the selecting player that the targets must be valid from the point of the ability controller +// // e.g. select opponent text may be misleading otherwise +// suffix = " (target controlling!)"; +// } if (getMaxNumberOfTargets() != 1) { StringBuilder sb = new StringBuilder(); sb.append("Select ").append(targetName); From 51221b2e3f1f8c0ae0b8fc1d8aaa3425624f69d7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 17 Oct 2017 15:32:31 -0400 Subject: [PATCH 132/164] Implemented Martyr's Cry --- Mage.Sets/src/mage/cards/m/MartyrsCry.java | 101 ++++++++++++++++++ Mage.Sets/src/mage/sets/MastersEditionIV.java | 1 + Mage.Sets/src/mage/sets/TheDark.java | 1 + 3 files changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MartyrsCry.java diff --git a/Mage.Sets/src/mage/cards/m/MartyrsCry.java b/Mage.Sets/src/mage/cards/m/MartyrsCry.java new file mode 100644 index 0000000000..0441ab4f5b --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MartyrsCry.java @@ -0,0 +1,101 @@ +/* + * 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.m; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class MartyrsCry extends CardImpl { + + public MartyrsCry(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{W}"); + + // Exile all white creatures. For each creature exiled this way, its controller draws a card. + this.getSpellAbility().addEffect(new MartyrsCryEffect()); + } + + public MartyrsCry(final MartyrsCry card) { + super(card); + } + + @Override + public MartyrsCry copy() { + return new MartyrsCry(this); + } +} + +class MartyrsCryEffect extends OneShotEffect { + + MartyrsCryEffect() { + super(Outcome.Exile); + this.staticText = "Exile all white creatures. For each creature exiled this way, its controller draws a card."; + } + + MartyrsCryEffect(final MartyrsCryEffect effect) { + super(effect); + } + + @Override + public MartyrsCryEffect copy() { + return new MartyrsCryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Map playerCrtCount = new HashMap<>(); + for (Iterator it = game.getBattlefield().getActivePermanents(source.getControllerId(), game).iterator(); it.hasNext();) { + Permanent perm = it.next(); + if (perm != null && perm.isCreature() && perm.getColor(game).isWhite() && perm.moveToExile(null, null, source.getSourceId(), game)) { + playerCrtCount.putIfAbsent(perm.getControllerId(), 0); + playerCrtCount.compute(perm.getControllerId(), (p, amount) -> amount + 1); + } + } + for (UUID playerId : game.getPlayerList().toList()) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.drawCards(playerCrtCount.getOrDefault(playerId, 0), game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index 25979eabb1..56844d6e8e 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -186,6 +186,7 @@ public class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Mahamoti Djinn", 52, Rarity.RARE, mage.cards.m.MahamotiDjinn.class)); cards.add(new SetCardInfo("Mana Matrix", 213, Rarity.RARE, mage.cards.m.ManaMatrix.class)); cards.add(new SetCardInfo("Mana Vault", 214, Rarity.RARE, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Martyr's Cry", 19, Rarity.RARE, mage.cards.m.MartyrsCry.class)); cards.add(new SetCardInfo("Martyrs of Korlis", 20, Rarity.UNCOMMON, mage.cards.m.MartyrsOfKorlis.class)); cards.add(new SetCardInfo("Maze of Ith", 246, Rarity.RARE, mage.cards.m.MazeOfIth.class)); cards.add(new SetCardInfo("Mightstone", 215, Rarity.COMMON, mage.cards.m.Mightstone.class)); diff --git a/Mage.Sets/src/mage/sets/TheDark.java b/Mage.Sets/src/mage/sets/TheDark.java index bacad0e06f..8f077c9ab8 100644 --- a/Mage.Sets/src/mage/sets/TheDark.java +++ b/Mage.Sets/src/mage/sets/TheDark.java @@ -105,6 +105,7 @@ public class TheDark extends ExpansionSet { cards.add(new SetCardInfo("Marsh Gas", 10, Rarity.COMMON, mage.cards.m.MarshGas.class)); cards.add(new SetCardInfo("Marsh Goblins", 118, Rarity.COMMON, mage.cards.m.MarshGoblins.class)); cards.add(new SetCardInfo("Marsh Viper", 44, Rarity.COMMON, mage.cards.m.MarshViper.class)); + cards.add(new SetCardInfo("Martyr's Cry", 85, Rarity.RARE, mage.cards.m.MartyrsCry.class)); cards.add(new SetCardInfo("Maze of Ith", 114, Rarity.UNCOMMON, mage.cards.m.MazeOfIth.class)); cards.add(new SetCardInfo("Merfolk Assassin", 31, Rarity.UNCOMMON, mage.cards.m.MerfolkAssassin.class)); cards.add(new SetCardInfo("Mind Bomb", 32, Rarity.RARE, mage.cards.m.MindBomb.class)); From 93c878c0d8911250b9956e9b103bffb8bfc87c92 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 17 Oct 2017 15:48:29 -0400 Subject: [PATCH 133/164] Implemented Krovikan Horror --- .../src/mage/cards/k/KrovikanHorror.java | 114 ++++++++++++++++++ Mage.Sets/src/mage/sets/Alliances.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 116 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KrovikanHorror.java diff --git a/Mage.Sets/src/mage/cards/k/KrovikanHorror.java b/Mage.Sets/src/mage/cards/k/KrovikanHorror.java new file mode 100644 index 0000000000..4b37bb97c6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KrovikanHorror.java @@ -0,0 +1,114 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class KrovikanHorror extends CardImpl { + + public KrovikanHorror(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HORROR); + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of the end step, if Krovikan Horror is in your graveyard with a creature card directly above it, you may return Krovikan Horror to your hand. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), + TargetController.ANY, KrovikanHorrorCondition.instance, true + )); + + // {1}, Sacrifice a creature: Krovikan Horror deals 1 damage to target creature or player. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new GenericManaCost(1)); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent())); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public KrovikanHorror(final KrovikanHorror card) { + super(card); + } + + @Override + public KrovikanHorror copy() { + return new KrovikanHorror(this); + } +} + +enum KrovikanHorrorCondition implements Condition { + + instance; + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + boolean nextCard = false; + for (Card card : controller.getGraveyard().getCards(game)) { + if (nextCard) { + return card.isCreature(); + } + if (card.getId().equals(source.getSourceId())) { + nextCard = true; + } + } + } + return false; + } + + @Override + public String toString() { + return "{this} is in your graveyard with a creature card directly above it"; + } +} diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 6144a6e8bb..4147a07003 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -104,6 +104,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Keeper of Tresserhorn", 14, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 184, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); + cards.add(new SetCardInfo("Krovikan Horror", 15, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); cards.add(new SetCardInfo("Krovikan Plague", 16, Rarity.UNCOMMON, mage.cards.k.KrovikanPlague.class)); cards.add(new SetCardInfo("Lake of the Dead", 185, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); cards.add(new SetCardInfo("Library of Lat-Nam", 47, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 2b276c52b3..054b8bbb59 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -169,6 +169,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Kjeldoran Outpost", 233, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); cards.add(new SetCardInfo("Knight of Stromgald", 99, Rarity.UNCOMMON, mage.cards.k.KnightOfStromgald.class)); cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class)); + cards.add(new SetCardInfo("Krovikan Horror", 101, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); cards.add(new SetCardInfo("Krovikan Sorcerer", 51, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class)); cards.add(new SetCardInfo("Leaping Lizard", 171, Rarity.COMMON, mage.cards.l.LeapingLizard.class)); cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, LimDulsHighGuard.class)); From 36523d541540fff6947381442b10bae999b9c49a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 10:40:21 -0400 Subject: [PATCH 134/164] text fix --- Mage.Sets/src/mage/cards/g/GlenElendraPranksters.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GlenElendraPranksters.java b/Mage.Sets/src/mage/cards/g/GlenElendraPranksters.java index 3a12d76299..0409f1141d 100644 --- a/Mage.Sets/src/mage/cards/g/GlenElendraPranksters.java +++ b/Mage.Sets/src/mage/cards/g/GlenElendraPranksters.java @@ -48,7 +48,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class GlenElendraPranksters extends CardImpl { public GlenElendraPranksters(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.FAERIE); this.subtype.add(SubType.WIZARD); this.power = new MageInt(1); @@ -57,8 +57,10 @@ public class GlenElendraPranksters extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Whenever you cast a spell during an opponent's turn, you may return target creature you control to its owner's hand. - Ability ability = new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility(new ReturnToHandTargetEffect(), true), OnOpponentsTurnCondition.instance, - "Whenever you cast a spell during an opponent's turn, you may have target creature get -1/-1 until end of turn."); + Ability ability = new ConditionalTriggeredAbility( + new SpellCastControllerTriggeredAbility(new ReturnToHandTargetEffect(), true), OnOpponentsTurnCondition.instance, + "Whenever you cast a spell during an opponent's turn, you may return target creature you control to its owner's hand." + ); ability.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(ability); } From 74642115397ef452128a7f15b8c16df952c98f23 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 14:26:35 -0400 Subject: [PATCH 135/164] Implemented Shyft --- Mage.Sets/src/mage/cards/s/Shyft.java | 96 +++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 98 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Shyft.java diff --git a/Mage.Sets/src/mage/cards/s/Shyft.java b/Mage.Sets/src/mage/cards/s/Shyft.java new file mode 100644 index 0000000000..ea0e075411 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Shyft.java @@ -0,0 +1,96 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BecomesColorOrColorsTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.game.Game; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class Shyft extends CardImpl { + + public Shyft(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, you may have Shyft become the color or colors of your choice. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ShyftEffect(), TargetController.YOU, true)); + } + + public Shyft(final Shyft card) { + super(card); + } + + @Override + public Shyft copy() { + return new Shyft(this); + } +} + +class ShyftEffect extends OneShotEffect { + + ShyftEffect() { + super(Outcome.Benefit); + this.staticText = "have {this} become the color or colors of your choice."; + } + + ShyftEffect(final ShyftEffect effect) { + super(effect); + } + + @Override + public ShyftEffect copy() { + return new ShyftEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Effect effect = new BecomesColorOrColorsTargetEffect(Duration.Custom); + effect.setTargetPointer(new FixedTarget(source.getSourceId(), source.getSourceObjectZoneChangeCounter())); + return effect.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 2f96059ac1..9e89571fa8 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -272,6 +272,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Shambling Strider", 151, Rarity.COMMON, mage.cards.s.ShamblingStrider.class)); cards.add(new SetCardInfo("Shatter", 216, Rarity.COMMON, mage.cards.s.Shatter.class)); cards.add(new SetCardInfo("Shield of the Ages", 310, Rarity.UNCOMMON, mage.cards.s.ShieldOfTheAges.class)); + cards.add(new SetCardInfo("Shyft", 96, Rarity.RARE, mage.cards.s.Shyft.class)); cards.add(new SetCardInfo("Sibilant Spirit", 97, Rarity.RARE, mage.cards.s.SibilantSpirit.class)); cards.add(new SetCardInfo("Silver Erne", 98, Rarity.UNCOMMON, mage.cards.s.SilverErne.class)); cards.add(new SetCardInfo("Skeleton Ship", 379, Rarity.RARE, mage.cards.s.SkeletonShip.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 054b8bbb59..768db1c538 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -216,6 +216,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Sea Drake", 64, Rarity.RARE, mage.cards.s.SeaDrake.class)); cards.add(new SetCardInfo("Sea Spirit", 65, Rarity.UNCOMMON, mage.cards.s.SeaSpirit.class)); cards.add(new SetCardInfo("Shrink", 175, Rarity.COMMON, mage.cards.s.Shrink.class)); + cards.add(new SetCardInfo("Shyft", 66, Rarity.COMMON, mage.cards.s.Shyft.class)); cards.add(new SetCardInfo("Sibilant Spirit", 67, Rarity.RARE, mage.cards.s.SibilantSpirit.class)); cards.add(new SetCardInfo("Skeleton Ship", 197, Rarity.RARE, mage.cards.s.SkeletonShip.class)); cards.add(new SetCardInfo("Skull Catapult", 219, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); From 08bdfcc961ab7f63db8f75bd6802863dece6f454 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 14:45:30 -0400 Subject: [PATCH 136/164] updated some text and implementations --- .../src/mage/cards/g/GiantTrapDoorSpider.java | 32 +------- Mage.Sets/src/mage/cards/h/HuntingKavu.java | 32 +------- Mage.Sets/src/mage/cards/s/SoulSnare.java | 28 +------ .../common/FilterCreatureAttackingYou.java | 82 +++++++++++++++++++ 4 files changed, 90 insertions(+), 84 deletions(-) create mode 100644 Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java diff --git a/Mage.Sets/src/mage/cards/g/GiantTrapDoorSpider.java b/Mage.Sets/src/mage/cards/g/GiantTrapDoorSpider.java index 6c0ed14e87..968ce61a78 100644 --- a/Mage.Sets/src/mage/cards/g/GiantTrapDoorSpider.java +++ b/Mage.Sets/src/mage/cards/g/GiantTrapDoorSpider.java @@ -33,7 +33,6 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileSourceEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.FlyingAbility; @@ -42,11 +41,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.target.common.FilterCreatureAttackingYou; import mage.target.common.TargetCreaturePermanent; /** @@ -55,7 +52,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class GiantTrapDoorSpider extends CardImpl { - private static final HuntingKavuFilter filter = new HuntingKavuFilter(); + private static final FilterCreatureAttackingYou filter = new FilterCreatureAttackingYou("creature without flying that's attacking you"); static { filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); @@ -71,7 +68,7 @@ public class GiantTrapDoorSpider extends CardImpl { // {1}{R}{G}, {tap}: Exile Giant Trap Door Spider and target creature without flying that's attacking you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(), new ManaCostsImpl("{1}{R}{G}")); ability.addCost(new TapSourceCost()); - ability.addEffect(new ExileTargetEffect()); + ability.addEffect(new ExileTargetEffect().setText("and target creature without flying that's attacking you")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } @@ -85,26 +82,3 @@ public class GiantTrapDoorSpider extends CardImpl { return new GiantTrapDoorSpider(this); } } - -class HuntingKavuFilter extends FilterAttackingCreature { - - public HuntingKavuFilter() { - super("creature without flying that's attacking you"); - } - - public HuntingKavuFilter(final HuntingKavuFilter filter) { - super(filter); - } - - @Override - public HuntingKavuFilter copy() { - return new HuntingKavuFilter(this); - } - - @Override - public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - return super.match(permanent, sourceId, playerId, game) - && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking - && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HuntingKavu.java b/Mage.Sets/src/mage/cards/h/HuntingKavu.java index c6541cbc9d..c4444d1338 100644 --- a/Mage.Sets/src/mage/cards/h/HuntingKavu.java +++ b/Mage.Sets/src/mage/cards/h/HuntingKavu.java @@ -33,7 +33,6 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileSourceEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.FlyingAbility; @@ -42,11 +41,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.target.common.FilterCreatureAttackingYou; import mage.target.common.TargetCreaturePermanent; /** @@ -55,7 +52,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class HuntingKavu extends CardImpl { - private static final HuntingKavuFilter filter = new HuntingKavuFilter(); + private static final FilterCreatureAttackingYou filter = new FilterCreatureAttackingYou("creature without flying that's attacking you"); static { filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); @@ -71,7 +68,7 @@ public class HuntingKavu extends CardImpl { // {1}{R}{G}, {tap}: Exile Hunting Kavu and target creature without flying that's attacking you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(), new ManaCostsImpl("{1}{R}{G}")); ability.addCost(new TapSourceCost()); - ability.addEffect(new ExileTargetEffect()); + ability.addEffect(new ExileTargetEffect().setText("nd target creature without flying that's attacking you")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } @@ -85,26 +82,3 @@ public class HuntingKavu extends CardImpl { return new HuntingKavu(this); } } - -class HuntingKavuFilter extends FilterAttackingCreature { - - public HuntingKavuFilter() { - super("creature without flying that's attacking you"); - } - - public HuntingKavuFilter(final HuntingKavuFilter filter) { - super(filter); - } - - @Override - public HuntingKavuFilter copy() { - return new HuntingKavuFilter(this); - } - - @Override - public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - return super.match(permanent, sourceId, playerId, game) - && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking - && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SoulSnare.java b/Mage.Sets/src/mage/cards/s/SoulSnare.java index e68f31e8fa..984e93f80a 100644 --- a/Mage.Sets/src/mage/cards/s/SoulSnare.java +++ b/Mage.Sets/src/mage/cards/s/SoulSnare.java @@ -37,9 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.target.common.FilterCreatureAttackingYou; import mage.target.common.TargetCreaturePermanent; /** @@ -56,7 +54,7 @@ public class SoulSnare extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new ManaCostsImpl("{W}")); ability.addCost(new SacrificeSourceCost()); - ability.addTarget(new TargetCreaturePermanent(new SoulSnareFilter())); + ability.addTarget(new TargetCreaturePermanent(new FilterCreatureAttackingYou(true))); this.addAbility(ability); } @@ -69,25 +67,3 @@ public class SoulSnare extends CardImpl { return new SoulSnare(this); } } - -class SoulSnareFilter extends FilterAttackingCreature { - - public SoulSnareFilter() { - super("creature that's attacking you or a planeswalker you control"); - } - - public SoulSnareFilter(final SoulSnareFilter filter) { - super(filter); - } - - @Override - public SoulSnareFilter copy() { - return new SoulSnareFilter(this); - } - - @Override - public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - return super.match(permanent, sourceId, playerId, game) - && playerId.equals(game.getCombat().getDefendingPlayerId(permanent.getId(), game)); - } -} diff --git a/Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java b/Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java new file mode 100644 index 0000000000..308089f38a --- /dev/null +++ b/Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java @@ -0,0 +1,82 @@ +/* +* 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.target.common; + +import java.util.UUID; +import mage.filter.common.FilterAttackingCreature; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class FilterCreatureAttackingYou extends FilterAttackingCreature { + + private final boolean orWalker; + + public FilterCreatureAttackingYou() { + this(false); + } + + public FilterCreatureAttackingYou(boolean orWalker) { + this("creature that's attacking you" + (orWalker ? "or a planeswalker you control" : ""), orWalker); + } + + public FilterCreatureAttackingYou(String name) { + this(name, false); + } + + public FilterCreatureAttackingYou(String name, boolean orWalker) { + super(name); + this.orWalker = orWalker; + } + + public FilterCreatureAttackingYou(final FilterCreatureAttackingYou filter) { + super(filter); + this.orWalker = filter.orWalker; + } + + @Override + public FilterCreatureAttackingYou copy() { + return new FilterCreatureAttackingYou(this); + } + + @Override + public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { + if (orWalker) { + return super.match(permanent, sourceId, playerId, game) + && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking + && playerId.equals(game.getCombat().getDefendingPlayerId(permanent.getId(), game)); + } else { + return super.match(permanent, sourceId, playerId, game) + && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking + && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); + } + } +} From 8cbffc89d8e336a15e680e9e252a938502d18c39 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 14:53:30 -0400 Subject: [PATCH 137/164] updated some text and implementations --- .../{target => filter}/common/FilterCreatureAttackingYou.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Mage/src/main/java/mage/{target => filter}/common/FilterCreatureAttackingYou.java (100%) diff --git a/Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java b/Mage/src/main/java/mage/filter/common/FilterCreatureAttackingYou.java similarity index 100% rename from Mage/src/main/java/mage/target/common/FilterCreatureAttackingYou.java rename to Mage/src/main/java/mage/filter/common/FilterCreatureAttackingYou.java From bcc319a636b094ee982a2a554aadb23bf429aa5c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 14:57:17 -0400 Subject: [PATCH 138/164] Implemented Ice Floe --- Mage.Sets/src/mage/cards/i/IceFloe.java | 82 +++++++++++++++++++ Mage.Sets/src/mage/sets/FifthEdition.java | 1 + Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 4 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IceFloe.java diff --git a/Mage.Sets/src/mage/cards/i/IceFloe.java b/Mage.Sets/src/mage/cards/i/IceFloe.java new file mode 100644 index 0000000000..974b442ac5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IceFloe.java @@ -0,0 +1,82 @@ +/* + * 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.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SkipUntapOptionalAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DontUntapAsLongAsSourceTappedEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.common.FilterCreatureAttackingYou; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class IceFloe extends CardImpl { + + private static final FilterCreatureAttackingYou filter = new FilterCreatureAttackingYou("creature without flying that's attacking you"); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + + public IceFloe(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // You may choose not to untap Ice Floe during your untap step. + this.addAbility(new SkipUntapOptionalAbility()); + + // {tap}: Tap target creature without flying that's attacking you. It doesn't untap during its controller's untap step for as long as Ice Floe remains tapped. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + ability.addEffect(new DontUntapAsLongAsSourceTappedEffect()); + this.addAbility(ability); + } + + public IceFloe(final IceFloe card) { + super(card); + } + + @Override + public IceFloe copy() { + return new IceFloe(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index c04cc7dae8..58f3d4975c 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -217,6 +217,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Icatian Scout", 313, Rarity.COMMON, IcatianScout.class)); cards.add(new SetCardInfo("Icatian Store", 423, Rarity.RARE, mage.cards.i.IcatianStore.class)); cards.add(new SetCardInfo("Icatian Town", 314, Rarity.RARE, mage.cards.i.IcatianTown.class)); + cards.add(new SetCardInfo("Ice Floe", 424, Rarity.UNCOMMON, mage.cards.i.IceFloe.class)); cards.add(new SetCardInfo("Imposing Visage", 241, Rarity.COMMON, mage.cards.i.ImposingVisage.class)); cards.add(new SetCardInfo("Incinerate", 242, Rarity.COMMON, mage.cards.i.Incinerate.class)); cards.add(new SetCardInfo("Inferno", 243, Rarity.RARE, mage.cards.i.Inferno.class)); diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 9e89571fa8..ae41e2d5b8 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -167,6 +167,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Hyalopterous Lemure", 21, Rarity.UNCOMMON, mage.cards.h.HyalopterousLemure.class)); cards.add(new SetCardInfo("Hydroblast", 72, Rarity.COMMON, mage.cards.h.Hydroblast.class)); cards.add(new SetCardInfo("Hymn of Rebirth", 373, Rarity.UNCOMMON, mage.cards.h.HymnOfRebirth.class)); + cards.add(new SetCardInfo("Ice Floe", 333, Rarity.UNCOMMON, mage.cards.i.IceFloe.class)); cards.add(new SetCardInfo("Iceberg", 73, Rarity.UNCOMMON, mage.cards.i.Iceberg.class)); cards.add(new SetCardInfo("Icequake", 22, Rarity.UNCOMMON, mage.cards.i.Icequake.class)); cards.add(new SetCardInfo("Icy Manipulator", 297, Rarity.UNCOMMON, mage.cards.i.IcyManipulator.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 768db1c538..f93ecf7023 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -148,6 +148,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Helm of Obedience", 210, Rarity.RARE, mage.cards.h.HelmOfObedience.class)); cards.add(new SetCardInfo("Icatian Javelineers", 15, Rarity.COMMON, IcatianJavelineers.class)); cards.add(new SetCardInfo("Icatian Scout", 17, Rarity.COMMON, IcatianScout.class)); + cards.add(new SetCardInfo("Ice Floe", 232, Rarity.UNCOMMON, mage.cards.i.IceFloe.class)); cards.add(new SetCardInfo("Iceberg", 49, Rarity.UNCOMMON, mage.cards.i.Iceberg.class)); cards.add(new SetCardInfo("Icequake", 94, Rarity.COMMON, mage.cards.i.Icequake.class)); cards.add(new SetCardInfo("Icy Prison", 50, Rarity.COMMON, mage.cards.i.IcyPrison.class)); From 53f77ac9cd3a99a4afc15d10ca5fb71283b6b5db Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 15:02:11 -0400 Subject: [PATCH 139/164] some fixes --- Mage.Sets/src/mage/cards/s/SnowFortress.java | 33 +++---------------- .../src/mage/cards/s/StalkingLeonin.java | 26 ++------------- 2 files changed, 6 insertions(+), 53 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SnowFortress.java b/Mage.Sets/src/mage/cards/s/SnowFortress.java index 7ec925286b..1d58404c88 100644 --- a/Mage.Sets/src/mage/cards/s/SnowFortress.java +++ b/Mage.Sets/src/mage/cards/s/SnowFortress.java @@ -42,12 +42,10 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.common.TargetCreatureOrPlayer; +import mage.target.common.FilterCreatureAttackingYou; +import mage.target.common.TargetCreaturePermanent; /** * @@ -55,7 +53,7 @@ import mage.target.common.TargetCreatureOrPlayer; */ public class SnowFortress extends CardImpl { - private static final SnowFortressFilter filter = new SnowFortressFilter(); + private static final FilterCreatureAttackingYou filter = new FilterCreatureAttackingYou("creature without flying that's attacking you"); static { filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); @@ -79,7 +77,7 @@ public class SnowFortress extends CardImpl { // {3}: Snow Fortress deals 1 damage to target creature without flying that's attacking you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new GenericManaCost(3)); - ability.addTarget(new TargetCreatureOrPlayer()); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } @@ -92,26 +90,3 @@ public class SnowFortress extends CardImpl { return new SnowFortress(this); } } - -class SnowFortressFilter extends FilterAttackingCreature { - - public SnowFortressFilter() { - super("creature without flying that's attacking you"); - } - - public SnowFortressFilter(final SnowFortressFilter filter) { - super(filter); - } - - @Override - public SnowFortressFilter copy() { - return new SnowFortressFilter(this); - } - - @Override - public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - return super.match(permanent, sourceId, playerId, game) - && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking - && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); - } -} diff --git a/Mage.Sets/src/mage/cards/s/StalkingLeonin.java b/Mage.Sets/src/mage/cards/s/StalkingLeonin.java index c917e94728..a181a42116 100644 --- a/Mage.Sets/src/mage/cards/s/StalkingLeonin.java +++ b/Mage.Sets/src/mage/cards/s/StalkingLeonin.java @@ -44,10 +44,10 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.common.FilterCreatureAttackingYou; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponent; import mage.util.CardUtil; @@ -72,7 +72,7 @@ public class StalkingLeonin extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new StalkingLeoninChooseOpponent(), false)); // Reveal the player you chose: Exile target creature that's attacking you if it's controlled by the chosen player. Activate this ability only once. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StalkingLeoninEffect(), new StalkingLeoninRevealOpponentCost()); - ability.addTarget(new TargetCreaturePermanent(new StalkingLeoninFilter())); + ability.addTarget(new TargetCreaturePermanent(new FilterCreatureAttackingYou())); this.addAbility(ability); } @@ -217,25 +217,3 @@ class StalkingLeoninEffect extends OneShotEffect { return false; } } - -class StalkingLeoninFilter extends FilterAttackingCreature { - - public StalkingLeoninFilter() { - super("creature that's attacking you"); - } - - public StalkingLeoninFilter(final StalkingLeoninFilter filter) { - super(filter); - } - - @Override - public StalkingLeoninFilter copy() { - return new StalkingLeoninFilter(this); - } - - @Override - public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { - return super.match(permanent, sourceId, playerId, game) - && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); - } -} From 1b5c1cdb61dddbd1659a0340ad2ae58288f60700 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 15:19:07 -0400 Subject: [PATCH 140/164] Implemented Righteous War --- Mage.Sets/src/mage/cards/r/RighteousWar.java | 89 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Visions.java | 1 + 2 files changed, 90 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RighteousWar.java diff --git a/Mage.Sets/src/mage/cards/r/RighteousWar.java b/Mage.Sets/src/mage/cards/r/RighteousWar.java new file mode 100644 index 0000000000..b64fd49875 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RighteousWar.java @@ -0,0 +1,89 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author TheElk801 + */ +public class RighteousWar extends CardImpl { + + private static final FilterCreaturePermanent whiteFilter = new FilterCreaturePermanent("white creatures you control"); + private static final FilterCreaturePermanent blackFilter = new FilterCreaturePermanent("black creatures you control"); + + static { + whiteFilter.add(new ColorPredicate(ObjectColor.WHITE)); + blackFilter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public RighteousWar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{B}"); + + // White creatures you control have protection from black. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilityControlledEffect( + ProtectionAbility.from(ObjectColor.BLACK), + Duration.WhileOnBattlefield, + whiteFilter + ) + )); + + // Black creatures you control have protection from white. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilityControlledEffect( + ProtectionAbility.from(ObjectColor.WHITE), + Duration.WhileOnBattlefield, + blackFilter + ) + )); + } + + public RighteousWar(final RighteousWar card) { + super(card); + } + + @Override + public RighteousWar copy() { + return new RighteousWar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 06465ba0d5..60a268a46f 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -147,6 +147,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Resistance Fighter", 118, Rarity.COMMON, mage.cards.r.ResistanceFighter.class)); cards.add(new SetCardInfo("Retribution of the Meek", 119, Rarity.RARE, mage.cards.r.RetributionOfTheMeek.class)); cards.add(new SetCardInfo("Righteous Aura", 120, Rarity.COMMON, mage.cards.r.RighteousAura.class)); + cards.add(new SetCardInfo("Righteous War", 134, Rarity.RARE, mage.cards.r.RighteousWar.class)); cards.add(new SetCardInfo("River Boa", 68, Rarity.COMMON, mage.cards.r.RiverBoa.class)); cards.add(new SetCardInfo("Rock Slide", 92, Rarity.COMMON, mage.cards.r.RockSlide.class)); cards.add(new SetCardInfo("Rowen", 69, Rarity.RARE, mage.cards.r.Rowen.class)); From 197aa33fc05fc59cf34dfe0fea8132debfbcb6d0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 18 Oct 2017 21:33:05 +0200 Subject: [PATCH 141/164] Removed Target Source redundancy --- Mage.Sets/src/mage/cards/o/OpalEyeKondasYojimbo.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OpalEyeKondasYojimbo.java b/Mage.Sets/src/mage/cards/o/OpalEyeKondasYojimbo.java index 23b9527c5f..971e38c0d8 100644 --- a/Mage.Sets/src/mage/cards/o/OpalEyeKondasYojimbo.java +++ b/Mage.Sets/src/mage/cards/o/OpalEyeKondasYojimbo.java @@ -69,9 +69,7 @@ public class OpalEyeKondasYojimbo extends CardImpl { this.addAbility(new BushidoAbility(1)); // {T}: The next time a source of your choice would deal damage this turn, that damage is dealt to Opal-Eye, Konda's Yojimbo instead. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new OpalEyeKondasYojimboRedirectionEffect(), new TapSourceCost()); - ability.addTarget(new TargetSource()); - this.addAbility(ability); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new OpalEyeKondasYojimboRedirectionEffect(), new TapSourceCost())); // {1}{W}: Prevent the next 1 damage that would be dealt to Opal-Eye this turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToSourceEffect(Duration.EndOfTurn, 1), new ManaCostsImpl("{1}{W}"))); From c5399460b9e874d4b736e452f49c32f4557ba8f2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 18 Oct 2017 22:12:27 +0200 Subject: [PATCH 142/164] Rewrote Choose Blockers effect to ContinuousRuleModifyingEffectImpl --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index cfbf33e8c1..2b07a65470 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -34,7 +34,6 @@ import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.condition.common.BeforeAttackersAreDeclaredCondition; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; @@ -238,10 +237,10 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } } -class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { // TODO: replace this with ContinuousRuleModifyingEffectImpl +class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { // TODO: reverse the resolution order in case of effect multiples public MasterWarcraftChooseBlockersEffect() { - super(Duration.EndOfTurn, Outcome.Benefit); + super(Duration.EndOfTurn, Outcome.Benefit, false, false); staticText = "You choose which creatures block this turn and how those creatures block"; } @@ -266,20 +265,11 @@ class MasterWarcraftChooseBlockersEffect extends ReplacementEffectImpl { // TODO @Override public boolean applies(GameEvent event, Ability source, Game game) { - Player blockController = game.getPlayer(source.getControllerId()); - if (blockController != null) { - return true; - } - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player blockController = game.getPlayer(source.getControllerId()); if (blockController != null) { game.getCombat().selectBlockers(blockController, game); return true; } return false; - } + } } From 5d126afc18df13a24d023292d238433f38c90311 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 18 Oct 2017 22:18:32 +0200 Subject: [PATCH 143/164] Rewrote Choose Blockers effect to ContinuousRuleModifyingEffectImpl --- .../src/mage/cards/b/BrutalHordechief.java | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java index 3311459c09..ff4b4e3cfe 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java +++ b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.combat.BlocksIfAbleAllEffect; @@ -71,7 +71,7 @@ public class BrutalHordechief extends CardImpl { // {3}{R/W}{R/W}: Creatures your opponents control block this turn if able, and you choose how those creatures block. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BlocksIfAbleAllEffect(filter, Duration.EndOfTurn), new ManaCostsImpl("{3}{R/W}{R/W}")); - ability.addEffect(new BrutalHordechiefReplacementEffect()); + ability.addEffect(new BrutalHordechiefChooseBlockersEffect()); this.addAbility(ability); } @@ -123,20 +123,20 @@ class BrutalHordechiefTriggeredAbility extends TriggeredAbilityImpl { } } -class BrutalHordechiefReplacementEffect extends ReplacementEffectImpl { +class BrutalHordechiefChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { // TODO: reverse the resolution order in case of effect multiples - public BrutalHordechiefReplacementEffect() { - super(Duration.EndOfCombat, Outcome.Benefit); - staticText = ", and you choose how those creatures block"; + public BrutalHordechiefChooseBlockersEffect() { + super(Duration.EndOfTurn, Outcome.Benefit, false, false); + staticText = "You choose which creatures block this turn and how those creatures block"; } - public BrutalHordechiefReplacementEffect(final BrutalHordechiefReplacementEffect effect) { + public BrutalHordechiefChooseBlockersEffect(final BrutalHordechiefChooseBlockersEffect effect) { super(effect); } @Override - public BrutalHordechiefReplacementEffect copy() { - return new BrutalHordechiefReplacementEffect(this); + public BrutalHordechiefChooseBlockersEffect copy() { + return new BrutalHordechiefChooseBlockersEffect(this); } @Override @@ -153,18 +153,10 @@ class BrutalHordechiefReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Player blockController = game.getPlayer(source.getControllerId()); if (blockController != null) { - return true; - } - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player blockController = game.getPlayer(source.getControllerId()); - if (blockController != null) { + game.informPlayers(source.getSourceObject(game).getIdName() + " applies"); game.getCombat().selectBlockers(blockController, game); return true; } return false; - } + } } From 12d74214ed9e6b89a52f7d040d0a70bbb9ecd896 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 18 Oct 2017 22:20:21 +0200 Subject: [PATCH 144/164] Some stray text fixes --- Mage.Sets/src/mage/cards/b/BrutalHordechief.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java index ff4b4e3cfe..108280010f 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java +++ b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java @@ -127,7 +127,7 @@ class BrutalHordechiefChooseBlockersEffect extends ContinuousRuleModifyingEffect public BrutalHordechiefChooseBlockersEffect() { super(Duration.EndOfTurn, Outcome.Benefit, false, false); - staticText = "You choose which creatures block this turn and how those creatures block"; + staticText = ", and you choose how those creatures block"; } public BrutalHordechiefChooseBlockersEffect(final BrutalHordechiefChooseBlockersEffect effect) { @@ -153,7 +153,6 @@ class BrutalHordechiefChooseBlockersEffect extends ContinuousRuleModifyingEffect public boolean applies(GameEvent event, Ability source, Game game) { Player blockController = game.getPlayer(source.getControllerId()); if (blockController != null) { - game.informPlayers(source.getSourceObject(game).getIdName() + " applies"); game.getCombat().selectBlockers(blockController, game); return true; } From bc6104d201a5402a3e9acaf2e1b8c6fe3d5a136d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 18 Oct 2017 22:36:11 -0400 Subject: [PATCH 145/164] Implemented Suleiman's Legacy --- .../src/mage/cards/s/SuleimansLegacy.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Visions.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SuleimansLegacy.java diff --git a/Mage.Sets/src/mage/cards/s/SuleimansLegacy.java b/Mage.Sets/src/mage/cards/s/SuleimansLegacy.java new file mode 100644 index 0000000000..5bb92a92e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SuleimansLegacy.java @@ -0,0 +1,81 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SetTargetPointer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class SuleimansLegacy extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("Djinns and Efreets"); + + static { + filter.add(Predicates.or( + new SubtypePredicate(SubType.DJINN), + new SubtypePredicate(SubType.EFREET) + )); + } + + public SuleimansLegacy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{W}"); + + // When Suleiman's Legacy enters the battlefield, destroy all Djinns and Efreets. They can't be regenerated. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter, true))); + + // Whenever a Djinn or Efreet enters the battlefield, destroy it. It can't be regenerated. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DestroyTargetEffect(true), filter, false, SetTargetPointer.PERMANENT, + "Whenever a Djinn or Efreet enters the battlefield, destroy it. It can't be regenerated." + )); + } + + public SuleimansLegacy(final SuleimansLegacy card) { + super(card); + } + + @Override + public SuleimansLegacy copy() { + return new SuleimansLegacy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 60a268a46f..7f7d25ed48 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -162,6 +162,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Spitting Drake", 95, Rarity.UNCOMMON, mage.cards.s.SpittingDrake.class)); cards.add(new SetCardInfo("Squandered Resources", 137, Rarity.RARE, mage.cards.s.SquanderedResources.class)); cards.add(new SetCardInfo("Stampeding Wildebeests", 71, Rarity.UNCOMMON, mage.cards.s.StampedingWildebeests.class)); + cards.add(new SetCardInfo("Suleiman's Legacy", 138, Rarity.RARE, mage.cards.s.SuleimansLegacy.class)); cards.add(new SetCardInfo("Summer Bloom", 72, Rarity.UNCOMMON, mage.cards.s.SummerBloom.class)); cards.add(new SetCardInfo("Sun Clasp", 121, Rarity.COMMON, mage.cards.s.SunClasp.class)); cards.add(new SetCardInfo("Suq'Ata Assassin", 19, Rarity.UNCOMMON, mage.cards.s.SuqAtaAssassin.class)); From 668a93d681da4ad67138c41642eb3498bf6def5b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 19 Oct 2017 07:01:39 +0200 Subject: [PATCH 146/164] Improved targetting of MasterWarcraftAttackEffect --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 2b07a65470..d16000e64e 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -49,6 +49,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.targetpointer.FixedTarget; /** @@ -128,6 +129,11 @@ class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectI } class MasterWarcraftAttackEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"); + static { + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + } MasterWarcraftAttackEffect() { super(Outcome.Benefit); @@ -146,9 +152,8 @@ class MasterWarcraftAttackEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - // TODO: find a way to undo creature selection - Target target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"), true); - if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { + Target target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, true); + if (controller.chooseTarget(Outcome.Benefit, target, source, game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { // Choose creatures that will be attacking this combat @@ -237,7 +242,7 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } } -class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { // TODO: reverse the resolution order in case of effect multiples +class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { // TODO: fix sorting order in case of Master Warcraft multiples public MasterWarcraftChooseBlockersEffect() { super(Duration.EndOfTurn, Outcome.Benefit, false, false); From 1452e101288cc5004962043557f247d041d84e3d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 19 Oct 2017 07:34:46 -0400 Subject: [PATCH 147/164] Implemented Waylay --- Mage.Sets/src/mage/cards/w/Waylay.java | 103 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + .../game/permanent/token/WaylayToken.java | 48 ++++++++ 3 files changed, 152 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/Waylay.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/WaylayToken.java diff --git a/Mage.Sets/src/mage/cards/w/Waylay.java b/Mage.Sets/src/mage/cards/w/Waylay.java new file mode 100644 index 0000000000..795197e929 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/Waylay.java @@ -0,0 +1,103 @@ +/* + * 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.w; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextCleanupDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Token; +import mage.game.permanent.token.WaylayToken; +import mage.target.targetpointer.FixedTargets; + +/** + * + * @author TheElk801 + */ +public class Waylay extends CardImpl { + + public Waylay(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Create three 2/2 white Knight creature tokens. Exile them at the beginning of the next cleanup step. + this.getSpellAbility().addEffect(new WaylayEffect()); + } + + public Waylay(final Waylay card) { + super(card); + } + + @Override + public Waylay copy() { + return new Waylay(this); + } +} + +class WaylayEffect extends OneShotEffect { + + public WaylayEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Create three 2/2 white Knight creature tokens. Exile them at the beginning of the next cleanup step."; + } + + public WaylayEffect(final WaylayEffect effect) { + super(effect); + } + + @Override + public WaylayEffect copy() { + return new WaylayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Token token = new WaylayToken(); + token.putOntoBattlefield(3, game, source.getSourceId(), source.getControllerId()); + List toExile = new ArrayList<>(); + for (UUID tokenId : token.getLastAddedTokenIds()) { + Permanent tokenPermanent = game.getPermanent(tokenId); + if (tokenPermanent != null) { + toExile.add(tokenPermanent); + } + } + Effect effect = new ExileTargetEffect(); + effect.setTargetPointer(new FixedTargets(toExile, game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextCleanupDelayedTriggeredAbility(effect), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 3968d93c04..e6c428107e 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -362,6 +362,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Vug Lizard", 227, Rarity.UNCOMMON, mage.cards.v.VugLizard.class)); cards.add(new SetCardInfo("War Dance", 282, Rarity.UNCOMMON, mage.cards.w.WarDance.class)); cards.add(new SetCardInfo("Wall of Junk", 315, Rarity.UNCOMMON, mage.cards.w.WallOfJunk.class)); + cards.add(new SetCardInfo("Waylay", 56, Rarity.UNCOMMON, mage.cards.w.Waylay.class)); cards.add(new SetCardInfo("Western Paladin", 168, Rarity.RARE, mage.cards.w.WesternPaladin.class)); cards.add(new SetCardInfo("Whetstone", 316, Rarity.RARE, mage.cards.w.Whetstone.class)); cards.add(new SetCardInfo("Whirlwind", 283, Rarity.RARE, mage.cards.w.Whirlwind.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/WaylayToken.java b/Mage/src/main/java/mage/game/permanent/token/WaylayToken.java new file mode 100644 index 0000000000..47942f2c6a --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/WaylayToken.java @@ -0,0 +1,48 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com AS IS AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game.permanent.token; + +import mage.constants.CardType; +import mage.constants.SubType; +import mage.MageInt; + +/** + * + * @author spjspj + */ +public class WaylayToken extends Token { + + public WaylayToken() { + super("Knight", "2/2 white Knight creature token"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add(SubType.KNIGHT); + power = new MageInt(2); + toughness = new MageInt(2); + } +} From d52f46323b02716fbcaae0f474292bf947b1a716 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 19 Oct 2017 13:55:16 -0400 Subject: [PATCH 148/164] Updated Adam Styborski's Pauper Cube --- .../cubes/AdamStyborskisPauperCube.java | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java index ba99a83ba6..4ef11e8d50 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java @@ -35,9 +35,9 @@ import mage.game.draft.DraftCube; */ public class AdamStyborskisPauperCube extends DraftCube { -public AdamStyborskisPauperCube() { + public AdamStyborskisPauperCube() { super("Adam Styborkski's Pauper Cube"); // https://docs.google.com/spreadsheets/d/12iQhC4bHqFW7hEWxPBjyC8yBDehFZ0_4DkqzyA8EL3o/edit#gid=0 - // last updated with Amonkhet 6/12/17 + // last updated with Hour of Devastation, Iconic Masters and Ixalan 10/18/17 cubeCards.add(new CardIdentity("Act of Treason", "")); cubeCards.add(new CardIdentity("Adventuring Gear", "")); cubeCards.add(new CardIdentity("Aerie Ouphes", "")); @@ -45,6 +45,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Aethersnipe", "")); cubeCards.add(new CardIdentity("Agony Warp", "")); cubeCards.add(new CardIdentity("Aim High", "")); + cubeCards.add(new CardIdentity("Ambuscade", "")); cubeCards.add(new CardIdentity("Ambush Viper", "")); cubeCards.add(new CardIdentity("Angelic Purge", "")); cubeCards.add(new CardIdentity("Arachnus Web", "")); @@ -55,18 +56,18 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Ashes to Ashes", "")); cubeCards.add(new CardIdentity("Assault Zeppelid", "")); cubeCards.add(new CardIdentity("Attended Knight", "")); - cubeCards.add(new CardIdentity("Augur of Bolas", "")); cubeCards.add(new CardIdentity("Auger Spree", "")); + cubeCards.add(new CardIdentity("Augur of Bolas", "")); cubeCards.add(new CardIdentity("Aven Riftwatcher", "")); cubeCards.add(new CardIdentity("Aven Surveyor", "")); cubeCards.add(new CardIdentity("Azorius Guildgate", "")); cubeCards.add(new CardIdentity("Baleful Eidolon", "")); cubeCards.add(new CardIdentity("Barbed Lightning", "")); - cubeCards.add(new CardIdentity("Barren Moor", "")); cubeCards.add(new CardIdentity("Basking Rootwalla", "")); cubeCards.add(new CardIdentity("Battle Screech", "")); cubeCards.add(new CardIdentity("Beetleback Chief", "")); cubeCards.add(new CardIdentity("Beetleform Mage", "")); + cubeCards.add(new CardIdentity("Beneath the Sands", "")); cubeCards.add(new CardIdentity("Blastoderm", "")); cubeCards.add(new CardIdentity("Blazing Torch", "")); cubeCards.add(new CardIdentity("Blightning", "")); @@ -78,8 +79,9 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Bonesplitter", "")); cubeCards.add(new CardIdentity("Borderland Marauder", "")); cubeCards.add(new CardIdentity("Boros Guildgate", "")); - cubeCards.add(new CardIdentity("Borrowed Grave", "")); + cubeCards.add(new CardIdentity("Borrowed Grace", "")); cubeCards.add(new CardIdentity("Branching Bolt", "")); + cubeCards.add(new CardIdentity("Brazen Buccaneers", "")); cubeCards.add(new CardIdentity("Brazen Wolves", "")); cubeCards.add(new CardIdentity("Burning-Tree Emissary", "")); cubeCards.add(new CardIdentity("Burst Lightning", "")); @@ -97,6 +99,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Chain Lightning", "")); cubeCards.add(new CardIdentity("Chainer's Edict", "")); cubeCards.add(new CardIdentity("Chatter of the Squirrel", "")); + cubeCards.add(new CardIdentity("Cinder Barrens", "")); cubeCards.add(new CardIdentity("Citanul Woodreaders", "")); cubeCards.add(new CardIdentity("Claustrophobia", "")); cubeCards.add(new CardIdentity("Clay Statue", "")); @@ -108,15 +111,12 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Compulsive Research", "")); cubeCards.add(new CardIdentity("Compulsory Rest", "")); cubeCards.add(new CardIdentity("Consume Strength", "")); - cubeCards.add(new CardIdentity("Corpse Churn", "")); cubeCards.add(new CardIdentity("Corrupted Zendikon", "")); cubeCards.add(new CardIdentity("Counterspell", "")); cubeCards.add(new CardIdentity("Crippling Fatigue", "")); cubeCards.add(new CardIdentity("Crow of Dark Tidings", "")); cubeCards.add(new CardIdentity("Crypt Rats", "")); cubeCards.add(new CardIdentity("Crystallization", "")); - cubeCards.add(new CardIdentity("Cultist's Staff", "")); - cubeCards.add(new CardIdentity("Cultivate", "")); cubeCards.add(new CardIdentity("Cunning Strike", "")); cubeCards.add(new CardIdentity("Curse of Chains", "")); cubeCards.add(new CardIdentity("Custodi Squire", "")); @@ -124,9 +124,11 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Dauntless Cathar", "")); cubeCards.add(new CardIdentity("Dead Reveler", "")); cubeCards.add(new CardIdentity("Dead Weight", "")); + cubeCards.add(new CardIdentity("Deadeye Tormentor", "")); cubeCards.add(new CardIdentity("Death Denied", "")); cubeCards.add(new CardIdentity("Deep Analysis", "")); cubeCards.add(new CardIdentity("Deprive", "")); + cubeCards.add(new CardIdentity("Depths of Desire", "")); cubeCards.add(new CardIdentity("Deputy of Acquittals", "")); cubeCards.add(new CardIdentity("Desert", "")); cubeCards.add(new CardIdentity("Desperate Sentry", "")); @@ -134,6 +136,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Diabolic Edict", "")); cubeCards.add(new CardIdentity("Dimir Guildgate", "")); cubeCards.add(new CardIdentity("Dinrova Horror", "")); + cubeCards.add(new CardIdentity("Dire Fleet Hoarder", "")); cubeCards.add(new CardIdentity("Disfigure", "")); cubeCards.add(new CardIdentity("Dismal Backwater", "")); cubeCards.add(new CardIdentity("Disowned Ancestor", "")); @@ -152,20 +155,21 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Epic Confrontation", "")); cubeCards.add(new CardIdentity("Errant Ephemeron", "")); cubeCards.add(new CardIdentity("Esper Cormorants", "")); - cubeCards.add(new CardIdentity("Essence Scatter", "")); cubeCards.add(new CardIdentity("Evincar's Justice", "")); cubeCards.add(new CardIdentity("Evolving Wilds", "")); cubeCards.add(new CardIdentity("Faceless Butcher", "")); cubeCards.add(new CardIdentity("Faith's Fetters", "")); + cubeCards.add(new CardIdentity("Falkenrath Noble", "")); cubeCards.add(new CardIdentity("Feeling of Dread", "")); - cubeCards.add(new CardIdentity("Fertile Thicket", "")); cubeCards.add(new CardIdentity("Fervent Cathar", "")); cubeCards.add(new CardIdentity("Firebolt", "")); cubeCards.add(new CardIdentity("Fireslinger", "")); cubeCards.add(new CardIdentity("Flayer Husk", "")); cubeCards.add(new CardIdentity("Flurry of Horns", "")); cubeCards.add(new CardIdentity("Forked Bolt", "")); + cubeCards.add(new CardIdentity("Forsaken Sanctuary", "")); cubeCards.add(new CardIdentity("Fortify", "")); + cubeCards.add(new CardIdentity("Foul Orchard", "")); cubeCards.add(new CardIdentity("Frilled Oculus", "")); cubeCards.add(new CardIdentity("Frostburn Weird", "")); cubeCards.add(new CardIdentity("Gathan Raiders", "")); @@ -182,21 +186,22 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Gods Willing", "")); cubeCards.add(new CardIdentity("Goldmeadow Harrier", "")); cubeCards.add(new CardIdentity("Golgari Guildgate", "")); - cubeCards.add(new CardIdentity("Grapple with the Past", "")); cubeCards.add(new CardIdentity("Gravedigger", "")); cubeCards.add(new CardIdentity("Gray Merchant of Asphodel", "")); + cubeCards.add(new CardIdentity("Grazing Whiptail", "")); cubeCards.add(new CardIdentity("Grim Contest", "")); cubeCards.add(new CardIdentity("Grisly Salvage", "")); cubeCards.add(new CardIdentity("Grixis Slavedriver", "")); cubeCards.add(new CardIdentity("Gruul Guildgate", "")); cubeCards.add(new CardIdentity("Gryff Vanguard", "")); cubeCards.add(new CardIdentity("Guardian Automaton", "")); + cubeCards.add(new CardIdentity("Guardian Idol", "")); cubeCards.add(new CardIdentity("Guardian of the Guildpact", "")); cubeCards.add(new CardIdentity("Gurmag Angler", "")); - cubeCards.add(new CardIdentity("Halimar Depths", "")); cubeCards.add(new CardIdentity("Halimar Wavewatch", "")); cubeCards.add(new CardIdentity("Harrow", "")); cubeCards.add(new CardIdentity("Harsh Sustenance", "")); + cubeCards.add(new CardIdentity("Highland Lake", "")); cubeCards.add(new CardIdentity("Hissing Iguanar", "")); cubeCards.add(new CardIdentity("Hooting Mandrills", "")); cubeCards.add(new CardIdentity("Humble", "")); @@ -206,6 +211,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Insolent Neonate", "")); cubeCards.add(new CardIdentity("Into the Roil", "")); cubeCards.add(new CardIdentity("Isolation Zone", "")); + cubeCards.add(new CardIdentity("Ivy Elemental", "")); cubeCards.add(new CardIdentity("Izzet Chronarch", "")); cubeCards.add(new CardIdentity("Izzet Guildgate", "")); cubeCards.add(new CardIdentity("Jilt", "")); @@ -214,7 +220,6 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Kabuto Moth", "")); cubeCards.add(new CardIdentity("Keldon Marauders", "")); cubeCards.add(new CardIdentity("Kingpin's Pet", "")); - cubeCards.add(new CardIdentity("Kodama's Reach", "")); cubeCards.add(new CardIdentity("Kor Skyfisher", "")); cubeCards.add(new CardIdentity("Kozilek's Channeler", "")); cubeCards.add(new CardIdentity("Krenko's Command", "")); @@ -222,25 +227,24 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Kruin Striker", "")); cubeCards.add(new CardIdentity("Lash Out", "")); cubeCards.add(new CardIdentity("Last Gasp", "")); - cubeCards.add(new CardIdentity("Lawless Broker", "")); + cubeCards.add(new CardIdentity("Leave in the Dust", "")); cubeCards.add(new CardIdentity("Leonin Bola", "")); - cubeCards.add(new CardIdentity("Leonin Scimitar", "")); + cubeCards.add(new CardIdentity("Lifecraft Cavalry", "")); cubeCards.add(new CardIdentity("Lightning Bolt", "")); cubeCards.add(new CardIdentity("Liliana's Specter", "")); - cubeCards.add(new CardIdentity("Looming Spires", "")); cubeCards.add(new CardIdentity("Lotus Path Djinn", "")); cubeCards.add(new CardIdentity("Loyal Pegasus", "")); cubeCards.add(new CardIdentity("Lurking Automaton", "")); cubeCards.add(new CardIdentity("Magma Jet", "")); cubeCards.add(new CardIdentity("Makeshift Mauler", "")); + cubeCards.add(new CardIdentity("Man-o'-War", "")); cubeCards.add(new CardIdentity("Mana Leak", "")); cubeCards.add(new CardIdentity("Manticore of the Gauntlet", "")); - cubeCards.add(new CardIdentity("Man-o'-War", "")); cubeCards.add(new CardIdentity("Mardu Hordechief", "")); cubeCards.add(new CardIdentity("Mardu Skullhunter", "")); cubeCards.add(new CardIdentity("Maul Splicer", "")); - cubeCards.add(new CardIdentity("Maulfist Squad", "")); cubeCards.add(new CardIdentity("Maze of Ith", "")); + cubeCards.add(new CardIdentity("Meandering River", "")); cubeCards.add(new CardIdentity("Mental Note", "")); cubeCards.add(new CardIdentity("Midnight Scavengers", "")); cubeCards.add(new CardIdentity("Mind Stone", "")); @@ -249,6 +253,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Mishra's Factory", "")); cubeCards.add(new CardIdentity("Mist Raven", "")); cubeCards.add(new CardIdentity("Mistral Charger", "")); + cubeCards.add(new CardIdentity("Mobile Garrison", "")); cubeCards.add(new CardIdentity("Mogg Fanatic", "")); cubeCards.add(new CardIdentity("Mogg Flunkies", "")); cubeCards.add(new CardIdentity("Mogg War Marshal", "")); @@ -260,17 +265,17 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Narcolepsy", "")); cubeCards.add(new CardIdentity("Necromancer's Assistant", "")); cubeCards.add(new CardIdentity("Nessian Asp", "")); + cubeCards.add(new CardIdentity("Nest Robber", "")); cubeCards.add(new CardIdentity("Nezumi Cutthroat", "")); cubeCards.add(new CardIdentity("Night's Whisper", "")); cubeCards.add(new CardIdentity("Nightscape Familiar", "")); cubeCards.add(new CardIdentity("Ninja of the Deep Hours", "")); cubeCards.add(new CardIdentity("Oblivion Ring", "")); cubeCards.add(new CardIdentity("Oona's Grace", "")); - cubeCards.add(new CardIdentity("Orcish Oriflamme", "")); cubeCards.add(new CardIdentity("Orzhov Guildgate", "")); cubeCards.add(new CardIdentity("Otherworldly Journey", "")); cubeCards.add(new CardIdentity("Pacifism", "")); - cubeCards.add(new CardIdentity("Palace Sentinels", "")); + cubeCards.add(new CardIdentity("Paladin of the Bloodstained", "")); cubeCards.add(new CardIdentity("Peema Outrider", "")); cubeCards.add(new CardIdentity("Penumbra Spider", "")); cubeCards.add(new CardIdentity("Peregrine Drake", "")); @@ -287,7 +292,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Plated Geopede", "")); cubeCards.add(new CardIdentity("Plover Knights", "")); cubeCards.add(new CardIdentity("Porcelain Legionnaire", "")); - cubeCards.add(new CardIdentity("Pouncing Kavu", "")); + cubeCards.add(new CardIdentity("Pounce", "")); cubeCards.add(new CardIdentity("Predatory Nightstalker", "")); cubeCards.add(new CardIdentity("Preordain", "")); cubeCards.add(new CardIdentity("Prey Upon", "")); @@ -316,27 +321,27 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Renegade Freighter", "")); cubeCards.add(new CardIdentity("Rift Bolt", "")); cubeCards.add(new CardIdentity("Rishadan Airship", "")); - cubeCards.add(new CardIdentity("River Serpent", "")); cubeCards.add(new CardIdentity("Ronin Houndmaster", "")); cubeCards.add(new CardIdentity("Rugged Highlands", "")); cubeCards.add(new CardIdentity("Runed Servitor", "")); cubeCards.add(new CardIdentity("Rushing River", "")); + cubeCards.add(new CardIdentity("Sailor of Means", "")); cubeCards.add(new CardIdentity("Sakura-Tribe Elder", "")); cubeCards.add(new CardIdentity("Sandsteppe Outcast", "")); cubeCards.add(new CardIdentity("Sangrite Backlash", "")); cubeCards.add(new CardIdentity("Sarkhan's Rage", "")); cubeCards.add(new CardIdentity("Savage Punch", "")); - cubeCards.add(new CardIdentity("Savage Surge", "")); cubeCards.add(new CardIdentity("Scatter the Seeds", "")); - cubeCards.add(new CardIdentity("Scion of the Wild", "")); cubeCards.add(new CardIdentity("Scion Summoner", "")); + cubeCards.add(new CardIdentity("Scion of the Wild", "")); cubeCards.add(new CardIdentity("Scoured Barrens", "")); cubeCards.add(new CardIdentity("Scourge Devil", "")); cubeCards.add(new CardIdentity("Screeching Skaab", "")); cubeCards.add(new CardIdentity("Scuzzback Marauders", "")); + cubeCards.add(new CardIdentity("Search for Tomorrow", "")); cubeCards.add(new CardIdentity("Searing Blaze", "")); cubeCards.add(new CardIdentity("Seeker of Insight", "")); - cubeCards.add(new CardIdentity("Sejiri Steppe", "")); + cubeCards.add(new CardIdentity("Seeker of the Way", "")); cubeCards.add(new CardIdentity("Selesnya Guildgate", "")); cubeCards.add(new CardIdentity("Sentinel Spider", "")); cubeCards.add(new CardIdentity("Separatist Voidmage", "")); @@ -349,7 +354,6 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Sigil Blessing", "")); cubeCards.add(new CardIdentity("Silent Departure", "")); cubeCards.add(new CardIdentity("Simic Guildgate", "")); - cubeCards.add(new CardIdentity("Skinthinner", "")); cubeCards.add(new CardIdentity("Skirk Marauder", "")); cubeCards.add(new CardIdentity("Skyknight Legionnaire", "")); cubeCards.add(new CardIdentity("Slash Panther", "")); @@ -362,21 +366,21 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Spined Thopter", "")); cubeCards.add(new CardIdentity("Splatter Thug", "")); cubeCards.add(new CardIdentity("Staggershock", "")); - cubeCards.add(new CardIdentity("Stave Off", "")); + cubeCards.add(new CardIdentity("Star Compass", "")); cubeCards.add(new CardIdentity("Stitched Drake", "")); + cubeCards.add(new CardIdentity("Stone Quarry", "")); + cubeCards.add(new CardIdentity("Storm Fleet Pyromancer", "")); cubeCards.add(new CardIdentity("Stormfront Pegasus", "")); cubeCards.add(new CardIdentity("Stormscape Apprentice", "")); cubeCards.add(new CardIdentity("Strip Mine", "")); + cubeCards.add(new CardIdentity("Striped Riverwinder", "")); + cubeCards.add(new CardIdentity("Submerged Boneyard", "")); cubeCards.add(new CardIdentity("Sultai Scavenger", "")); cubeCards.add(new CardIdentity("Suppression Bonds", "")); - cubeCards.add(new CardIdentity("Swift Spinner", "")); cubeCards.add(new CardIdentity("Swiftwater Cliffs", "")); cubeCards.add(new CardIdentity("Sylvan Might", "")); cubeCards.add(new CardIdentity("Sylvok Lifestaff", "")); cubeCards.add(new CardIdentity("Tah-Crop Elite", "")); - cubeCards.add(new CardIdentity("Tajuru Pathwarden", "")); - cubeCards.add(new CardIdentity("Talruum Minotaur", "")); - cubeCards.add(new CardIdentity("Tandem Lookout", "")); cubeCards.add(new CardIdentity("Temporal Isolation", "")); cubeCards.add(new CardIdentity("Tenement Crasher", "")); cubeCards.add(new CardIdentity("Terminate", "")); @@ -387,25 +391,26 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Thornwood Falls", "")); cubeCards.add(new CardIdentity("Thought Scour", "")); cubeCards.add(new CardIdentity("Thraben Inspector", "")); + cubeCards.add(new CardIdentity("Thrill-Kill Assassin", "")); cubeCards.add(new CardIdentity("Thundering Giant", "")); cubeCards.add(new CardIdentity("Thundering Tanadon", "")); cubeCards.add(new CardIdentity("Thunderous Wrath", "")); + cubeCards.add(new CardIdentity("Timber Gorge", "")); cubeCards.add(new CardIdentity("Time to Feed", "")); cubeCards.add(new CardIdentity("Tithe Drinker", "")); cubeCards.add(new CardIdentity("Totem-Guide Hartebeest", "")); cubeCards.add(new CardIdentity("Tragic Slip", "")); cubeCards.add(new CardIdentity("Tranquil Cove", "")); + cubeCards.add(new CardIdentity("Tranquil Expanse", "")); cubeCards.add(new CardIdentity("Travel Preparations", "")); cubeCards.add(new CardIdentity("Treasure Cruise", "")); cubeCards.add(new CardIdentity("Triplicate Spirits", "")); - cubeCards.add(new CardIdentity("Tumble Magnet", "")); cubeCards.add(new CardIdentity("Typhoid Rats", "")); cubeCards.add(new CardIdentity("Ulamog's Crusher", "")); cubeCards.add(new CardIdentity("Ulvenwald Captive", "")); cubeCards.add(new CardIdentity("Undying Rage", "")); cubeCards.add(new CardIdentity("Unearth", "")); cubeCards.add(new CardIdentity("Unmake", "")); - cubeCards.add(new CardIdentity("Unnatural Aggression", "")); cubeCards.add(new CardIdentity("Vampire Interloper", "")); cubeCards.add(new CardIdentity("Vault Skirge", "")); cubeCards.add(new CardIdentity("Viashino Firstblade", "")); @@ -424,7 +429,6 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Wasteland Scorpion", "")); cubeCards.add(new CardIdentity("Wayfarer's Bauble", "")); cubeCards.add(new CardIdentity("Werebear", "")); - cubeCards.add(new CardIdentity("Whirlpool Whelm", "")); cubeCards.add(new CardIdentity("Whitemane Lion", "")); cubeCards.add(new CardIdentity("Wild Instincts", "")); cubeCards.add(new CardIdentity("Wild Mongrel", "")); @@ -435,6 +439,7 @@ public AdamStyborskisPauperCube() { cubeCards.add(new CardIdentity("Winds of Rebuke", "")); cubeCards.add(new CardIdentity("Winged Coatl", "")); cubeCards.add(new CardIdentity("Wojek Halberdiers", "")); + cubeCards.add(new CardIdentity("Woodland Stream", "")); cubeCards.add(new CardIdentity("Wrecking Ball", "")); cubeCards.add(new CardIdentity("Wretched Gryff", "")); cubeCards.add(new CardIdentity("Yavimaya Elder", "")); From 3558899033cf5c97f773b6f1b8fdc08fc7572742 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 20 Oct 2017 00:41:32 +0200 Subject: [PATCH 149/164] Major code revamp, created a new watcher --- .../src/mage/cards/m/MasterWarcraft.java | 175 ++++++++++-------- 1 file changed, 102 insertions(+), 73 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index d16000e64e..23c5a7a503 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -28,6 +28,7 @@ package mage.cards.m; import java.util.*; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; @@ -45,12 +46,15 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.game.stack.Spell; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.targetpointer.FixedTarget; +import mage.watchers.Watcher; /** * @@ -62,13 +66,18 @@ public class MasterWarcraft extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R/W}{R/W}"); // Cast Master Warcraft only before attackers are declared. - this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeAttackersAreDeclaredCondition.instance)); + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeAttackersAreDeclaredCondition.instance, "Cast Master Warcraft only before attackers are declared")); // You choose which creatures attack this turn. this.getSpellAbility().addEffect(new MasterWarcraftChooseAttackersEffect()); // You choose which creatures block this turn and how those creatures block. this.getSpellAbility().addEffect(new MasterWarcraftChooseBlockersEffect()); + + + // (only the last resolved Master Warcraft spell's effects apply) + this.getSpellAbility().addWatcher(new MasterWarcraftCastWatcher()); + this.getSpellAbility().addEffect(new MasterWarcraftCastWatcherIncrementEffect()); } public MasterWarcraft(final MasterWarcraft card) { @@ -83,6 +92,11 @@ public class MasterWarcraft extends CardImpl { class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"); + static { + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + } + public MasterWarcraftChooseAttackersEffect() { super(Duration.EndOfTurn, Outcome.Benefit, false, false); staticText = "You choose which creatures attack this turn"; @@ -109,61 +123,27 @@ class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectI @Override public boolean applies(GameEvent event, Ability source, Game game) { - Player chooser = game.getPlayer(source.getControllerId()); - Player attackingPlayer = game.getPlayer(game.getCombat().getAttackingPlayerId()); - if (chooser != null && attackingPlayer != null && !attackingPlayer.getAvailableAttackers(game).isEmpty()) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { - // Clears previous instances of "should attack" effects - // ("shouldn't attack" effects don't need cleaning because MasterWarcraftMustAttackRequirementEffect overrides them) - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(permanent, false, game).entrySet()) { - RequirementEffect effect = entry.getKey(); - if (effect instanceof MasterWarcraftMustAttackRequirementEffect) { - effect.discard(); - } - } - } - new MasterWarcraftAttackEffect().apply(game, source); // Master Warcraft imposes its effect right before the attackers being declared... + MasterWarcraftCastWatcher watcher = (MasterWarcraftCastWatcher) game.getState().getWatchers().get(MasterWarcraftCastWatcher.class.getSimpleName()); + watcher.decrement(); + if (watcher.copyCountApply > 0) { + game.informPlayers(source.getSourceObject(game).getIdName() + " didn't apply"); + return false; } - return false; // ...and then resumes the attack declaration for the active player as normal - } -} - -class MasterWarcraftAttackEffect extends OneShotEffect { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that will attack this combat (creatures not chosen won't attack this combat)"); - static { - filter.add(new ControllerPredicate(TargetController.ACTIVE)); - } - - MasterWarcraftAttackEffect() { - super(Outcome.Benefit); - } - - MasterWarcraftAttackEffect(final MasterWarcraftAttackEffect effect) { - super(effect); - } - - @Override - public MasterWarcraftAttackEffect copy() { - return new MasterWarcraftAttackEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { + watcher.copyCountApply = watcher.copyCount; Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { + Player attackingPlayer = game.getPlayer(game.getCombat().getAttackingPlayerId()); + if (controller != null && attackingPlayer != null && !attackingPlayer.getAvailableAttackers(game).isEmpty()) { Target target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, true); if (controller.chooseTarget(Outcome.Benefit, target, source, game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { // Choose creatures that will be attacking this combat if (target.getTargets().contains(permanent.getId())) { - RequirementEffect effect = new MasterWarcraftMustAttackRequirementEffect(); + RequirementEffect effect = new AttacksIfAbleTargetEffect(Duration.EndOfCombat); effect.setText(""); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); - // TODO: find a better way to report attackers to game log - // game.informPlayers(controller.getLogName() + " has decided that " + permanent.getLogName() + " should attack this combat if able"); + game.informPlayers(controller.getLogName() + " has decided that " + permanent.getLogName() + " attacks this combat if able"); // All other creatures can't attack } else { @@ -172,36 +152,10 @@ class MasterWarcraftAttackEffect extends OneShotEffect { effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); } - } - return true; } } - return false; - } -} - -class MasterWarcraftMustAttackRequirementEffect extends AttacksIfAbleTargetEffect { - - MasterWarcraftMustAttackRequirementEffect() { - super(Duration.EndOfCombat); - } - - MasterWarcraftMustAttackRequirementEffect(final MasterWarcraftMustAttackRequirementEffect effect) { - super(effect); - } - - @Override - public MasterWarcraftMustAttackRequirementEffect copy() { - return new MasterWarcraftMustAttackRequirementEffect(this); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (discarded) { - return false; - } - return this.getTargetPointer().getTargets(game, source).contains(permanent.getId()); + return false; // the attack declaration resumes for the active player as normal } } @@ -242,7 +196,7 @@ class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { } } -class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { // TODO: fix sorting order in case of Master Warcraft multiples +class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { public MasterWarcraftChooseBlockersEffect() { super(Duration.EndOfTurn, Outcome.Benefit, false, false); @@ -270,6 +224,13 @@ class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectIm @Override public boolean applies(GameEvent event, Ability source, Game game) { + MasterWarcraftCastWatcher watcher = (MasterWarcraftCastWatcher) game.getState().getWatchers().get(MasterWarcraftCastWatcher.class.getSimpleName()); + watcher.decrement(); + if (watcher.copyCountApply > 0) { + game.informPlayers(source.getSourceObject(game).getIdName() + " didn't apply"); + return false; + } + watcher.copyCountApply = watcher.copyCount; Player blockController = game.getPlayer(source.getControllerId()); if (blockController != null) { game.getCombat().selectBlockers(blockController, game); @@ -278,3 +239,71 @@ class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectIm return false; } } + +class MasterWarcraftCastWatcher extends Watcher { + + public int copyCount = 0; + public int copyCountApply = 0; + + public MasterWarcraftCastWatcher() { + super(MasterWarcraftCastWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public MasterWarcraftCastWatcher(final MasterWarcraftCastWatcher watcher) { + super(watcher); + this.copyCount = watcher.copyCount; + this.copyCountApply = watcher.copyCountApply; + } + + @Override + public void reset() { + copyCount = 0; + copyCountApply = 0; + } + + @Override + public MasterWarcraftCastWatcher copy() { + return new MasterWarcraftCastWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + } + + public void increment() { + copyCount++; + copyCountApply = copyCount; + } + + public void decrement() { + if (copyCountApply > 0); { + copyCountApply--; + } + } +} + +class MasterWarcraftCastWatcherIncrementEffect extends OneShotEffect { + + MasterWarcraftCastWatcherIncrementEffect() { + super(Outcome.Neutral); + } + + MasterWarcraftCastWatcherIncrementEffect(final MasterWarcraftCastWatcherIncrementEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + MasterWarcraftCastWatcher watcher = (MasterWarcraftCastWatcher) game.getState().getWatchers().get(MasterWarcraftCastWatcher.class.getSimpleName()); + if (watcher != null) { + watcher.increment(); + return true; + } + return false; + } + + @Override + public MasterWarcraftCastWatcherIncrementEffect copy() { + return new MasterWarcraftCastWatcherIncrementEffect(this); + } +} From 483e6549f6bf8b6acd3bee1cc9f77a12405372bb Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 20 Oct 2017 02:01:09 +0200 Subject: [PATCH 150/164] Cleaned up code, fixed NullPointerException --- .../src/mage/cards/m/MasterWarcraft.java | 57 +++++-------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 23c5a7a503..7bac539453 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -39,6 +39,7 @@ import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect; +import mage.abilities.effects.common.combat.CantAttackTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -145,12 +146,21 @@ class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectI game.addEffect(effect, source); game.informPlayers(controller.getLogName() + " has decided that " + permanent.getLogName() + " attacks this combat if able"); - // All other creatures can't attack + // All other creatures can't attack (unless they must attack) } else { - RestrictionEffect effect = new MasterWarcraftCantAttackRestrictionEffect(); - effect.setText(""); - effect.setTargetPointer(new FixedTarget(permanent.getId())); - game.addEffect(effect, source); + boolean hasToAttack = false; + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(permanent, false, game).entrySet()) { + RequirementEffect effect2 = entry.getKey(); + if (effect2.mustAttack(game)) { + hasToAttack = true; + } + } + if (!hasToAttack) { + RestrictionEffect effect = new CantAttackTargetEffect(Duration.EndOfCombat); + effect.setText(""); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } } } } @@ -159,43 +169,6 @@ class MasterWarcraftChooseAttackersEffect extends ContinuousRuleModifyingEffectI } } -class MasterWarcraftCantAttackRestrictionEffect extends RestrictionEffect { - - MasterWarcraftCantAttackRestrictionEffect() { - super(Duration.EndOfCombat); - } - - MasterWarcraftCantAttackRestrictionEffect(final MasterWarcraftCantAttackRestrictionEffect effect) { - super(effect); - } - - @Override - public MasterWarcraftCantAttackRestrictionEffect copy() { - return new MasterWarcraftCantAttackRestrictionEffect(this); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - return this.getTargetPointer().getFirst(game, source).equals(permanent.getId()); - } - - @Override - public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) { - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, false, game).entrySet()) { - RequirementEffect effect = entry.getKey(); - if (effect.mustAttack(game)) { - return true; - } - } - return false; - } - - @Override - public String getText(Mode mode) { - return "Unless {this} must attack, {this} can't attack."; - } -} - class MasterWarcraftChooseBlockersEffect extends ContinuousRuleModifyingEffectImpl { public MasterWarcraftChooseBlockersEffect() { From b30335e3440ab26e4ffb725cb05b486a68efca73 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 20 Oct 2017 10:41:33 -0400 Subject: [PATCH 151/164] Implemented Momentum --- Mage.Sets/src/mage/cards/m/Momentum.java | 83 +++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 1 + .../main/java/mage/counters/CounterType.java | 1 + 3 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/Momentum.java diff --git a/Mage.Sets/src/mage/cards/m/Momentum.java b/Mage.Sets/src/mage/cards/m/Momentum.java new file mode 100644 index 0000000000..4d54ffdf88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Momentum.java @@ -0,0 +1,83 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class Momentum extends CardImpl { + + public Momentum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put a growth counter on Momentum. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.GROWTH.createInstance(), true), TargetController.YOU, true)); + + // Enchanted creature gets +1/+1 for each growth counter on Momentum. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(new CountersSourceCount(CounterType.GROWTH), new CountersSourceCount(CounterType.GROWTH)))); + } + + public Momentum(final Momentum card) { + super(card); + } + + @Override + public Momentum copy() { + return new Momentum(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 6a243198e5..acec22dff2 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -120,6 +120,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Mental Discipline", 37, Rarity.COMMON, mage.cards.m.MentalDiscipline.class)); cards.add(new SetCardInfo("Metalworker", 135, Rarity.RARE, mage.cards.m.Metalworker.class)); cards.add(new SetCardInfo("Metathran Soldier", 39, Rarity.COMMON, mage.cards.m.MetathranSoldier.class)); + cards.add(new SetCardInfo("Momentum", 113, Rarity.UNCOMMON, mage.cards.m.Momentum.class)); cards.add(new SetCardInfo("Multani's Decree", 114, Rarity.COMMON, mage.cards.m.MultanisDecree.class)); cards.add(new SetCardInfo("Opalescence", 13, Rarity.RARE, mage.cards.o.Opalescence.class)); cards.add(new SetCardInfo("Opposition", 40, Rarity.RARE, mage.cards.o.Opposition.class)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index d4b4464157..1b7862d19e 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -68,6 +68,7 @@ public enum CounterType { FURY("fury"), FUSE("fuse"), GOLD("gold"), + GROWTH("growth"), HATCHLING("hatchling"), HEALING("healing"), HOOFPRINT("hoofprint"), From 147bc413a78235cf6d464eef4a6dcc3e6ceb100f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 20 Oct 2017 10:57:41 -0400 Subject: [PATCH 152/164] Implemented Tribal Golem --- Mage.Sets/src/mage/cards/t/TribalGolem.java | 126 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TribalGolem.java diff --git a/Mage.Sets/src/mage/cards/t/TribalGolem.java b/Mage.Sets/src/mage/cards/t/TribalGolem.java new file mode 100644 index 0000000000..f29eb8611b --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TribalGolem.java @@ -0,0 +1,126 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class TribalGolem extends CardImpl { + + private static final FilterControlledPermanent filter1 = new FilterControlledPermanent("a Beast"); + private static final FilterControlledPermanent filter2 = new FilterControlledPermanent("a Goblin"); + private static final FilterControlledPermanent filter3 = new FilterControlledPermanent("a Soldier"); + private static final FilterControlledPermanent filter4 = new FilterControlledPermanent("a Wizard"); + private static final FilterControlledPermanent filter5 = new FilterControlledPermanent("a Zombie"); + + static { + filter1.add(new SubtypePredicate(SubType.BEAST)); + filter2.add(new SubtypePredicate(SubType.GOBLIN)); + filter3.add(new SubtypePredicate(SubType.SOLDIER)); + filter4.add(new SubtypePredicate(SubType.WIZARD)); + filter5.add(new SubtypePredicate(SubType.ZOMBIE)); + } + + public TribalGolem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); + + this.subtype.add(SubType.GOLEM); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Tribal Golem has trample as long as you control a Beast, haste as long as you control a Goblin, first strike as long as you control a Soldier, flying as long as you control a Wizard, and "{B}: Regenerate Tribal Golem" as long as you control a Zombie. + Effect effect1 = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(TrampleAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter1), + "{this} has trample as long as you control a Beast," + ); + Effect effect2 = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(HasteAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter2), + "haste as long as you control a Goblin," + ); + Effect effect3 = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter3), + "first strike as long as you control a Soldier," + ); + Effect effect4 = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(FlyingAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter4), + "flying as long as you control a Wizard," + ); + Effect effect5 = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new RegenerateSourceEffect(), + new ManaCostsImpl("{B}") + )), + new PermanentsOnTheBattlefieldCondition(filter5), + "and \"{B}: Regenerate {this}\" as long as you control a Zombie" + ); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect1); + ability.addEffect(effect2); + ability.addEffect(effect3); + ability.addEffect(effect4); + ability.addEffect(effect5); + this.addAbility(ability); + } + + public TribalGolem(final TribalGolem card) { + super(card); + } + + @Override + public TribalGolem copy() { + return new TribalGolem(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index ae21f921fc..f8311aadc5 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -311,6 +311,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Trade Secrets", 118, Rarity.RARE, mage.cards.t.TradeSecrets.class)); cards.add(new SetCardInfo("Tranquil Thicket", 326, Rarity.COMMON, mage.cards.t.TranquilThicket.class)); cards.add(new SetCardInfo("Treespring Lorian", 293, Rarity.COMMON, mage.cards.t.TreespringLorian.class)); + cards.add(new SetCardInfo("Tribal Golem", 311, Rarity.RARE, mage.cards.t.TribalGolem.class)); cards.add(new SetCardInfo("Tribal Unity", 294, Rarity.UNCOMMON, mage.cards.t.TribalUnity.class)); cards.add(new SetCardInfo("Trickery Charm", 119, Rarity.COMMON, mage.cards.t.TrickeryCharm.class)); cards.add(new SetCardInfo("True Believer", 57, Rarity.RARE, mage.cards.t.TrueBeliever.class)); From d90e2804b73a46a6fd961b9218e5b15ba293362e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 21 Oct 2017 08:19:27 -0400 Subject: [PATCH 153/164] fixed Skulduggery and Consume Strength affecting creatures which leave and re-enter the battlefield on the same turn. --- .../src/mage/cards/c/ConsumeStrength.java | 28 +++++++++++-------- Mage.Sets/src/mage/cards/s/Skulduggery.java | 21 ++++++++------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ConsumeStrength.java b/Mage.Sets/src/mage/cards/c/ConsumeStrength.java index 1bf9ca987f..15654f0fce 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumeStrength.java +++ b/Mage.Sets/src/mage/cards/c/ConsumeStrength.java @@ -29,7 +29,9 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -38,6 +40,7 @@ import mage.filter.predicate.mageobject.AnotherTargetPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -46,17 +49,16 @@ import mage.target.common.TargetCreaturePermanent; public class ConsumeStrength extends CardImpl { public ConsumeStrength(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{B}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}{G}"); // Target creature gets +2/+2 until end of turn. Another target creature gets -2/-2 until end of turn. this.getSpellAbility().addEffect(new ConsumeStrengthEffect()); - + FilterCreaturePermanent filter1 = new FilterCreaturePermanent("creature to get +2/+2"); TargetCreaturePermanent target1 = new TargetCreaturePermanent(filter1); target1.setTargetTag(1); this.getSpellAbility().addTarget(target1); - + FilterCreaturePermanent filter2 = new FilterCreaturePermanent("another creature to get -2/-2"); filter2.add(new AnotherTargetPredicate(2)); TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter2); @@ -74,10 +76,10 @@ public class ConsumeStrength extends CardImpl { } } -class ConsumeStrengthEffect extends ContinuousEffectImpl { +class ConsumeStrengthEffect extends OneShotEffect { public ConsumeStrengthEffect() { - super(Duration.EndOfTurn, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature); + super(Outcome.BoostCreature); this.staticText = "Target creature gets +2/+2 until end of turn. Another target creature gets -2/-2 until end of turn"; } @@ -94,14 +96,16 @@ class ConsumeStrengthEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { - permanent.addPower(2); - permanent.addToughness(2); + ContinuousEffect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); if (permanent != null) { - permanent.addPower(-2); - permanent.addToughness(-2); + ContinuousEffect effect = new BoostTargetEffect(-2, -2, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/Skulduggery.java b/Mage.Sets/src/mage/cards/s/Skulduggery.java index 7690f8944c..b3d4dbf328 100644 --- a/Mage.Sets/src/mage/cards/s/Skulduggery.java +++ b/Mage.Sets/src/mage/cards/s/Skulduggery.java @@ -29,14 +29,14 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Layer; import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -44,6 +44,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -76,10 +77,10 @@ public class Skulduggery extends CardImpl { } } -class SkulduggeryEffect extends ContinuousEffectImpl { +class SkulduggeryEffect extends OneShotEffect { public SkulduggeryEffect() { - super(Duration.EndOfTurn, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature); + super(Outcome.BoostCreature); this.staticText = "Until end of turn, target creature you control gets +1/+1 and target creature an opponent controls gets -1/-1"; } @@ -96,13 +97,15 @@ class SkulduggeryEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { - permanent.addPower(1); - permanent.addToughness(1); + ContinuousEffect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); if (permanent != null) { - permanent.addPower(-1); - permanent.addToughness(-1); + ContinuousEffect effect = new BoostTargetEffect(-1, -1, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } return true; } From 5033e27b0b167edf08dfdb22b1f7c7defd7448cb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 21 Oct 2017 10:52:59 -0400 Subject: [PATCH 154/164] Implemented Melting --- .../mage/cards/l/LeylineOfSingularity.java | 31 ++---- Mage.Sets/src/mage/cards/m/Melting.java | 100 ++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + 3 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/Melting.java diff --git a/Mage.Sets/src/mage/cards/l/LeylineOfSingularity.java b/Mage.Sets/src/mage/cards/l/LeylineOfSingularity.java index 91c380d368..4c30b1554f 100644 --- a/Mage.Sets/src/mage/cards/l/LeylineOfSingularity.java +++ b/Mage.Sets/src/mage/cards/l/LeylineOfSingularity.java @@ -36,9 +36,7 @@ import mage.abilities.keyword.LeylineAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.common.FilterNonlandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -48,21 +46,14 @@ import mage.game.permanent.Permanent; */ public class LeylineOfSingularity extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("nonland permanents"); - - static { - filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); - } - public LeylineOfSingularity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); + // If Leyline of Singularity is in your opening hand, you may begin the game with it on the battlefield. this.addAbility(LeylineAbility.getInstance()); // All nonland permanents are legendary. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetSupertypeAllEffect(Duration.WhileOnBattlefield, filter))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetSupertypeAllEffect())); } public LeylineOfSingularity(final LeylineOfSingularity card) { @@ -75,19 +66,16 @@ public class LeylineOfSingularity extends CardImpl { } } - class SetSupertypeAllEffect extends ContinuousEffectImpl { - private final FilterPermanent filter; + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent(); - public SetSupertypeAllEffect(Duration duration, FilterPermanent filter) { - super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); - this.filter = filter; + public SetSupertypeAllEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); } public SetSupertypeAllEffect(final SetSupertypeAllEffect effect) { super(effect); - this.filter = effect.filter; } @Override @@ -97,9 +85,8 @@ class SetSupertypeAllEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - permanent.addSuperType(SuperType.LEGENDARY); - + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + permanent.addSuperType(SuperType.LEGENDARY); } return true; } diff --git a/Mage.Sets/src/mage/cards/m/Melting.java b/Mage.Sets/src/mage/cards/m/Melting.java new file mode 100644 index 0000000000..c10d6610fa --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Melting.java @@ -0,0 +1,100 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class Melting extends CardImpl { + + public Melting(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + // All lands are no longer snow. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MeltingEffect())); + } + + public Melting(final Melting card) { + super(card); + } + + @Override + public Melting copy() { + return new Melting(this); + } +} + +class MeltingEffect extends ContinuousEffectImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent(); + + public MeltingEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); + } + + public MeltingEffect(final MeltingEffect effect) { + super(effect); + } + + @Override + public MeltingEffect copy() { + return new MeltingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + permanent.getSuperType().remove(SuperType.SNOW); + } + return true; + } + + @Override + public String getText(Mode mode) { + return "All lands are no longer snow"; + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index ae41e2d5b8..8db2063fca 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -212,6 +212,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Magus of the Unseen", 82, Rarity.RARE, mage.cards.m.MagusOfTheUnseen.class)); cards.add(new SetCardInfo("Malachite Talisman", 303, Rarity.UNCOMMON, mage.cards.m.MalachiteTalisman.class)); cards.add(new SetCardInfo("Marton Stromgald", 199, Rarity.RARE, mage.cards.m.MartonStromgald.class)); + cards.add(new SetCardInfo("Melting", 201, Rarity.UNCOMMON, mage.cards.m.Melting.class)); cards.add(new SetCardInfo("Merieke Ri Berit", 375, Rarity.RARE, mage.cards.m.MeriekeRiBerit.class)); cards.add(new SetCardInfo("Mesmeric Trance", 83, Rarity.RARE, mage.cards.m.MesmericTrance.class)); cards.add(new SetCardInfo("Meteor Shower", 202, Rarity.COMMON, mage.cards.m.MeteorShower.class)); From 8d390a475d50a5fd25b48fed0dff071da82811a9 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:34:54 +0200 Subject: [PATCH 155/164] Miniscule fix --- Mage.Sets/src/mage/cards/m/MasterWarcraft.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java index 7bac539453..94c9c56589 100644 --- a/Mage.Sets/src/mage/cards/m/MasterWarcraft.java +++ b/Mage.Sets/src/mage/cards/m/MasterWarcraft.java @@ -249,7 +249,7 @@ class MasterWarcraftCastWatcher extends Watcher { } public void decrement() { - if (copyCountApply > 0); { + if (copyCountApply > 0) { copyCountApply--; } } From a41d67600727af22da1c4fb10c36001f7b60feea Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:37:21 +0200 Subject: [PATCH 156/164] Implemented Dazzling Beauty --- .../src/mage/cards/d/DazzlingBeauty.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DazzlingBeauty.java diff --git a/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java b/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java new file mode 100644 index 0000000000..02cbf8dcfd --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java @@ -0,0 +1,118 @@ +/* + * 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.d; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.BlockedPredicate; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 & L_J + */ +public class DazzlingBeauty extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("unblocked attacking creature"); + + static { + filter.add(new AttackingPredicate()); + filter.add(Predicates.not(new BlockedPredicate())); + } + + public DazzlingBeauty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Cast Dazzling Beauty only during the declare blockers step. + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, PhaseStep.DECLARE_BLOCKERS, null, "Cast Dazzling Beauty only during the declare blockers step")); + + // Target unblocked attacking creature becomes blocked. + this.getSpellAbility().addEffect(new DazzlingBeautyEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + + // Draw a card at the beginning of the next turn's upkeep. + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); + } + + public DazzlingBeauty(final DazzlingBeauty card) { + super(card); + } + + @Override + public DazzlingBeauty copy() { + return new DazzlingBeauty(this); + } +} + +class DazzlingBeautyEffect extends OneShotEffect { + + public DazzlingBeautyEffect() { + super(Outcome.Benefit); + this.staticText = "Target unblocked attacking creature becomes blocked"; + } + + public DazzlingBeautyEffect(final DazzlingBeautyEffect effect) { + super(effect); + } + + @Override + public DazzlingBeautyEffect copy() { + return new DazzlingBeautyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (controller != null && permanent != null) { + CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId()); + if (combatGroup != null) { + combatGroup.setBlocked(true); + return true; + } + } + return false; + } +} From 9140cf92cbd6baa9317a62084953405a93d96f90 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:39:49 +0200 Subject: [PATCH 157/164] Implemented Forcemage Advocate --- .../src/mage/cards/f/ForcemageAdvocate.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/ForcemageAdvocate.java diff --git a/Mage.Sets/src/mage/cards/f/ForcemageAdvocate.java b/Mage.Sets/src/mage/cards/f/ForcemageAdvocate.java new file mode 100644 index 0000000000..71579beb72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/ForcemageAdvocate.java @@ -0,0 +1,86 @@ +/* + * 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.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInOpponentsGraveyard; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author L_J + */ +public class ForcemageAdvocate extends CardImpl { + + public ForcemageAdvocate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.subtype.add(SubType.CENTAUR); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // {tap}: Return target card from an opponent's graveyard to his or her hand. Put a +1/+1 counter on target creature. + Effect effect = new ReturnFromGraveyardToHandTargetEffect(); + effect.setText("Return target card from an opponent's graveyard to his or her hand"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + + effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setText("Put a +1/+1 counter on target creature"); + effect.setTargetPointer(new SecondTargetPointer()); + ability.addEffect(effect); + ability.addTarget(new TargetCardInOpponentsGraveyard(1, 1, new FilterCard(), true)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public ForcemageAdvocate(final ForcemageAdvocate card) { + super(card); + } + + @Override + public ForcemageAdvocate copy() { + return new ForcemageAdvocate(this); + } +} From 23a7ea39f75ed845b500ede7fc7b8b854172819d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:40:44 +0200 Subject: [PATCH 158/164] Implemented Shieldmage Advocate --- .../src/mage/cards/s/ShieldmageAdvocate.java | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShieldmageAdvocate.java diff --git a/Mage.Sets/src/mage/cards/s/ShieldmageAdvocate.java b/Mage.Sets/src/mage/cards/s/ShieldmageAdvocate.java new file mode 100644 index 0000000000..15022713e9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShieldmageAdvocate.java @@ -0,0 +1,132 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.TargetSource; +import mage.target.common.TargetCardInOpponentsGraveyard; +import mage.target.common.TargetCreatureOrPlayer; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author L_J + */ +public class ShieldmageAdvocate extends CardImpl { + + public ShieldmageAdvocate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // {tap}: Return target card from an opponent's graveyard to his or her hand. Prevent all damage that would be dealt to target creature or player this turn by a source of your choice. + Effect effect = new ReturnFromGraveyardToHandTargetEffect(); + effect.setText("Return target card from an opponent's graveyard to his or her hand"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + + effect = new ShieldmageAdvocateEffect(); + effect.setTargetPointer(new SecondTargetPointer()); + ability.addEffect(effect); + ability.addTarget(new TargetCardInOpponentsGraveyard(1, 1, new FilterCard(), true)); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public ShieldmageAdvocate(final ShieldmageAdvocate card) { + super(card); + } + + @Override + public ShieldmageAdvocate copy() { + return new ShieldmageAdvocate(this); + } +} + +class ShieldmageAdvocateEffect extends PreventionEffectImpl { + + protected final TargetSource targetSource; + + public ShieldmageAdvocateEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, false); + staticText = "Prevent all damage that would be dealt to target creature or player this turn by a source of your choice"; + this.targetSource = new TargetSource(); + } + + public ShieldmageAdvocateEffect(final ShieldmageAdvocateEffect effect) { + super(effect); + this.targetSource = effect.targetSource.copy(); + } + + @Override + public ShieldmageAdvocateEffect copy() { + return new ShieldmageAdvocateEffect(this); + } + + @Override + public void init(Ability source, Game game) { + this.targetSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + preventDamageAction(event, source, game); + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + if (event.getTargetId().equals(targetPointer.getFirst(game, source)) && event.getSourceId().equals(targetSource.getFirstTarget())) { + return true; + } + } + return false; + } + +} From 50d4d31932f65c9272f8d914b2c8f47a810dcc7e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:42:15 +0200 Subject: [PATCH 159/164] Implemented Tourach's Gate --- Mage.Sets/src/mage/cards/t/TourachsGate.java | 164 +++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TourachsGate.java diff --git a/Mage.Sets/src/mage/cards/t/TourachsGate.java b/Mage.Sets/src/mage/cards/t/TourachsGate.java new file mode 100644 index 0000000000..f298c2a9ff --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TourachsGate.java @@ -0,0 +1,164 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.AttachedToMatchesFilterCondition; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapAttachedCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author L_J + */ +public class TourachsGate extends CardImpl { + + private static final FilterControlledPermanent filterLand = new FilterControlledPermanent("land you control"); + static { + filterLand.add(new CardTypePredicate(CardType.LAND)); + } + + private static final FilterPermanent filterUntapped = new FilterPermanent("enchanted land is untapped"); + static { + filterUntapped.add(Predicates.not(new TappedPredicate())); + } + + private static final FilterCreaturePermanent filterAttackingCreatures = new FilterCreaturePermanent("attacking creatures you control"); + static { + filterAttackingCreatures.add(new AttackingPredicate()); + filterAttackingCreatures.add(new ControllerPredicate(TargetController.YOU)); + } + + private static final FilterControlledCreaturePermanent filterThrull = new FilterControlledCreaturePermanent("a Thrull"); + static { + filterThrull.add(new SubtypePredicate(SubType.THRULL)); + } + + public TourachsGate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}"); + this.subtype.add(SubType.AURA); + + // Enchant land you control + TargetPermanent auraTarget = new TargetControlledPermanent(filterLand); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Sacrifice a Thrull: Put three time counters on Tourach's Gate. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.TIME.createInstance(3)), + new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterThrull, true)))); + + // At the beginning of your upkeep, remove a time counter from Tourach's Gate. If there are no time counters on Tourach's Gate, sacrifice it. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TourachsGateUpkeepEffect(), TargetController.YOU, false)); + + // Tap enchanted land: Attacking creatures you control get +2/-1 until end of turn. Activate this ability only if enchanted land is untapped. + Cost cost = new TapAttachedCost(); + cost.setText("Tap enchanted land"); + this.addAbility(new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(2, -1, Duration.EndOfTurn, filterAttackingCreatures, false), + cost, new AttachedToMatchesFilterCondition(filterUntapped))); + } + + public TourachsGate(final TourachsGate card) { + super(card); + } + + @Override + public TourachsGate copy() { + return new TourachsGate(this); + } +} + +class TourachsGateUpkeepEffect extends OneShotEffect { + + TourachsGateUpkeepEffect() { + super(Outcome.Sacrifice); + staticText = "remove a time counter from {this}. If there are no time counters on {this}, sacrifice it"; + } + + TourachsGateUpkeepEffect(final TourachsGateUpkeepEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + int amount = permanent.getCounters(game).getCount(CounterType.TIME); + if (amount > 0) { + permanent.removeCounters(CounterType.TIME.createInstance(), game); + } + // is supposed to function similar to Vanishing + amount = permanent.getCounters(game).getCount(CounterType.TIME); + if (amount == 0) { + permanent.sacrifice(source.getSourceId(), game); + } + return true; + } + return false; + } + + @Override + public TourachsGateUpkeepEffect copy() { + return new TourachsGateUpkeepEffect(this); + } +} From f322b792a0a50e8f945bb8e22f2538bdaef08e88 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:43:08 +0200 Subject: [PATCH 160/164] Implemented Veteran's Voice --- Mage.Sets/src/mage/cards/v/VeteransVoice.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VeteransVoice.java diff --git a/Mage.Sets/src/mage/cards/v/VeteransVoice.java b/Mage.Sets/src/mage/cards/v/VeteransVoice.java new file mode 100644 index 0000000000..880bc071ee --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeteransVoice.java @@ -0,0 +1,114 @@ +/* + * 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.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.AttachedToMatchesFilterCondition; +import mage.abilities.costs.common.TapAttachedCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author L_J + */ +public class VeteransVoice extends CardImpl { + + private static final FilterCreaturePermanent filterUntapped = new FilterCreaturePermanent("enchanted creature is untapped"); + + static { + filterUntapped.add(Predicates.not(new TappedPredicate())); + } + + public VeteransVoice(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + this.subtype.add(SubType.AURA); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Tap enchanted creature: Target creature other than the creature tapped this way gets +2/+1 until end of turn. Activate this ability only if enchanted creature is untapped. + FilterPermanent filterTarget = new FilterCreaturePermanent("creature other than the creature tapped this way"); + filterTarget.add(Predicates.not(new AttachmentByUUIDPredicate(this.getId()))); + Ability ability2 = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, + new BoostTargetEffect(2, 1, Duration.EndOfTurn), new TapAttachedCost(), new AttachedToMatchesFilterCondition(filterUntapped)); + ability2.addTarget(new TargetPermanent(filterTarget)); + this.addAbility(ability2); + } + + public VeteransVoice(final VeteransVoice card) { + super(card); + } + + @Override + public VeteransVoice copy() { + return new VeteransVoice(this); + } +} + +class AttachmentByUUIDPredicate implements Predicate { + + private final UUID id; + + public AttachmentByUUIDPredicate(UUID id) { + this.id = id; + } + + @Override + public boolean apply(Permanent input, Game game) { + return input.getAttachments().contains(id); + } + + @Override + public String toString() { + return "AttachmentUUID(" + id + ')'; + } +} From bd5f94cedcd53f9bcd13d728dafe65cebd1a568c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:44:30 +0200 Subject: [PATCH 161/164] Implemented Veteran's Voice --- Mage.Sets/src/mage/sets/Alliances.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 4147a07003..c60b00701c 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -104,7 +104,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Keeper of Tresserhorn", 14, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 184, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); - cards.add(new SetCardInfo("Krovikan Horror", 15, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); + cards.add(new SetCardInfo("Krovikan Horror", 15, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); cards.add(new SetCardInfo("Krovikan Plague", 16, Rarity.UNCOMMON, mage.cards.k.KrovikanPlague.class)); cards.add(new SetCardInfo("Lake of the Dead", 185, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); cards.add(new SetCardInfo("Library of Lat-Nam", 47, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); @@ -171,6 +171,8 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Varchild's Crusader", 120, Rarity.COMMON, mage.cards.v.VarchildsCrusader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Varchild's Crusader", 121, Rarity.COMMON, mage.cards.v.VarchildsCrusader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Varchild's War-Riders", 122, Rarity.RARE, mage.cards.v.VarchildsWarRiders.class)); + cards.add(new SetCardInfo("Veteran's Voice", 123, Rarity.COMMON, mage.cards.v.VeteransVoice.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Veteran's Voice", 124, Rarity.COMMON, mage.cards.v.VeteransVoice.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Viscerid Armor", 60, Rarity.COMMON, mage.cards.v.VisceridArmor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Viscerid Armor", 61, Rarity.COMMON, mage.cards.v.VisceridArmor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Viscerid Drone", 62, Rarity.UNCOMMON, mage.cards.v.VisceridDrone.class)); From 909968c262c506f44976d62d5ca260288a85bbb8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:45:33 +0200 Subject: [PATCH 162/164] Implemented Tourach's Gate --- Mage.Sets/src/mage/sets/FallenEmpires.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/FallenEmpires.java b/Mage.Sets/src/mage/sets/FallenEmpires.java index aa73229d50..e8b7e2d03f 100644 --- a/Mage.Sets/src/mage/sets/FallenEmpires.java +++ b/Mage.Sets/src/mage/sets/FallenEmpires.java @@ -237,6 +237,7 @@ public class FallenEmpires extends ExpansionSet { cards.add(new SetCardInfo("Thrull Retainer", 30, Rarity.UNCOMMON, mage.cards.t.ThrullRetainer.class)); cards.add(new SetCardInfo("Thrull Wizard", 31, Rarity.UNCOMMON, mage.cards.t.ThrullWizard.class)); cards.add(new SetCardInfo("Tidal Influence", 57, Rarity.UNCOMMON, mage.cards.t.TidalInfluence.class)); + cards.add(new SetCardInfo("Tourach's Gate", 33, Rarity.RARE, mage.cards.t.TourachsGate.class)); cards.add(new SetCardInfo("Vodalian Knights", 58, Rarity.RARE, mage.cards.v.VodalianKnights.class)); cards.add(new SetCardInfo("Vodalian Mage", 59, Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vodalian Mage", 60, Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS)); From 978b2fd5549cf5892b9d643d702c9e0cb48e67ca Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:46:41 +0200 Subject: [PATCH 163/164] Implemented two Advocates --- Mage.Sets/src/mage/sets/Judgment.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Judgment.java b/Mage.Sets/src/mage/sets/Judgment.java index 4f46a7b417..9007e49c9e 100644 --- a/Mage.Sets/src/mage/sets/Judgment.java +++ b/Mage.Sets/src/mage/sets/Judgment.java @@ -100,6 +100,7 @@ public class Judgment extends ExpansionSet { cards.add(new SetCardInfo("Flash of Insight", 40, Rarity.UNCOMMON, mage.cards.f.FlashOfInsight.class)); cards.add(new SetCardInfo("Fledgling Dragon", 90, Rarity.RARE, mage.cards.f.FledglingDragon.class)); cards.add(new SetCardInfo("Folk Medicine", 115, Rarity.COMMON, mage.cards.f.FolkMedicine.class)); + cards.add(new SetCardInfo("Forcemage Advocate", 116, Rarity.UNCOMMON, mage.cards.f.ForcemageAdvocate.class)); cards.add(new SetCardInfo("Funeral Pyre", 10, Rarity.COMMON, mage.cards.f.FuneralPyre.class)); cards.add(new SetCardInfo("Genesis", 117, Rarity.RARE, mage.cards.g.Genesis.class)); cards.add(new SetCardInfo("Giant Warthog", 118, Rarity.COMMON, mage.cards.g.GiantWarthog.class)); @@ -118,7 +119,7 @@ public class Judgment extends ExpansionSet { cards.add(new SetCardInfo("Krosan Reclamation", 122, Rarity.UNCOMMON, mage.cards.k.KrosanReclamation.class)); cards.add(new SetCardInfo("Krosan Verge", 141, Rarity.UNCOMMON, mage.cards.k.KrosanVerge.class)); cards.add(new SetCardInfo("Krosan Wayfarer", 123, Rarity.COMMON, mage.cards.k.KrosanWayfarer.class)); - cards.add(new SetCardInfo("Laquatus's Disdain", 44, Rarity.UNCOMMON, mage.cards.l.LaquatussDisdain.class)); + cards.add(new SetCardInfo("Laquatus's Disdain", 44, Rarity.UNCOMMON, mage.cards.l.LaquatussDisdain.class)); cards.add(new SetCardInfo("Lava Dart", 94, Rarity.COMMON, mage.cards.l.LavaDart.class)); cards.add(new SetCardInfo("Lead Astray", 14, Rarity.COMMON, mage.cards.l.LeadAstray.class)); cards.add(new SetCardInfo("Liberated Dwarf", 95, Rarity.COMMON, mage.cards.l.LiberatedDwarf.class)); @@ -147,6 +148,7 @@ public class Judgment extends ExpansionSet { cards.add(new SetCardInfo("Riftstone Portal", 143, Rarity.UNCOMMON, mage.cards.r.RiftstonePortal.class)); cards.add(new SetCardInfo("Scalpelexis", 50, Rarity.RARE, mage.cards.s.Scalpelexis.class)); cards.add(new SetCardInfo("Seedtime", 130, Rarity.RARE, mage.cards.s.Seedtime.class)); + cards.add(new SetCardInfo("Shieldmage Advocate", 22, Rarity.COMMON, mage.cards.s.ShieldmageAdvocate.class)); cards.add(new SetCardInfo("Silver Seraph", 23, Rarity.RARE, mage.cards.s.SilverSeraph.class)); cards.add(new SetCardInfo("Solitary Confinement", 24, Rarity.RARE, mage.cards.s.SolitaryConfinement.class)); cards.add(new SetCardInfo("Soulcatchers' Aerie", 25, Rarity.UNCOMMON, mage.cards.s.SoulcatchersAerie.class)); @@ -164,8 +166,8 @@ public class Judgment extends ExpansionSet { cards.add(new SetCardInfo("Test of Endurance", 29, Rarity.RARE, mage.cards.t.TestOfEndurance.class)); cards.add(new SetCardInfo("Thriss, Nantuko Primus", 134, Rarity.RARE, mage.cards.t.ThrissNantukoPrimus.class)); cards.add(new SetCardInfo("Toxic Stench", 74, Rarity.COMMON, mage.cards.t.ToxicStench.class)); - cards.add(new SetCardInfo("Treacherous Vampire", 75, Rarity.UNCOMMON, mage.cards.t.TreacherousVampire.class)); - cards.add(new SetCardInfo("Treacherous Werewolf", 76, Rarity.COMMON, mage.cards.t.TreacherousWerewolf.class)); + cards.add(new SetCardInfo("Treacherous Vampire", 75, Rarity.UNCOMMON, mage.cards.t.TreacherousVampire.class)); + cards.add(new SetCardInfo("Treacherous Werewolf", 76, Rarity.COMMON, mage.cards.t.TreacherousWerewolf.class)); cards.add(new SetCardInfo("Tunneler Wurm", 135, Rarity.UNCOMMON, mage.cards.t.TunnelerWurm.class)); cards.add(new SetCardInfo("Unquestioned Authority", 31, Rarity.UNCOMMON, mage.cards.u.UnquestionedAuthority.class)); cards.add(new SetCardInfo("Valor", 32, Rarity.UNCOMMON, mage.cards.v.Valor.class)); From ac19187a20b5c9522b0d5de655828b51007d54f8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 21 Oct 2017 18:47:28 +0200 Subject: [PATCH 164/164] Implemented Dazzling Beauty --- Mage.Sets/src/mage/sets/Mirage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index 2100e30fab..e16c401dca 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -105,6 +105,7 @@ public class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Daring Apprentice", 60, Rarity.RARE, mage.cards.d.DaringApprentice.class)); cards.add(new SetCardInfo("Dark Banishing", 13, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); cards.add(new SetCardInfo("Dark Ritual", 14, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Dazzling Beauty", 212, Rarity.COMMON, mage.cards.d.DazzlingBeauty.class)); cards.add(new SetCardInfo("Dirtwater Wraith", 15, Rarity.COMMON, mage.cards.d.DirtwaterWraith.class)); cards.add(new SetCardInfo("Disempower", 213, Rarity.COMMON, mage.cards.d.Disempower.class)); cards.add(new SetCardInfo("Disenchant", 214, Rarity.COMMON, mage.cards.d.Disenchant.class));