diff --git a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java index 778c6ae58c2..0190ec139bc 100644 --- a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java @@ -201,9 +201,12 @@ public class FeedbackPanel extends javax.swing.JPanel { } // Issue 256: Chat+Feedback panel: request focus prevents players from chatting - private void requestFocusIfPossible() { + // Issue #1054: XMage steals window focus whenever the screen updates + private void requestFocusIfPossible() { boolean requestFocusAllowed = true; - if (connectedChatPanel != null && connectedChatPanel.getTxtMessageInputComponent() != null) { + if (MageFrame.getInstance().getFocusOwner() == null) { + requestFocusAllowed = false; + } else if (connectedChatPanel != null && connectedChatPanel.getTxtMessageInputComponent() != null) { if (connectedChatPanel.getTxtMessageInputComponent().hasFocus()) { requestFocusAllowed = false; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index 007e208be20..0728084c111 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -80,6 +80,7 @@ public class MythicspoilerComSource implements CardImageSource { cardNameAliases.put("THS-purphorosemissary", "purphorossemissary"); cardNameAliases.put("THS-soldierofpantheon", "soldierofthepantheon"); cardNameAliases.put("THS-vulpinegolaith", "vulpinegoliath"); + cardNameAliases.put("ORI-kothopedhoarderofsouls", "kothophedsoulhoarder"); } private Map getSetLinks(String cardSet) { @@ -130,17 +131,17 @@ public class MythicspoilerComSource implements CardImageSource { if (cardNameAliases.containsKey(cardSet + "-" + cardName)) { cardName = cardNameAliases.get(cardSet + "-" + cardName); } - if (cardName.endsWith("1") || cardName.endsWith("2") || cardName.endsWith("3")|| cardName.endsWith("4")|| cardName.endsWith("5")) { - if (!cardName.startsWith("forest") && - !cardName.startsWith("swamp") && - !cardName.startsWith("mountain") && - !cardName.startsWith("island") && - !cardName.startsWith("plains")) { + if (cardName.endsWith("1") || cardName.endsWith("2") || cardName.endsWith("3") || cardName.endsWith("4") || cardName.endsWith("5")) { + if (!cardName.startsWith("forest") + && !cardName.startsWith("swamp") + && !cardName.startsWith("mountain") + && !cardName.startsWith("island") + && !cardName.startsWith("plains")) { cardName = cardName.substring(0, cardName.length() - 1); - } + } } setLinks.put(cardName, baseUrl + cardLink); - } + } } } @@ -149,7 +150,7 @@ public class MythicspoilerComSource implements CardImageSource { System.out.println("Exception when parsing the mythicspoiler page: " + ex.getMessage()); } return setLinks; - } + } @Override public String generateURL(CardDownloadData card) throws Exception { diff --git a/Mage.Common/src/mage/utils/MageVersion.java b/Mage.Common/src/mage/utils/MageVersion.java index 8ea13bc3cad..05b90a6e01d 100644 --- a/Mage.Common/src/mage/utils/MageVersion.java +++ b/Mage.Common/src/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 2; - public final static String MAGE_VERSION_MINOR_PATCH = "v0"; + public final static String MAGE_VERSION_MINOR_PATCH = "v1"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml index 01aa84df340..839ee4bfd6f 100644 --- a/Mage.Server.Console/pom.xml +++ b/Mage.Server.Console/pom.xml @@ -31,51 +31,4 @@ test - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-install-plugin - 2.5.2 - - - maven-resources-plugin - - UTF-8 - - - - maven-jar-plugin - - - ${manifest.file} - - true - mage.server.console.ConsoleFrame - - - - - - maven-assembly-plugin - - false - - src/main/assembly/distribution.xml - - - - - - mage-console - - - - src/main/resources/META-INF/MANIFEST.MF - diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 7b8b96edaeb..57c42140b9b 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -173,12 +173,11 @@ public class ComputerPlayer extends PlayerImpl implements Player { public ComputerPlayer(String name, RangeOfInfluence range) { super(name, range); - flagName = "computer"; human = false; userData = UserData.getDefaultUserDataView(); userData.setAvatarId(64); userData.setGroupId(UserGroup.COMPUTER.getGroupId()); - userData.setFlagName("Computer.png"); + userData.setFlagName("computer.png"); pickedCards = new ArrayList<>(); } diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml index 37d72390fb8..c18cbdeb3af 100644 --- a/Mage.Server/release/config/config.xml +++ b/Mage.Server/release/config/config.xml @@ -37,7 +37,7 @@ - + diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index 4d6368fae2e..c705ffd740a 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -181,6 +181,8 @@ public class Session { return 1018; case "Bandit": return 1020; + case "Wehk": + return 66; } return 51; } diff --git a/Mage.Sets/src/mage/sets/MagicOrigins.java b/Mage.Sets/src/mage/sets/MagicOrigins.java index cc4c9524148..d9d75e78dd0 100644 --- a/Mage.Sets/src/mage/sets/MagicOrigins.java +++ b/Mage.Sets/src/mage/sets/MagicOrigins.java @@ -51,11 +51,11 @@ public class MagicOrigins extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - /* There are 15 additional cards, numbered 270–284, that don't appear in Magic - 2015 booster packs. These are reprints from earlier sets that are present in - some supplemental products, including sample decks and the Deck Builder's Toolkit. - These additional cards have a Magic 2015 expansion symbol and are legal in all - formats in which Magic 2015 is legal. */ + /* There are additional cards, numbered 273–288, that don't appear in Magic + Origin booster packs. These are reprints from earlier sets that are present in + some supplemental products, including sample decks and the Deck Builder's Toolkit. + These additional cards have a Magic Origin expansion symbol and are legal in all + formats in which Magic Origins is legal. */ this.maxCardNumberInBooster = 272; } } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/FavorableWinds.java b/Mage.Sets/src/mage/sets/avacynrestored/FavorableWinds.java index 2efe567a05a..f7a00271332 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/FavorableWinds.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/FavorableWinds.java @@ -27,19 +27,18 @@ */ package mage.sets.avacynrestored; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; -import java.util.UUID; - /** * * @author noxx @@ -56,7 +55,6 @@ public class FavorableWinds extends CardImpl { super(ownerId, 51, "Favorable Winds", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); this.expansionSetCode = "AVR"; - // Creatures you control with flying get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, false))); } diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java index 6dcb76e201c..826408a71be 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java @@ -28,9 +28,6 @@ package mage.sets.betrayersofkamigawa; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -40,14 +37,16 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.OfferingAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterLandCard; import mage.game.Game; import mage.players.Player; +import mage.target.TargetCard; import mage.target.common.TargetCardInHand; - /** * @author LevelX2 */ @@ -70,7 +69,6 @@ public class PatronOfTheMoon extends CardImpl { // {1}: Put up to two land cards from your hand onto the battlefield tapped. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PatronOfTheMoonEffect(), new ManaCostsImpl("{1}")); - ability.addTarget(new TargetCardInHand(0,2, new FilterLandCard())); this.addAbility(ability); } @@ -86,6 +84,7 @@ public class PatronOfTheMoon extends CardImpl { } class PatronOfTheMoonEffect extends OneShotEffect { + PatronOfTheMoonEffect() { super(Outcome.PutLandInPlay); staticText = "Put up to two land cards from your hand onto the battlefield tapped"; @@ -99,7 +98,9 @@ class PatronOfTheMoonEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID cardId : targetPointer.getTargets(game, source)) { + TargetCard target = new TargetCardInHand(0, 2, new FilterLandCard("up to two land cards to put onto the battlefield tapped")); + controller.chooseTarget(outcome, controller.getHand(), target, source, game); + for (UUID cardId : target.getTargets()) { Card card = game.getCard(cardId); if (card != null) { controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), true); @@ -115,4 +116,4 @@ class PatronOfTheMoonEffect extends OneShotEffect { return new PatronOfTheMoonEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander2014/ContainmentPriest.java b/Mage.Sets/src/mage/sets/commander2014/ContainmentPriest.java index caff08b7404..12728e17d97 100644 --- a/Mage.Sets/src/mage/sets/commander2014/ContainmentPriest.java +++ b/Mage.Sets/src/mage/sets/commander2014/ContainmentPriest.java @@ -27,8 +27,6 @@ */ package mage.sets.commander2014; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -41,17 +39,12 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.WatcherScope; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; -import mage.game.stack.Spell; import mage.players.Player; -import mage.watchers.Watcher; +import mage.watchers.common.CreatureWasCastWatcher; /** * @@ -71,7 +64,7 @@ public class ContainmentPriest extends CardImpl { // Flash this.addAbility(FlashAbility.getInstance()); // If a nontoken creature would enter the battlefield and it wasn't cast, exile it instead. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ContainmentPriestReplacementEffect()), new CreatureCastWatcher()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ContainmentPriestReplacementEffect()), new CreatureWasCastWatcher()); } public ContainmentPriest(final ContainmentPriest card) { @@ -86,14 +79,8 @@ public class ContainmentPriest extends CardImpl { class ContainmentPriestReplacementEffect extends ReplacementEffectImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard(); - - static { - filter.add(Predicates.not(new TokenPredicate())); - } - public ContainmentPriestReplacementEffect() { - super(Duration.WhileOnBattlefield, Outcome.GainControl); + super(Duration.WhileOnBattlefield, Outcome.Exile); staticText = "If a nontoken creature would enter the battlefield and it wasn't cast, exile it instead"; } @@ -125,19 +112,18 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl { } return false; } - - @Override + + @Override public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; + return event.getType() == GameEvent.EventType.ZONE_CHANGE; // Token create the create Token event } - @Override public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { Card card = game.getCard(event.getTargetId()); if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly - CreatureCastWatcher watcher = (CreatureCastWatcher) game.getState().getWatchers().get("CreatureWasCast"); + CreatureWasCastWatcher watcher = (CreatureWasCastWatcher) game.getState().getWatchers().get("CreatureWasCast"); if (watcher != null && !watcher.wasCreatureCastThisTurn(event.getTargetId())) { return true; } @@ -146,51 +132,3 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl { return false; } } - -class CreatureCastWatcher extends Watcher { - - private final Set creaturesCasted = new HashSet<>(); - - public CreatureCastWatcher() { - super("CreatureWasCast", WatcherScope.GAME); - } - - public CreatureCastWatcher(final CreatureCastWatcher watcher) { - super(watcher); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.SPELL_CAST) { - Spell spell = (Spell) game.getObject(event.getTargetId()); - if (spell != null) { - Card card = game.getCard(spell.getSourceId()); - if (card != null && card.getCardType().contains(CardType.CREATURE)) { - creaturesCasted.add(card.getId()); - } - } - } - if (event.getType() == GameEvent.EventType.ZONE_CHANGE - && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { - Card card = game.getCard(event.getTargetId()); - if (card != null && card.getCardType().contains(CardType.CREATURE)) { - creaturesCasted.remove(card.getId()); - } - } - } - - public boolean wasCreatureCastThisTurn(UUID creatureSourceId) { - return creaturesCasted.contains(creatureSourceId); - } - - @Override - public void reset() { - super.reset(); - creaturesCasted.clear(); - } - - @Override - public CreatureCastWatcher copy() { - return new CreatureCastWatcher(this); - } -} diff --git a/Mage.Sets/src/mage/sets/conspiracy/BarbedShocker.java b/Mage.Sets/src/mage/sets/conspiracy/BarbedShocker.java new file mode 100644 index 00000000000..0fb985c6562 --- /dev/null +++ b/Mage.Sets/src/mage/sets/conspiracy/BarbedShocker.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.sets.conspiracy; + +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author markedagain + */ +public class BarbedShocker extends CardImpl { + + public BarbedShocker(UUID ownerId) { + super(ownerId, 136, "Barbed Shocker", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.expansionSetCode = "CNS"; + this.subtype.add("Insect"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Haste + this.addAbility(HasteAbility.getInstance()); + // Whenever Barbed Shocker deals damage to a player, that player discards all the cards in his or her hand, then draws that many cards. + this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new BarbedShockerEffect(), false, true)); + } + + public BarbedShocker(final BarbedShocker card) { + super(card); + } + + @Override + public BarbedShocker copy() { + return new BarbedShocker(this); + } +} +class BarbedShockerEffect extends OneShotEffect { + + public BarbedShockerEffect() { + super(Outcome.Discard); + this.staticText = " that player discards all the cards in his or her hand, then draws that many cards"; + } + + public BarbedShockerEffect(final BarbedShockerEffect effect) { + super(effect); + } + + @Override + public BarbedShockerEffect copy() { + return new BarbedShockerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetPlayer != null) { + int count = targetPlayer.getHand().size(); + for (Card card : targetPlayer.getHand().getCards(game)) { + targetPlayer.discard(card, source, game); + } + targetPlayer.drawCards(count, game); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dissension/MacabreWaltz.java b/Mage.Sets/src/mage/sets/dissension/MacabreWaltz.java new file mode 100644 index 00000000000..90b164516d8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dissension/MacabreWaltz.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dissension; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class MacabreWaltz extends mage.sets.magicorigins.MacabreWaltz { + + public MacabreWaltz(UUID ownerId) { + super(ownerId); + this.cardNumber = 47; + this.expansionSetCode = "DIS"; + } + + public MacabreWaltz(final MacabreWaltz card) { + super(card); + } + + @Override + public MacabreWaltz copy() { + return new MacabreWaltz(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java index 7d49f8ada0d..a0569cfff99 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.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.sets.dragonsmaze; import java.util.UUID; @@ -56,17 +55,14 @@ import mage.util.CardUtil; * * @author LevelX2 */ - - public class CouncilOfTheAbsolute extends CardImpl { - public CouncilOfTheAbsolute (UUID ownerId) { + public CouncilOfTheAbsolute(UUID ownerId) { super(ownerId, 62, "Council of the Absolute", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); this.expansionSetCode = "DGM"; this.subtype.add("Human"); this.subtype.add("Advisor"); - this.power = new MageInt(2); this.toughness = new MageInt(4); @@ -79,7 +75,7 @@ public class CouncilOfTheAbsolute extends CardImpl { } - public CouncilOfTheAbsolute (final CouncilOfTheAbsolute card) { + public CouncilOfTheAbsolute(final CouncilOfTheAbsolute card) { super(card); } diff --git a/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java index a4bbe3f58f3..d9590de8ffa 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java +++ b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java @@ -33,7 +33,9 @@ import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -44,7 +46,6 @@ import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; /** @@ -63,8 +64,9 @@ public class TorrentElemental extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Whenever Torrent Elemental attacks, tap all creatures defending player controls. - this.addAbility(new AttacksTriggeredAbility(new TorrentElementalEffect(), false, null, SetTargetPointer.PLAYER)); - + Effect effect = new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent()); + effect.setText("tap all creatures defending player controls."); + this.addAbility(new AttacksTriggeredAbility(effect, false, null, SetTargetPointer.PLAYER)); // {3}{B/G}{B/G}: Put Torrent Elemental from exile onto the battlefield tapped. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.EXILED, new ReturnSourceFromExileToBattlefieldEffect(true), new ManaCostsImpl("{3}{B/G}{B/G}")); this.addAbility(ability); @@ -81,31 +83,6 @@ public class TorrentElemental extends CardImpl { } } -class TorrentElementalEffect extends OneShotEffect { - - public TorrentElementalEffect() { - super(Outcome.Tap); - this.staticText = "tap all creatures defending player controls"; - } - - public TorrentElementalEffect(final TorrentElementalEffect effect) { - super(effect); - } - - @Override - public TorrentElementalEffect copy() { - return new TorrentElementalEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), getTargetPointer().getFirst(game, source), game)) { - permanent.tap(game); - } - return true; - } -} - class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { private boolean tapped; @@ -172,4 +149,4 @@ class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { staticText = sb.toString(); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/invasion/ArmoredGuardian.java b/Mage.Sets/src/mage/sets/invasion/ArmoredGuardian.java new file mode 100644 index 00000000000..875c459a54e --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ArmoredGuardian.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +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.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.continuous.GainProtectionFromColorTargetEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class ArmoredGuardian extends CardImpl { + + public ArmoredGuardian(UUID ownerId) { + super(ownerId, 230, "Armored Guardian", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Cat"); + this.subtype.add("Soldier"); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // {1}{W}{W}: Target creature you control gains protection from the color of your choice until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), + new ManaCostsImpl("{1}{W}{W}")); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + // {1}{U}{U}: Armored Guardian gains shroud until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), + new ManaCostsImpl("{1}{U}{U}"))); + } + + public ArmoredGuardian(final ArmoredGuardian card) { + super(card); + } + + @Override + public ArmoredGuardian copy() { + return new ArmoredGuardian(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/BlindSeer.java b/Mage.Sets/src/mage/sets/invasion/BlindSeer.java new file mode 100644 index 00000000000..aa9a60a6383 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/BlindSeer.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.sets.invasion; + +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.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author LoneFox + + */ +public class BlindSeer extends CardImpl { + + public BlindSeer(UUID ownerId) { + super(ownerId, 47, "Blind Seer", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + this.expansionSetCode = "INV"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {1}{U}: Target spell or permanent becomes the color of your choice until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorTargetEffect(Duration.EndOfTurn), + new ManaCostsImpl("{1}{U}")); + ability.addTarget(new TargetSpellOrPermanent()); + this.addAbility(ability); + } + + public BlindSeer(final BlindSeer card) { + super(card); + } + + @Override + public BlindSeer copy() { + return new BlindSeer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/BlindingLight.java b/Mage.Sets/src/mage/sets/invasion/BlindingLight.java new file mode 100644 index 00000000000..65a593b5788 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/BlindingLight.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class BlindingLight extends mage.sets.mirage.BlindingLight { + + public BlindingLight(UUID ownerId) { + super(ownerId); + this.cardNumber = 9; + this.expansionSetCode = "INV"; + } + + public BlindingLight(final BlindingLight card) { + super(card); + } + + @Override + public BlindingLight copy() { + return new BlindingLight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/CallousGiant.java b/Mage.Sets/src/mage/sets/invasion/CallousGiant.java new file mode 100644 index 00000000000..f7304cfad28 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/CallousGiant.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.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author LoneFox + + */ +public class CallousGiant extends CardImpl { + + public CallousGiant(UUID ownerId) { + super(ownerId, 139, "Callous Giant", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + this.expansionSetCode = "INV"; + this.subtype.add("Giant"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // If a source would deal 3 or less damage to Callous Giant, prevent that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CallousGiantEffect())); + } + + public CallousGiant(final CallousGiant card) { + super(card); + } + + @Override + public CallousGiant copy() { + return new CallousGiant(this); + } +} + +class CallousGiantEffect extends PreventionEffectImpl { + + public CallousGiantEffect() { + super(Duration.WhileOnBattlefield); + staticText = "If a source would deal 3 or less damage to {this}, prevent that damage."; + } + + public CallousGiantEffect(final CallousGiantEffect effect) { + super(effect); + } + + @Override + public CallousGiantEffect copy() { + return new CallousGiantEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + if(event.getAmount() <= 3) + { + preventDamageAction(event, source, game); + return true; + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return super.applies(event, source, game) && event.getTargetId().equals(source.getSourceId()); + } + +} diff --git a/Mage.Sets/src/mage/sets/invasion/CryptAngel.java b/Mage.Sets/src/mage/sets/invasion/CryptAngel.java new file mode 100644 index 00000000000..da30d56b63d --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/CryptAngel.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LoneFox + + */ +public class CryptAngel extends CardImpl { + + private static final FilterCard filter = new FilterCard("white"); + private static final FilterCreatureCard filter2 = new FilterCreatureCard("blue or red creature card from your graveyard"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + filter2.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.BLUE))); + } + + public CryptAngel(UUID ownerId) { + super(ownerId, 97, "Crypt Angel", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Angel"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // protection from white + this.addAbility(new ProtectionAbility(filter)); + // When Crypt Angel enters the battlefield, return target blue or red creature card from your graveyard to your hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); + ability.addTarget(new TargetCardInYourGraveyard(filter2)); + this.addAbility(ability); + } + + public CryptAngel(final CryptAngel card) { + super(card); + } + + @Override + public CryptAngel copy() { + return new CryptAngel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/PlagueSpitter.java b/Mage.Sets/src/mage/sets/invasion/PlagueSpitter.java new file mode 100644 index 00000000000..cc9c600a78c --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/PlagueSpitter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.DamageEverythingEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LoneFox + + */ +public class PlagueSpitter extends CardImpl { + + public PlagueSpitter(UUID ownerId) { + super(ownerId, 119, "Plague Spitter", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Horror"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, Plague Spitter deals 1 damage to each creature and each player. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DamageEverythingEffect(1), TargetController.YOU, false)); + // When Plague Spitter dies, Plague Spitter deals 1 damage to each creature and each player. + this.addAbility(new DiesTriggeredAbility(new DamageEverythingEffect(1), false)); + } + + public PlagueSpitter(final PlagueSpitter card) { + super(card); + } + + @Override + public PlagueSpitter copy() { + return new PlagueSpitter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/PlagueSpores.java b/Mage.Sets/src/mage/sets/invasion/PlagueSpores.java new file mode 100644 index 00000000000..db32455cf27 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/PlagueSpores.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.sets.invasion; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author LoneFox + + */ +public class PlagueSpores extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public PlagueSpores(UUID ownerId) { + super(ownerId, 260, "Plague Spores", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{4}{B}{R}"); + this.expansionSetCode = "INV"; + + // Destroy target nonblack creature and target land. They can't be regenerated. + Effect effect = new DestroyTargetEffect(true); + effect.setText("Destroy target nonblack creature and target land. They can't be regenerated."); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().addTarget(new TargetLandPermanent()); + } + + public PlagueSpores(final PlagueSpores card) { + super(card); + } + + @Override + public PlagueSpores copy() { + return new PlagueSpores(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/RecklessAssault.java b/Mage.Sets/src/mage/sets/invasion/RecklessAssault.java new file mode 100644 index 00000000000..ec7a63d2631 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/RecklessAssault.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + + */ +public class RecklessAssault extends CardImpl { + + public RecklessAssault(UUID ownerId) { + super(ownerId, 263, "Reckless Assault", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{R}"); + this.expansionSetCode = "INV"; + + // {1}, Pay 2 life: Reckless Assault deals 1 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}")); + ability.addCost(new PayLifeCost(2)); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public RecklessAssault(final RecklessAssault card) { + super(card); + } + + @Override + public RecklessAssault copy() { + return new RecklessAssault(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/SamiteArcher.java b/Mage.Sets/src/mage/sets/invasion/SamiteArcher.java new file mode 100644 index 00000000000..ee23bb2bb9b --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/SamiteArcher.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +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.common.DamageTargetEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + + */ +public class SamiteArcher extends CardImpl { + + public SamiteArcher(UUID ownerId) { + super(ownerId, 269, "Samite Archer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.subtype.add("Archer"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {T}: Prevent the next 1 damage that would be dealt to target creature or player this turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), + new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + // {T}: Samite Archer deals 1 damage to target creature or player. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public SamiteArcher(final SamiteArcher card) { + super(card); + } + + @Override + public SamiteArcher copy() { + return new SamiteArcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/SmolderingTar.java b/Mage.Sets/src/mage/sets/invasion/SmolderingTar.java new file mode 100644 index 00000000000..7effc424ebf --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/SmolderingTar.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.sets.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class SmolderingTar extends CardImpl { + + public SmolderingTar(UUID ownerId) { + super(ownerId, 275, "Smoldering Tar", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{R}"); + this.expansionSetCode = "INV"; + + // At the beginning of your upkeep, target player loses 1 life. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new LoseLifeTargetEffect(1), TargetController.YOU, false); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + // Sacrifice Smoldering Tar: Smoldering Tar deals 4 damage to target creature. Activate this ability only any time you could cast a sorcery. + ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(4), new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public SmolderingTar(final SmolderingTar card) { + super(card); + } + + @Override + public SmolderingTar copy() { + return new SmolderingTar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/StalkingAssassin.java b/Mage.Sets/src/mage/sets/invasion/StalkingAssassin.java new file mode 100644 index 00000000000..e89edd61256 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/StalkingAssassin.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +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.common.DestroyTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class StalkingAssassin extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); + + static { + filter.add(new TappedPredicate()); + } + + public StalkingAssassin(UUID ownerId) { + super(ownerId, 277, "Stalking Assassin", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Assassin"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {3}{U}, {T}: Tap target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{3}{U}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + // {3}{B}, {T}: Destroy target tapped creature. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{3}{B}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public StalkingAssassin(final StalkingAssassin card) { + super(card); + } + + @Override + public StalkingAssassin copy() { + return new StalkingAssassin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/TectonicInstability.java b/Mage.Sets/src/mage/sets/invasion/TectonicInstability.java new file mode 100644 index 00000000000..5cbdd9b6bed --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/TectonicInstability.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; + +/** + * + * @author LoneFox + + */ +public class TectonicInstability extends CardImpl { + + public TectonicInstability(UUID ownerId) { + super(ownerId, 173, "Tectonic Instability", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + this.expansionSetCode = "INV"; + + // Whenever a land enters the battlefield, tap all lands its controller controls. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, + new TapAllTargetPlayerControlsEffect(new FilterLandPermanent()), new FilterLandPermanent(), + false, SetTargetPointer.PLAYER, "Whenever a land enters the battlefield, tap all lands its controller controls.")); + } + + public TectonicInstability(final TectonicInstability card) { + super(card); + } + + @Override + public TectonicInstability copy() { + return new TectonicInstability(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/Tek.java b/Mage.Sets/src/mage/sets/invasion/Tek.java new file mode 100644 index 00000000000..e4457c07a41 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/Tek.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.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + + */ +public class Tek extends CardImpl { + + private static final FilterControlledPermanent filterPlains = new FilterControlledPermanent("Plains"); + private static final FilterControlledPermanent filterIsland = new FilterControlledPermanent("Island"); + private static final FilterControlledPermanent filterSwamp = new FilterControlledPermanent("Swamp"); + private static final FilterControlledPermanent filterMountain = new FilterControlledPermanent("Mountain"); + private static final FilterControlledPermanent filterForest = new FilterControlledPermanent("Forest"); + + static { + filterPlains.add(new SubtypePredicate("Plains")); + filterIsland.add(new SubtypePredicate("Island")); + filterSwamp.add(new SubtypePredicate("Swamp")); + filterMountain.add(new SubtypePredicate("Mountain")); + filterForest.add(new SubtypePredicate("Forest")); + } + + + public Tek(UUID ownerId) { + super(ownerId, 313, "Tek", Rarity.RARE, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + this.expansionSetCode = "INV"; + this.subtype.add("Dragon"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Tek gets +0/+2 as long as you control a Plains, has flying as long as you control an Island, gets +2/+0 as long as you control a Swamp, has first strike as long as you control a Mountain, and has trample as long as you control a Forest. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(0, 2, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filterPlains), "{this} gets +0/+2 as long as you control a Plains")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filterIsland), ", has flying as long as you control an Island")); + ability.addEffect(new ConditionalContinuousEffect(new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filterSwamp), ", gets +2/+0 as long as you control a Swamp")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filterMountain), ", has first strike as long as you control a Mountain")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filterForest), ", and has trample as long as you control a Forest.")); + this.addAbility(ability); + } + + public Tek(final Tek card) { + super(card); + } + + @Override + public Tek copy() { + return new Tek(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/UrborgShambler.java b/Mage.Sets/src/mage/sets/invasion/UrborgShambler.java new file mode 100644 index 00000000000..e587ab087b4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/UrborgShambler.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.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class UrborgShambler extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("black creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public UrborgShambler(UUID ownerId) { + super(ownerId, 133, "Urborg Shambler", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Horror"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Other black creatures get -1/-1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(-1, -1, + Duration.WhileOnBattlefield, filter, true))); + } + + public UrborgShambler(final UrborgShambler card) { + super(card); + } + + @Override + public UrborgShambler copy() { + return new UrborgShambler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/VoraciousCobra.java b/Mage.Sets/src/mage/sets/invasion/VoraciousCobra.java new file mode 100644 index 00000000000..9bdc35bf630 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/VoraciousCobra.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.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class VoraciousCobra extends CardImpl { + + public VoraciousCobra(UUID ownerId) { + super(ownerId, 288, "Voracious Cobra", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); + this.expansionSetCode = "INV"; + this.subtype.add("Snake"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + // Whenever Voracious Cobra deals combat damage to a creature, destroy that creature. + this.addAbility(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(), true, false, true)); + } + + public VoraciousCobra(final VoraciousCobra card) { + super(card); + } + + @Override + public VoraciousCobra copy() { + return new VoraciousCobra(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/Wallop.java b/Mage.Sets/src/mage/sets/invasion/Wallop.java new file mode 100644 index 00000000000..d4b1b93cdea --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/Wallop.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.sets.invasion; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class Wallop extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue or black creature with flying"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.BLACK))); + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public Wallop(UUID ownerId) { + super(ownerId, 223, "Wallop", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{1}{G}"); + this.expansionSetCode = "INV"; + + // Destroy target blue or black creature with flying. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public Wallop(final Wallop card) { + super(card); + } + + @Override + public Wallop copy() { + return new Wallop(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/ManaShort.java b/Mage.Sets/src/mage/sets/limitedalpha/ManaShort.java index 68a31f8db1c..9a1f38eec6e 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/ManaShort.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/ManaShort.java @@ -27,16 +27,14 @@ */ package mage.sets.limitedalpha; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.filter.common.FilterLandPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -52,7 +50,6 @@ public class ManaShort extends CardImpl { super(ownerId, 66, "Mana Short", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{U}"); this.expansionSetCode = "LEA"; - // Tap all lands target player controls and empty his or her mana pool. this.getSpellAbility().addEffect(new ManaShortEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); @@ -68,13 +65,13 @@ public class ManaShort extends CardImpl { } } -class ManaShortEffect extends OneShotEffect { +class ManaShortEffect extends TapAllTargetPlayerControlsEffect { public ManaShortEffect() { - super(Outcome.Detriment); + super(new FilterLandPermanent("lands")); staticText = "Tap all lands target player controls and empty his or her mana pool"; } - + public ManaShortEffect(final ManaShortEffect effect) { super(effect); } @@ -83,24 +80,15 @@ class ManaShortEffect extends OneShotEffect { public ManaShortEffect copy() { return new ManaShortEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); - if (targetPlayer != null) { - FilterLandPermanent filter = new FilterLandPermanent(); - filter.add(new ControllerIdPredicate(targetPlayer.getId())); - - List lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent land : lands) { - land.tap(game); - } - + if(targetPlayer != null) { + super.apply(game, source); targetPlayer.getManaPool().emptyPool(game); - return true; } return false; } - } diff --git a/Mage.Sets/src/mage/sets/lorwyn/BoggartForager.java b/Mage.Sets/src/mage/sets/lorwyn/BoggartForager.java new file mode 100644 index 00000000000..022a18d0646 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/BoggartForager.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.sets.lorwyn; + +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.mana.ManaCostsImpl; +import mage.abilities.effects.common.ShuffleLibraryTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPlayer; + +/** + * + * @author Wehk + */ +public class BoggartForager extends CardImpl { + + public BoggartForager(UUID ownerId) { + super(ownerId, 154, "Boggart Forager", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{R}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Goblin"); + this.subtype.add("Rogue"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {R}, Sacrifice Boggart Forager: Target player shuffles his or her library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleLibraryTargetEffect(), new ManaCostsImpl("{R}")); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public BoggartForager(final BoggartForager card) { + super(card); + } + + @Override + public BoggartForager copy() { + return new BoggartForager(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/ExiledBoggart.java b/Mage.Sets/src/mage/sets/lorwyn/ExiledBoggart.java new file mode 100644 index 00000000000..6503fffe837 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/ExiledBoggart.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author Wehk + */ +public class ExiledBoggart extends CardImpl { + + public ExiledBoggart(UUID ownerId) { + super(ownerId, 109, "Exiled Boggart", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Goblin"); + this.subtype.add("Rogue"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Exiled Boggart dies, discard a card. + this.addAbility(new DiesTriggeredAbility(new DiscardControllerEffect(1), false)); + } + + public ExiledBoggart(final ExiledBoggart card) { + super(card); + } + + @Override + public ExiledBoggart copy() { + return new ExiledBoggart(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/GoldmeadowDodger.java b/Mage.Sets/src/mage/sets/lorwyn/GoldmeadowDodger.java new file mode 100644 index 00000000000..a957e34130f --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/GoldmeadowDodger.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.sets.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; + +/** + * + * @author Wehk + */ +public class GoldmeadowDodger extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 4 or greater"); + + static { + filter.add(new PowerPredicate(Filter.ComparisonType.GreaterThan, 3)); + } + + public GoldmeadowDodger(UUID ownerId) { + super(ownerId, 16, "Goldmeadow Dodger", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{W}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Kithkin"); + this.subtype.add("Rogue"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Goldmeadow Dodger can't be blocked by creatures with power 4 or greater. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + } + + public GoldmeadowDodger(final GoldmeadowDodger card) { + super(card); + } + + @Override + public GoldmeadowDodger copy() { + return new GoldmeadowDodger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/MistbindClique.java b/Mage.Sets/src/mage/sets/lorwyn/MistbindClique.java index 5eaf9d8f525..3809f1350bc 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/MistbindClique.java +++ b/Mage.Sets/src/mage/sets/lorwyn/MistbindClique.java @@ -27,14 +27,13 @@ */ package mage.sets.lorwyn; -import java.util.List; import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.ZoneChangeTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; import mage.abilities.keyword.ChampionAbility; import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; @@ -44,11 +43,9 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterLandPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.target.TargetPlayer; /** @@ -92,14 +89,14 @@ class MistbindCliqueAbility extends ZoneChangeTriggeredAbility { public MistbindCliqueAbility() { // ability has to trigger independant where the source object is now - super(Zone.ALL, Zone.BATTLEFIELD, Zone.EXILED, new MistbindCliqueTapEffect(), "When a Faerie is championed with {this}, ", false); + super(Zone.ALL, Zone.BATTLEFIELD, Zone.EXILED, new TapAllTargetPlayerControlsEffect(new FilterLandPermanent("lands")), "When a Faerie is championed with {this}, ", false); this.addTarget(new TargetPlayer()); } public MistbindCliqueAbility(MistbindCliqueAbility ability) { super(ability); } - + @Override public MistbindCliqueAbility copy() { return new MistbindCliqueAbility(this); @@ -113,44 +110,11 @@ class MistbindCliqueAbility extends ZoneChangeTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getSourceId() != null && event.getSourceId().equals(getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; + ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getTarget() != null && zEvent.getTarget().hasSubtype("Faerie")) { return true; - } + } } return false; } } - -class MistbindCliqueTapEffect extends OneShotEffect { - - public MistbindCliqueTapEffect() { - super(Outcome.Tap); - staticText = "tap all lands target player controls"; - } - - public MistbindCliqueTapEffect(final MistbindCliqueTapEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getFirstTarget() == null) { - return false; - } - - FilterLandPermanent filter = new FilterLandPermanent(); - filter.add(new ControllerIdPredicate(source.getFirstTarget())); - - List lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent land : lands) { - land.tap(game); - } - return true; - } - - @Override - public MistbindCliqueTapEffect copy() { - return new MistbindCliqueTapEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/lorwyn/Rootgrapple.java b/Mage.Sets/src/mage/sets/lorwyn/Rootgrapple.java new file mode 100644 index 00000000000..03d45de6570 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/Rootgrapple.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.sets.lorwyn; + +import java.util.UUID; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.TargetPermanent; + +/** + * + * @author Wehk + */ +public class Rootgrapple extends CardImpl { + + private static final FilterPermanent filterNoncreature = new FilterPermanent("noncreature permanent"); + private static final FilterPermanent filterTreefolk = new FilterPermanent("If you control a Treefolk,"); + + static { + filterNoncreature.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + filterTreefolk.add(new SubtypePredicate("Treefolk")); + } + + public Rootgrapple(UUID ownerId) { + super(ownerId, 234, "Rootgrapple", Rarity.COMMON, new CardType[]{CardType.TRIBAL, CardType.INSTANT}, "{4}{G}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Treefolk"); + + // Destroy target noncreature permanent. + this.getSpellAbility().addTarget(new TargetPermanent(filterNoncreature)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + + // If you control a Treefolk, draw a card. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DrawCardSourceControllerEffect(1), + new PermanentsOnTheBattlefieldCondition(filterTreefolk, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 0), + "If you control a Treefolk, draw a card")); + } + + public Rootgrapple(final Rootgrapple card) { + super(card); + } + + @Override + public Rootgrapple copy() { + return new Rootgrapple(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AcolyteOfTheInferno.java b/Mage.Sets/src/mage/sets/magicorigins/AcolyteOfTheInferno.java new file mode 100644 index 00000000000..fb8642d959f --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AcolyteOfTheInferno.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author Wehk + */ +public class AcolyteOfTheInferno extends CardImpl { + + public AcolyteOfTheInferno(UUID ownerId) { + super(ownerId, 128, "Acolyte of the Inferno", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Monk"); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Renown 1 + this.addAbility(new RenownAbility(1)); + + // Whenever Acolyte of the Inferno becomes blocked by a creature, it deals 2 damage to that creature + this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new DamageTargetEffect(2, true, "that creature"), false)); + } + + public AcolyteOfTheInferno(final AcolyteOfTheInferno card) { + super(card); + } + + @Override + public AcolyteOfTheInferno copy() { + return new AcolyteOfTheInferno(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AerialVolley.java b/Mage.Sets/src/mage/sets/magicorigins/AerialVolley.java new file mode 100644 index 00000000000..daecbc102c9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AerialVolley.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author LevelX2 + */ +public class AerialVolley extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public AerialVolley(UUID ownerId) { + super(ownerId, 168, "Aerial Volley", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); + this.expansionSetCode = "ORI"; + + // Aerial Volley deals 3 damage divided as you choose among one, two, or three target creatures with flying. + Effect effect = new DamageMultiEffect(3); + effect.setText("A{this} deals 3 damage divided as you choose among one, two, or three target creatures with flying"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3, filter)); + + } + + public AerialVolley(final AerialVolley card) { + super(card); + } + + @Override + public AerialVolley copy() { + return new AerialVolley(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AlchemistsVial.java b/Mage.Sets/src/mage/sets/magicorigins/AlchemistsVial.java new file mode 100644 index 00000000000..84867bbeef7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AlchemistsVial.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.combat.CantAttackBlockTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class AlchemistsVial extends CardImpl { + + public AlchemistsVial(UUID ownerId) { + super(ownerId, 220, "Alchemist's Vial", Rarity.COMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "ORI"; + + // When Alchemist's Vial enters the battlefield, draw a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); + // {1}, {T}: Sacrifice Alchemist's Vial: Target creature can't attack or block this turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantAttackBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public AlchemistsVial(final AlchemistsVial card) { + super(card); + } + + @Override + public AlchemistsVial copy() { + return new AlchemistsVial(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AlhammarretHighArbiter.java b/Mage.Sets/src/mage/sets/magicorigins/AlhammarretHighArbiter.java new file mode 100644 index 00000000000..a3ffd5c8fb0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AlhammarretHighArbiter.java @@ -0,0 +1,189 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandCard; +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.TargetCard; +import mage.util.CardUtil; +import mage.util.GameLog; + +/** + * + * @author LevelX2 + */ +public class AlhammarretHighArbiter extends CardImpl { + + public AlhammarretHighArbiter(UUID ownerId) { + super(ownerId, 43, "Alhammarret, High Arbiter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + this.expansionSetCode = "ORI"; + this.supertype.add("Legendary"); + this.subtype.add("Sphinx"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // As Alhammarret, High Arbiter enters the battlefield, each opponent reveals his or her hand. You choose the name of a nonland card revealed this way. + // Your opponents can't cast spells with the chosen name. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AlhammarretHighArbiterEffect(), ""))); + } + + public AlhammarretHighArbiter(final AlhammarretHighArbiter card) { + super(card); + } + + @Override + public AlhammarretHighArbiter copy() { + return new AlhammarretHighArbiter(this); + } +} + +class AlhammarretHighArbiterEffect extends OneShotEffect { + + public AlhammarretHighArbiterEffect() { + super(Outcome.Benefit); + this.staticText = "As {this} enters the battlefield, each opponent reveals his or her hand. You choose the name of a nonland card revealed this way." + + "
Your opponents can't cast spells with the chosen name"; + } + + public AlhammarretHighArbiterEffect(final AlhammarretHighArbiterEffect effect) { + super(effect); + } + + @Override + public AlhammarretHighArbiterEffect copy() { + return new AlhammarretHighArbiterEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards revealedCards = new CardsImpl(Zone.PICK); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + if (playerId != controller.getId()) { + Player opponent = game.getPlayer(playerId); + if (opponent != null) { + Cards cards = new CardsImpl(opponent.getHand()); + opponent.revealCards(opponent.getName() + "'s hand", cards, game); + revealedCards.addAll(cards); + } + } + } + TargetCard target = new TargetCard(Zone.HAND, new FilterNonlandCard("nonland card from an opponents hand")); + controller.chooseTarget(Outcome.Benefit, revealedCards, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + game.informPlayers("The choosen card name is [" + GameLog.getColoredObjectName(card) + "]"); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent != null) { + sourcePermanent.addInfo("chosen card name", CardUtil.addToolTipMarkTags("Chosen card name: " + card.getName()), game); + } + game.addEffect(new AlhammarretHighArbiterCantCastEffect(card.getName()), source); + } + return true; + + } + return false; + } +} + +class AlhammarretHighArbiterCantCastEffect extends ContinuousRuleModifyingEffectImpl { + + String cardName; + + public AlhammarretHighArbiterCantCastEffect(String cardName) { + super(Duration.Custom, Outcome.Benefit); + this.cardName = cardName; + staticText = "Your opponents can't cast spells with the chosen name"; + } + + public AlhammarretHighArbiterCantCastEffect(final AlhammarretHighArbiterCantCastEffect effect) { + super(effect); + this.cardName = effect.cardName; + } + + @Override + public AlhammarretHighArbiterCantCastEffect copy() { + return new AlhammarretHighArbiterCantCastEffect(this); + } + + @Override + public boolean isInactive(Ability source, Game game) { + Permanent sourceObject = game.getPermanent(source.getSourceId()); + return sourceObject == null || sourceObject.getZoneChangeCounter(game) != source.getSourceObjectZoneChangeCounter(); + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null) { + return "You may not cast a card named " + cardName + " (" + mageObject.getLogName() + ")."; + } + return null; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + MageObject object = game.getObject(event.getSourceId()); + if (object != null && object.getName().equals(cardName)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AmprynTactician.java b/Mage.Sets/src/mage/sets/magicorigins/AmprynTactician.java new file mode 100644 index 00000000000..3229076d44a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AmprynTactician.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author Wehk + */ +public class AmprynTactician extends CardImpl { + + public AmprynTactician(UUID ownerId) { + super(ownerId, 2, "Ampryn Tactician", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Ampryn Tactician enters the battlefield, creatures you control get +1/+1 until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostControlledEffect(1, 1, Duration.EndOfTurn))); + } + + public AmprynTactician(final AmprynTactician card) { + super(card); + } + + @Override + public AmprynTactician copy() { + return new AmprynTactician(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AnchorToTheAEther.java b/Mage.Sets/src/mage/sets/magicorigins/AnchorToTheAEther.java new file mode 100644 index 00000000000..c7992654e2d --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AnchorToTheAEther.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.common.PutOnLibraryTargetEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class AnchorToTheAEther extends CardImpl { + + public AnchorToTheAEther(UUID ownerId) { + super(ownerId, 44, "Anchor to the AEther", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{U}"); + this.expansionSetCode = "ORI"; + + // Put target creature on top of its owner's library. Scry 1. + this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new ScryEffect(1)); + + } + + public AnchorToTheAEther(final AnchorToTheAEther card) { + super(card); + } + + @Override + public AnchorToTheAEther copy() { + return new AnchorToTheAEther(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java new file mode 100644 index 00000000000..4cbe0168fc4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AnimistsAwakening.java @@ -0,0 +1,125 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class AnimistsAwakening extends CardImpl { + + public AnimistsAwakening(UUID ownerId) { + super(ownerId, 169, "Animist's Awakening", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}"); + this.expansionSetCode = "ORI"; + + // Reveal the top X cards of your library. Put all land cards from among them onto the battlefield tapped and the rest on the bottom of your library in any order. + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, untap those lands. + this.getSpellAbility().addEffect(new AnimistsAwakeningEffect()); + } + + public AnimistsAwakening(final AnimistsAwakening card) { + super(card); + } + + @Override + public AnimistsAwakening copy() { + return new AnimistsAwakening(this); + } +} + +class AnimistsAwakeningEffect extends OneShotEffect { + + public AnimistsAwakeningEffect() { + super(Outcome.PutCardInPlay); + staticText = "Reveal the top X cards of your library. Put all land cards from among them onto the battlefield tapped and the rest on the bottom of your library in any order." + + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, untap those lands"; + } + + public AnimistsAwakeningEffect(final AnimistsAwakeningEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + Cards cards = new CardsImpl(Zone.LIBRARY); + int xValue = source.getManaCostsToPay().getX(); + cards.addAll(controller.getLibrary().getTopCards(game, xValue)); + List lands = new ArrayList<>(); + if (cards.size() > 0) { + controller.revealCards(sourceObject.getIdName(), cards, game); + for (Card card : cards.getCards(new FilterLandCard(), source.getSourceId(), source.getControllerId(), game)) { + cards.remove(card); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + Permanent land = game.getPermanent(card.getId()); + if (land != null) { + lands.add(land); + } + + } + controller.putCardsOnBottomOfLibrary(cards, game, source, true); + + if (SpellMasteryCondition.getInstance().apply(game, source)) { + for (Permanent land : lands) { + land.untap(game); + } + } + } + return true; + } + + @Override + public AnimistsAwakeningEffect copy() { + return new AnimistsAwakeningEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ArchangelOfTithes.java b/Mage.Sets/src/mage/sets/magicorigins/ArchangelOfTithes.java new file mode 100644 index 00000000000..f58a35af3a9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ArchangelOfTithes.java @@ -0,0 +1,131 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantAttackYouUnlessPayManaAllEffect; +import mage.abilities.effects.common.combat.CantBlockUnlessPayManaAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class ArchangelOfTithes extends CardImpl { + + public ArchangelOfTithes(UUID ownerId) { + super(ownerId, 4, "Archangel of Tithes", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{1}{W}{W}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Angel"); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // As long as Archangel of Tithes is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchangelOfTithesPayManaToAttackAllEffect())); + + // As long as Archangel of Tithes is attacking, creatures can't block unless their controller pays {1} for each of those creatures. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchangelOfTithesPayManaToBlockAllEffect())); + } + + public ArchangelOfTithes(final ArchangelOfTithes card) { + super(card); + } + + @Override + public ArchangelOfTithes copy() { + return new ArchangelOfTithes(this); + } +} + +class ArchangelOfTithesPayManaToAttackAllEffect extends CantAttackYouUnlessPayManaAllEffect { + + ArchangelOfTithesPayManaToAttackAllEffect() { + super(new ManaCostsImpl<>("{1}"), true); + staticText = "As long as {this} is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures."; + } + + ArchangelOfTithesPayManaToAttackAllEffect(ArchangelOfTithesPayManaToAttackAllEffect effect) { + super(effect); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent.isTapped()) { + return false; + } + return super.applies(event, source, game); + } + + @Override + public ArchangelOfTithesPayManaToAttackAllEffect copy() { + return new ArchangelOfTithesPayManaToAttackAllEffect(this); + } + +} + +class ArchangelOfTithesPayManaToBlockAllEffect extends CantBlockUnlessPayManaAllEffect { + + ArchangelOfTithesPayManaToBlockAllEffect() { + super(new ManaCostsImpl<>("{1}"), true); + staticText = "As long as {this} is attacking, creatures can't block unless their controller pays {1} for each of those creatures."; + } + + ArchangelOfTithesPayManaToBlockAllEffect(ArchangelOfTithesPayManaToBlockAllEffect effect) { + super(effect); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (!permanent.isAttacking()) { + return false; + } + return super.applies(event, source, game); + } + + @Override + public ArchangelOfTithesPayManaToBlockAllEffect copy() { + return new ArchangelOfTithesPayManaToBlockAllEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/AvenBattlePriest.java b/Mage.Sets/src/mage/sets/magicorigins/AvenBattlePriest.java new file mode 100644 index 00000000000..b46ed44fc46 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/AvenBattlePriest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author Wehk + */ +public class AvenBattlePriest extends CardImpl { + + public AvenBattlePriest(UUID ownerId) { + super(ownerId, 6, "Aven Battle Priest", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{5}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Bird"); + this.subtype.add("Cleric"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Aven battle Priest enters the battlefield, you gain 3 life. + this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3))); + } + + public AvenBattlePriest(final AvenBattlePriest card) { + super(card); + } + + @Override + public AvenBattlePriest copy() { + return new AvenBattlePriest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/CalculatedDismissal.java b/Mage.Sets/src/mage/sets/magicorigins/CalculatedDismissal.java new file mode 100644 index 00000000000..5a8856b34b0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/CalculatedDismissal.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.CounterUnlessPaysEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetSpell; + +/** + * + * @author LevelX2 + */ +public class CalculatedDismissal extends CardImpl { + + public CalculatedDismissal(UUID ownerId) { + super(ownerId, 48, "Calculated Dismissal", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{U}"); + this.expansionSetCode = "ORI"; + + // Counter target spell unless its controller pays {3}. + this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(3))); + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, scry 2. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new ScryEffect(2), SpellMasteryCondition.getInstance(), + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, scry 2")); + } + + public CalculatedDismissal(final CalculatedDismissal card) { + super(card); + } + + @Override + public CalculatedDismissal copy() { + return new CalculatedDismissal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/CallOfTheFullMoon.java b/Mage.Sets/src/mage/sets/magicorigins/CallOfTheFullMoon.java new file mode 100644 index 00000000000..cb0b34f8d31 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/CallOfTheFullMoon.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class CallOfTheFullMoon extends CardImpl { + + public CallOfTheFullMoon(UUID ownerId) { + super(ownerId, 134, "Call of the Full Moon", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature gets +3/+2 and has trample. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 2, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA); + effect.setText("and has trample."); + ability.addEffect(effect); + this.addAbility(ability); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice Call of the Full Moon. + TriggeredAbility ability2 = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect(), TargetController.ANY, false); + this.addAbility(new ConditionalTriggeredAbility(ability2, TwoOrMoreSpellsWereCastLastTurnCondition.getInstance(), + "At the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice {this}.")); + } + + public CallOfTheFullMoon(final CallOfTheFullMoon card) { + super(card); + } + + @Override + public CallOfTheFullMoon copy() { + return new CallOfTheFullMoon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/CausticCaterpillar.java b/Mage.Sets/src/mage/sets/magicorigins/CausticCaterpillar.java new file mode 100644 index 00000000000..ad57d8f949c --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/CausticCaterpillar.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.sets.magicorigins; + +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.mana.ManaCostsImpl; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class CausticCaterpillar extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifact or enchantment"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.ENCHANTMENT))); + } + + public CausticCaterpillar(UUID ownerId) { + super(ownerId, 170, "Caustic Caterpillar", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Insect"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {1}{G}, Sacrifice Caustic Caterpillar: Destroy target artifact or enchantment. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{1}{G}")); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public CausticCaterpillar(final CausticCaterpillar card) { + super(card); + } + + @Override + public CausticCaterpillar copy() { + return new CausticCaterpillar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java index a12cfc19dd7..45882a2ddcf 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java @@ -1,146 +1,145 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.sets.magicorigins; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageSelfEffect; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.command.Emblem; -import mage.players.Player; -import mage.target.TargetPlayer; -import mage.target.common.TargetCreaturePermanent; - -/** - * - * @author LevelX2 - */ -public class ChandraRoaringFlame extends CardImpl { - - public ChandraRoaringFlame(UUID ownerId) { - super(ownerId, 135, "Chandra, Roaring Flame", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, ""); - this.expansionSetCode = "ORI"; - this.subtype.add("Chandra"); - this.color.setRed(true); - - this.nightCard = true; - this.canTransform = true; - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); - - // +1: Chandra, Roaring Flame deals 2 damage to target player. - LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1); - loyaltyAbility.addTarget(new TargetPlayer()); - this.addAbility(loyaltyAbility); - - //-2: Chandra, Roaring Flame deals 2 damage to target creature. - loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), -2); - loyaltyAbility.addTarget(new TargetCreaturePermanent()); - this.addAbility(loyaltyAbility); - - //-7: Chandra, Roaring Flame deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." - this.addAbility(new LoyaltyAbility(new ChandraRoaringFlameEmblemEffect(), -7)); - - - } - - public ChandraRoaringFlame(final ChandraRoaringFlame card) { - super(card); - } - - @Override - public ChandraRoaringFlame copy() { - return new ChandraRoaringFlame(this); - } -} - -class ChandraRoaringFlameEmblemEffect extends OneShotEffect { - - public ChandraRoaringFlameEmblemEffect() { - super(Outcome.Damage); - this.staticText = "{this} deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with \"At the beginning of your upkeep, this emblem deals 3 damage to you.\""; - } - - public ChandraRoaringFlameEmblemEffect(final ChandraRoaringFlameEmblemEffect effect) { - super(effect); - } - - @Override - public ChandraRoaringFlameEmblemEffect copy() { - return new ChandraRoaringFlameEmblemEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - List opponentsEmblem = new ArrayList<>(); - for(UUID playerId: game.getOpponents(controller.getId())) { - Player opponent = game.getPlayer(playerId); - if (opponent != null) { - if (opponent.damage(6, source.getSourceId(), game, false, true) > 0) { - opponentsEmblem.add(opponent); - } - } - } - for (Player opponent : opponentsEmblem) { - game.addEmblem(new ChandraRoaringFlameEmblem(), source, opponent.getId()); - } - } - return false; - } -} - -/** - * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." - */ -class ChandraRoaringFlameEmblem extends Emblem { - - public ChandraRoaringFlameEmblem() { - setName("EMBLEM: Chandra, Roaring Flame"); - Effect effect = new DamageTargetEffect(3); - effect.setText("this emblem deals 3 damage to you"); - this.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, effect, TargetController.YOU, false, true)); - } +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class ChandraRoaringFlame extends CardImpl { + + public ChandraRoaringFlame(UUID ownerId) { + super(ownerId, 135, "Chandra, Roaring Flame", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, ""); + this.expansionSetCode = "ORI"; + this.subtype.add("Chandra"); + this.color.setRed(true); + + this.nightCard = true; + this.canTransform = true; + + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + + // +1: Chandra, Roaring Flame deals 2 damage to target player. + LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1); + loyaltyAbility.addTarget(new TargetPlayer()); + this.addAbility(loyaltyAbility); + + //-2: Chandra, Roaring Flame deals 2 damage to target creature. + loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), -2); + loyaltyAbility.addTarget(new TargetCreaturePermanent()); + this.addAbility(loyaltyAbility); + + //-7: Chandra, Roaring Flame deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." + this.addAbility(new LoyaltyAbility(new ChandraRoaringFlameEmblemEffect(), -7)); + + + } + + public ChandraRoaringFlame(final ChandraRoaringFlame card) { + super(card); + } + + @Override + public ChandraRoaringFlame copy() { + return new ChandraRoaringFlame(this); + } +} + +class ChandraRoaringFlameEmblemEffect extends OneShotEffect { + + public ChandraRoaringFlameEmblemEffect() { + super(Outcome.Damage); + this.staticText = "{this} deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with \"At the beginning of your upkeep, this emblem deals 3 damage to you.\""; + } + + public ChandraRoaringFlameEmblemEffect(final ChandraRoaringFlameEmblemEffect effect) { + super(effect); + } + + @Override + public ChandraRoaringFlameEmblemEffect copy() { + return new ChandraRoaringFlameEmblemEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + List opponentsEmblem = new ArrayList<>(); + for(UUID playerId: game.getOpponents(controller.getId())) { + Player opponent = game.getPlayer(playerId); + if (opponent != null) { + if (opponent.damage(6, source.getSourceId(), game, false, true) > 0) { + opponentsEmblem.add(opponent); + } + } + } + for (Player opponent : opponentsEmblem) { + game.addEmblem(new ChandraRoaringFlameEmblem(), source, opponent.getId()); + } + } + return false; + } +} + +/** + * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." + */ +class ChandraRoaringFlameEmblem extends Emblem { + + public ChandraRoaringFlameEmblem() { + setName("EMBLEM: Chandra, Roaring Flame"); + Effect effect = new DamageTargetEffect(3); + effect.setText("this emblem deals 3 damage to you"); + this.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, effect, TargetController.YOU, false, true)); + } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magicorigins/ChandrasIgnition.java b/Mage.Sets/src/mage/sets/magicorigins/ChandrasIgnition.java index b6c28101735..8fc0e942883 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ChandrasIgnition.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ChandrasIgnition.java @@ -66,34 +66,34 @@ public class ChandrasIgnition extends CardImpl { } class ChandrasIgnitionEffect extends OneShotEffect { - + public ChandrasIgnitionEffect() { super(Outcome.Benefit); this.staticText = "Target creature you control deals damage equal to its power to each other creature and each opponent"; } - + public ChandrasIgnitionEffect(final ChandrasIgnitionEffect effect) { super(effect); } - + @Override public ChandrasIgnitionEffect copy() { return new ChandrasIgnitionEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (targetCreature != null && targetCreature.getPower().getValue() > 0) { for (Permanent creature : game.getState().getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) { if (!creature.getId().equals(targetCreature.getId())) { - creature.damage(targetCreature.getPower().getValue(), source.getSourceId(), game, false, true); + creature.damage(targetCreature.getPower().getValue(), targetCreature.getId(), game, false, true); } } for(UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); if (opponent != null) { - opponent.damage(targetCreature.getPower().getValue(), source.getSourceId(), game, false, true); + opponent.damage(targetCreature.getPower().getValue(), targetCreature.getId(), game, false, true); } } } diff --git a/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java b/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java new file mode 100644 index 00000000000..db3331a17ff --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class ConsecratedByBlood extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("two other creatures"); + + static { + filter.add(new AnotherPredicate()); + } + + public ConsecratedByBlood(UUID ownerId) { + super(ownerId, 87, "Consecrated By Blood", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature gets +2/+2 and has flying and "Sacrifice two other creatures: Regenerate this creature." + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA); + effect.setText("and has flying"); + ability.addEffect(effect); + effect = new GainAbilityAttachedEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), + new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, true))), AttachmentType.AURA); + effect.setText("and \"Sacrifice two other creatures: Regenerate this creature.\""); + ability.addEffect(effect); + this.addAbility(ability); + } + + public ConsecratedByBlood(final ConsecratedByBlood card) { + super(card); + } + + @Override + public ConsecratedByBlood copy() { + return new ConsecratedByBlood(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ConsulsLieutenant.java b/Mage.Sets/src/mage/sets/magicorigins/ConsulsLieutenant.java new file mode 100644 index 00000000000..0359438bf99 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ConsulsLieutenant.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.RenownedSourceCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterAttackingCreature; + +/** + * + * @author LevelX2 + */ +public class ConsulsLieutenant extends CardImpl { + + public ConsulsLieutenant(UUID ownerId) { + super(ownerId, 11, "Consul's Lieutenant", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{W}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + // Renown 1 + this.addAbility(new RenownAbility(1)); + // Whenever Consul's Lieutenant attacks, if it's renowned, other attacking creatures you control get +1/+1 until end of turn. + this.addAbility(new ConditionalTriggeredAbility(new AttacksTriggeredAbility( + new BoostControlledEffect(1, 1, Duration.EndOfTurn, new FilterAttackingCreature("other attacking creatures you control"), true), false), + RenownedSourceCondition.getInstance(), + "Whenever Consul's Lieutenant attacks, if it's renowned, other attacking creatures you control get +1/+1 until end of turn.")); + + } + + public ConsulsLieutenant(final ConsulsLieutenant card) { + super(card); + } + + @Override + public ConsulsLieutenant copy() { + return new ConsulsLieutenant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/CruelRevival.java b/Mage.Sets/src/mage/sets/magicorigins/CruelRevival.java index 92d0760bf83..3c800688d73 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/CruelRevival.java +++ b/Mage.Sets/src/mage/sets/magicorigins/CruelRevival.java @@ -28,6 +28,7 @@ package mage.sets.magicorigins; import java.util.UUID; +import mage.constants.Rarity; /** * @@ -37,6 +38,7 @@ public class CruelRevival extends mage.sets.onslaught.CruelRevival { public CruelRevival(UUID ownerId) { super(ownerId); + this.rarity = Rarity.UNCOMMON; this.cardNumber = 88; this.expansionSetCode = "ORI"; } diff --git a/Mage.Sets/src/mage/sets/magicorigins/DarkDabbling.java b/Mage.Sets/src/mage/sets/magicorigins/DarkDabbling.java new file mode 100644 index 00000000000..26e92e1593a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/DarkDabbling.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.RegenerateTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class DarkDabbling extends CardImpl { + + public DarkDabbling(UUID ownerId) { + super(ownerId, 89, "Dark Dabbling", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{B}"); + this.expansionSetCode = "ORI"; + + // Regenerate target creature. Draw a card. + this.getSpellAbility().addEffect(new RegenerateTargetEffect()); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, also regenerate each other creature you control. + this.getSpellAbility().addEffect(new DarkDabblingEffect()); + } + + public DarkDabbling(final DarkDabbling card) { + super(card); + } + + @Override + public DarkDabbling copy() { + return new DarkDabbling(this); + } +} + +class DarkDabblingEffect extends OneShotEffect { + + public DarkDabblingEffect() { + super(Outcome.Benefit); + this.staticText = "Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, also regenerate each other creature you control"; + } + + public DarkDabblingEffect(final DarkDabblingEffect effect) { + super(effect); + } + + @Override + public DarkDabblingEffect copy() { + return new DarkDabblingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (SpellMasteryCondition.getInstance().apply(game, source)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { + if (!permanent.getId().equals(getTargetPointer().getFirst(game, source))) { + RegenerateTargetEffect regenEffect = new RegenerateTargetEffect(); + regenEffect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(regenEffect, source); + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/DeepSeaTerror.java b/Mage.Sets/src/mage/sets/magicorigins/DeepSeaTerror.java new file mode 100644 index 00000000000..de8288f3431 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/DeepSeaTerror.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalRestrictionEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class DeepSeaTerror extends CardImpl { + + public DeepSeaTerror(UUID ownerId) { + super(ownerId, 52, "Deep-Sea Terror", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Serpent"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Deep-Sea Terror can't attack unless there are seven or more cards in your graveyard. + Effect effect = new ConditionalRestrictionEffect( + new CantAttackAnyPlayerSourceEffect(Duration.WhileOnBattlefield), + new InvertCondition(new CardsInControllerGraveCondition(7))); + effect.setText("{this} can't attack unless there are seven or more cards in your graveyard"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + + } + + public DeepSeaTerror(final DeepSeaTerror card) { + super(card); + } + + @Override + public DeepSeaTerror copy() { + return new DeepSeaTerror(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/EmbermawHellion.java b/Mage.Sets/src/mage/sets/magicorigins/EmbermawHellion.java new file mode 100644 index 00000000000..5632b9cfcf4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/EmbermawHellion.java @@ -0,0 +1,125 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.GameEvent; + +/** + * + * @author LoneFox + + */ +public class EmbermawHellion extends CardImpl { + + public EmbermawHellion(UUID ownerId) { + super(ownerId, 141, "Embermaw Hellion", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Hellion"); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // If another red source you control would deal damage to a permanent or player, it deals that much damage plus 1 to that permanent or player instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmbermawHellionEffect())); + } + + public EmbermawHellion(final EmbermawHellion card) { + super(card); + } + + @Override + public EmbermawHellion copy() { + return new EmbermawHellion(this); + } +} + +class EmbermawHellionEffect extends ReplacementEffectImpl { + + EmbermawHellionEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "If another red source you control would deal damage to a permanent or player, it deals that much damage plus 1 to that permanent or player instead."; + } + + EmbermawHellionEffect(final EmbermawHellionEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + switch(event.getType()) { + case DAMAGE_CREATURE: + case DAMAGE_PLANESWALKER: + case DAMAGE_PLAYER: + return true; + default: + return false; + } + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if(source.getControllerId().equals(game.getControllerId(event.getSourceId()))) { + Card card = game.getCard(event.getSourceId()); + return card != null && card.getColor(game).isRed() && !card.getId().equals(source.getSourceId()); + } + return false; + } + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(event.getAmount() + 1); + return false; + } + + @Override + public EmbermawHellionEffect copy() { + return new EmbermawHellionEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/EnlightenedAscetic.java b/Mage.Sets/src/mage/sets/magicorigins/EnlightenedAscetic.java new file mode 100644 index 00000000000..a2e31a2e755 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/EnlightenedAscetic.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author Wehk + */ +public class EnlightenedAscetic extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("enchantment"); + + static { + filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); + } + + public EnlightenedAscetic(UUID ownerId) { + super(ownerId, 12, "Enlightened Ascetic", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Cat"); + this.subtype.add("Monk"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Enlightened Ascetic enters the battlefield, you may destroy target enchantment. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), true); + Target target = new TargetPermanent(filter); + ability.addTarget(target); + this.addAbility(ability); + } + + public EnlightenedAscetic(final EnlightenedAscetic card) { + super(card); + } + + @Override + public EnlightenedAscetic copy() { + return new EnlightenedAscetic(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java b/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java index 9c81ff6e17d..f85197d29d8 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java +++ b/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java @@ -28,12 +28,12 @@ package mage.sets.magicorigins; import java.util.UUID; -import mage.abilities.condition.common.RenownCondition; +import mage.abilities.condition.common.RenownedTargetCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.PreventDamageToTargetEffect; -import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -56,12 +56,11 @@ public class EnshroudingMist extends CardImpl { Effect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE); effect.setText("Prevent all damage that would dealt to it this turn"); this.getSpellAbility().addEffect(effect); - OneShotEffect effect2 = new UntapSourceEffect(); + OneShotEffect effect2 = new UntapTargetEffect(); effect2.setText("untap it"); - this.getSpellAbility().addEffect(new ConditionalOneShotEffect(effect2, RenownCondition.getInstance())); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(effect2, RenownedTargetCondition.getInstance())); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - - + } public EnshroudingMist(final EnshroudingMist card) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/ErebossTitan.java b/Mage.Sets/src/mage/sets/magicorigins/ErebossTitan.java index 6d4d632fc99..a8b4940e0af 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ErebossTitan.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ErebossTitan.java @@ -74,7 +74,7 @@ public class ErebossTitan extends CardImpl { // Erebos's Titan has indestructible as long as no opponent controls a creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield), - new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 0), + new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.EQUAL_TO, 0, false), "As long as your opponents control no creatures, {this} has indestructible"))); // Whenever a creature leaves an opponent's graveyard, you may discard a card. If you do, return Erebos's Titan from your graveyard to your hand. @@ -95,7 +95,7 @@ public class ErebossTitan extends CardImpl { class ErebossTitanTriggeredAbility extends TriggeredAbilityImpl { public ErebossTitanTriggeredAbility() { - super(Zone.BATTLEFIELD, new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new DiscardCardCost())); + super(Zone.GRAVEYARD, new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new DiscardCardCost())); } public ErebossTitanTriggeredAbility(final ErebossTitanTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/EyeblightMassacre.java b/Mage.Sets/src/mage/sets/magicorigins/EyeblightMassacre.java new file mode 100644 index 00000000000..66e10dee682 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/EyeblightMassacre.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + + */ +public class EyeblightMassacre extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Non-Elf creatures"); + + static { + filter.add(Predicates.not(new SubtypePredicate("Elf"))); + } + + public EyeblightMassacre(UUID ownerId) { + super(ownerId, 96, "Eyeblight Massacre", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); + this.expansionSetCode = "ORI"; + + // Non-Elf creatures get -2/-2 until end of turn. + this.getSpellAbility().addEffect(new BoostAllEffect(-2, -2, Duration.EndOfTurn, filter, false)); + } + + public EyeblightMassacre(final EyeblightMassacre card) { + super(card); + } + + @Override + public EyeblightMassacre copy() { + return new EyeblightMassacre(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/FetidImp.java b/Mage.Sets/src/mage/sets/magicorigins/FetidImp.java new file mode 100644 index 00000000000..8e7701c598d --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/FetidImp.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class FetidImp extends CardImpl { + + public FetidImp(UUID ownerId) { + super(ownerId, 97, "Fetid Imp", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Imp"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // {B}: Fetid Imp gains deathtouch until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{B}"))); + } + + public FetidImp(final FetidImp card) { + super(card); + } + + @Override + public FetidImp copy() { + return new FetidImp(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/FoundryOfTheConsuls.java b/Mage.Sets/src/mage/sets/magicorigins/FoundryOfTheConsuls.java new file mode 100644 index 00000000000..954e9edf44c --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/FoundryOfTheConsuls.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.ThopterColorlessToken; + +/** + * + * @author LoneFox + + */ +public class FoundryOfTheConsuls extends CardImpl { + + public FoundryOfTheConsuls(UUID ownerId) { + super(ownerId, 247, "Foundry of the Consuls", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "ORI"; + + // {T}: Add {1} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + // {5}, {T}, Sacrifice Foundry of the Consuls: Put two 1/1 colorless Thopter artifact creature tokens with flying onto the battlefield. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new ThopterColorlessToken("ORI"), 2), + new ManaCostsImpl("{5}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + public FoundryOfTheConsuls(final FoundryOfTheConsuls card) { + super(card); + } + + @Override + public FoundryOfTheConsuls copy() { + return new FoundryOfTheConsuls(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/GatherThePack.java b/Mage.Sets/src/mage/sets/magicorigins/GatherThePack.java new file mode 100644 index 00000000000..31888fd17a7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/GatherThePack.java @@ -0,0 +1,119 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; + +/** + * + * @author LevelX2 + */ +public class GatherThePack extends CardImpl { + + public GatherThePack(UUID ownerId) { + super(ownerId, 178, "Gather the Pack", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{1}{G}"); + this.expansionSetCode = "ORI"; + + // Reveal the top five cards of your library. You may put a creature card from among them into your hand. Put the rest into your graveyard. + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, put up to two creature cards from among the revealed cards into your hand instead of one. + this.getSpellAbility().addEffect(new GatherThePackEffect()); + } + + public GatherThePack(final GatherThePack card) { + super(card); + } + + @Override + public GatherThePack copy() { + return new GatherThePack(this); + } +} + +class GatherThePackEffect extends OneShotEffect { + + public GatherThePackEffect(final GatherThePackEffect effect) { + super(effect); + } + + public GatherThePackEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Reveal the top five cards of your library. You may put a creature card from among them into your hand. Put the rest into your graveyard." + + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, put up to two creature cards from among the revealed cards into your hand instead of one"; + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Cards cards = new CardsImpl(Zone.LIBRARY); + cards.addAll(controller.getLibrary().getTopCards(game, 5)); + if (!cards.isEmpty()) { + int creatures = cards.count(new FilterCreatureCard(), source.getSourceId(), source.getControllerId(), game); + if (creatures > 0) { + int max = 1; + if (SpellMasteryCondition.getInstance().apply(game, source) && creatures > 1) { + max++; + } + TargetCard target = new TargetCard(0, max, Zone.LIBRARY, new FilterCreatureCard("creature card" + (max > 1 ? "s" : "") + " to put into your hand")); + if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) { + Card card = cards.get(target.getFirstTarget(), game); + if (card != null) { + cards.remove(card); + controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game); + } + } + } + if (cards.size() > 0) { + controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + } + } + return true; + } + + @Override + public GatherThePackEffect copy() { + return new GatherThePackEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/GhirapurAEtherGrid.java b/Mage.Sets/src/mage/sets/magicorigins/GhirapurAEtherGrid.java new file mode 100644 index 00000000000..95138ec2cc1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/GhirapurAEtherGrid.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +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.common.TargetCreatureOrPlayer; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author Wehk + */ +public class GhirapurAEtherGrid extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped artifacts you control"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + filter.add(Predicates.not(new TappedPredicate())); + } + + public GhirapurAEtherGrid(UUID ownerId) { + super(ownerId, 148, "Ghirapur AEther Grid", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + this.expansionSetCode = "ORI"; + + // Tap two untaped artifacts you control: Ghirapur Aether Grid deals 1 damage to target creature or player + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DamageTargetEffect(1), + new TapTargetCost(new TargetControlledPermanent(2, 2, filter, true))); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public GhirapurAEtherGrid(final GhirapurAEtherGrid card) { + super(card); + } + + @Override + public GhirapurAEtherGrid copy() { + return new GhirapurAEtherGrid(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/GoblinGloryChaser.java b/Mage.Sets/src/mage/sets/magicorigins/GoblinGloryChaser.java index b05ba2784c5..c5a5ae8e4ce 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/GoblinGloryChaser.java +++ b/Mage.Sets/src/mage/sets/magicorigins/GoblinGloryChaser.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.RenownCondition; +import mage.abilities.condition.common.RenownedSourceCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; @@ -59,14 +59,14 @@ public class GoblinGloryChaser extends CardImpl { // Renown 1 this.addAbility(new RenownAbility(1)); - + // As long as Goblin Glory Chaser is renowned, it has menace. Effect effect = new ConditionalContinuousEffect( - new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), - RenownCondition.getInstance(), + new GainAbilitySourceEffect(new MenaceAbility(), Duration.WhileOnBattlefield), + RenownedSourceCondition.getInstance(), "As long as {this} is renowned, it has menace"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); - this.addAbility(ability); + this.addAbility(ability); } public GoblinGloryChaser(final GoblinGloryChaser card) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/GuardianAutomaton.java b/Mage.Sets/src/mage/sets/magicorigins/GuardianAutomaton.java new file mode 100644 index 00000000000..3e66bafc19f --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/GuardianAutomaton.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; + +/** + * + * @author LoneFox + + */ +public class GuardianAutomaton extends CardImpl { + + public GuardianAutomaton(UUID ownerId) { + super(ownerId, 227, "Guardian Automaton", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Construct"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Guardian Automaton dies, you gain 3 life. + this.addAbility(new DiesTriggeredAbility(new GainLifeEffect(3))); + } + + public GuardianAutomaton(final GuardianAutomaton card) { + super(card); + } + + @Override + public GuardianAutomaton copy() { + return new GuardianAutomaton(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java new file mode 100644 index 00000000000..1c2589ac464 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.players.Player; +import mage.watchers.common.CreatureWasCastWatcher; + +/** + * + * @author LevelX2 + */ +public class HallowedMoonlight extends CardImpl { + + public HallowedMoonlight(UUID ownerId) { + super(ownerId, 16, "Hallowed Moonlight", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{W}"); + this.expansionSetCode = "ORI"; + + // Until end of turn, if a creature would enter the battlefield and it wasn't cast, exile it instead. + this.getSpellAbility().addEffect(new HallowedMoonlightEffect()); + this.getSpellAbility().addWatcher(new CreatureWasCastWatcher()); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public HallowedMoonlight(final HallowedMoonlight card) { + super(card); + } + + @Override + public HallowedMoonlight copy() { + return new HallowedMoonlight(this); + } +} + +class HallowedMoonlightEffect extends ReplacementEffectImpl { + + public HallowedMoonlightEffect() { + super(Duration.EndOfTurn, Outcome.Exile); + staticText = "Until end of turn, if a creature would enter the battlefield and it wasn't cast, exile it instead"; + } + + public HallowedMoonlightEffect(final HallowedMoonlightEffect effect) { + super(effect); + } + + @Override + public HallowedMoonlightEffect copy() { + return new HallowedMoonlightEffect(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()); + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (controller != null) { + Card card = game.getCard(event.getTargetId()); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, zEvent.getFromZone(), true); + } + return true; + + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE || event.getType() == GameEvent.EventType.CREATE_TOKEN; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.CREATE_TOKEN) { + // TODO: not clear how to check for creature type + // Tokens: Even though you’re probably casting a spell that makes tokens (Lingering Souls, Raise the Alarm, etc), + // the tokens themselves are not cast. As such, Hallowed Moonlight will stop ANY kind of creature tokens + // from entering the battlefield. + return true; + } + if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { + Card card = game.getCard(event.getTargetId()); + if (card != null && card.getCardType().contains(CardType.CREATURE)) { + // TODO: Bestow Card cast as Enchantment probably not handled correctly + CreatureWasCastWatcher watcher = (CreatureWasCastWatcher) game.getState().getWatchers().get("CreatureWasCast"); + if (watcher != null && !watcher.wasCreatureCastThisTurn(event.getTargetId())) { + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/HarbingerOfTheTides.java b/Mage.Sets/src/mage/sets/magicorigins/HarbingerOfTheTides.java new file mode 100644 index 00000000000..54048591d95 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/HarbingerOfTheTides.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class HarbingerOfTheTides extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature an opponent controls"); + + static { + filter.add(new TappedPredicate()); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public HarbingerOfTheTides(UUID ownerId) { + super(ownerId, 58, "Harbinger of the Tides", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{U}{U}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Merfolk"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // You may cast Harbinger of the Tides as though it had flash if you pay {2} more to cast it. + this.addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl<>("{2}"))); + + // When Harbinger of the Tides enters the battlefield, you may return target tapped creature an opponent controls to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + } + + public HarbingerOfTheTides(final HarbingerOfTheTides card) { + super(card); + } + + @Override + public HarbingerOfTheTides copy() { + return new HarbingerOfTheTides(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/HealingHands.java b/Mage.Sets/src/mage/sets/magicorigins/HealingHands.java new file mode 100644 index 00000000000..6fb1d99ddf5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/HealingHands.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetPlayer; + +/** + * + * @author Wehk + */ +public class HealingHands extends CardImpl { + + public HealingHands(UUID ownerId) { + super(ownerId, 17, "Healing Hands", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{W}"); + this.expansionSetCode = "ORI"; + + // Target player gains 4 life. + this.getSpellAbility().addEffect(new GainLifeTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetPlayer()); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public HealingHands(final HealingHands card) { + super(card); + } + + @Override + public HealingHands copy() { + return new HealingHands(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java b/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java index d09a2fb9e63..0661baef1d0 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java +++ b/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.RenownCondition; +import mage.abilities.condition.common.RenownedSourceCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; @@ -64,12 +64,12 @@ public class HonoredHierarch extends CardImpl { // As long as Honored Hierarch is renowned, it has vigilance and "{T}: Add one mana of any color to your mana pool." Effect effect = new ConditionalContinuousEffect( new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield), - RenownCondition.getInstance(), + RenownedSourceCondition.getInstance(), "As long as {this} is renown, it has vigilance"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); effect = new ConditionalContinuousEffect( new GainAbilitySourceEffect(new AnyColorManaAbility(), Duration.WhileOnBattlefield), - RenownCondition.getInstance(), + RenownedSourceCondition.getInstance(), "and \"{T}: Add one mana of any color to your mana pool.\""); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/magicorigins/InfectiousBloodlust.java b/Mage.Sets/src/mage/sets/magicorigins/InfectiousBloodlust.java index 56631e05d85..219311c74be 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/InfectiousBloodlust.java +++ b/Mage.Sets/src/mage/sets/magicorigins/InfectiousBloodlust.java @@ -29,11 +29,11 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.AttacksEachTurnStaticAbility; import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; @@ -42,6 +42,7 @@ import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.constants.AttachmentType; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; @@ -56,7 +57,7 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class InfectiousBloodlust extends CardImpl { - + private static final FilterCard filter = new FilterCard("card named Infectious Bloodlust"); static { @@ -74,7 +75,7 @@ public class InfectiousBloodlust extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature gets +2/+1, has haste, and attacks each turn if able. Effect effect = new BoostEnchantedEffect(2, 1); effect.setText("Enchanted creature gets +2/+1"); @@ -82,11 +83,12 @@ public class InfectiousBloodlust extends CardImpl { effect = new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA); effect.setText("has haste"); ability.addEffect(effect); - effect = new GainAbilityAttachedEffect(new AttacksEachTurnStaticAbility(), AttachmentType.AURA); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + effect = new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA); effect.setText("and attacks each turn if able"); ability.addEffect(effect); this.addAbility(ability); - + // When enchanted creature dies, you may search your library for a card named Infectious Bloodlust, reveal it, put it into your hand, then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); this.addAbility(new DiesAttachedTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), "enchanted creature", true)); diff --git a/Mage.Sets/src/mage/sets/magicorigins/JoragaInvocation.java b/Mage.Sets/src/mage/sets/magicorigins/JoragaInvocation.java new file mode 100644 index 00000000000..b5277621db7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/JoragaInvocation.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class JoragaInvocation extends CardImpl { + + public JoragaInvocation(UUID ownerId) { + super(ownerId, 183, "Joraga Invocation", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{4}{G}{G}"); + this.expansionSetCode = "ORI"; + + // Each creature you control gets +3/+3 until end of turn and must be blocked this turn if able. + this.getSpellAbility().addEffect(new BoostControlledEffect(3, 3, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new JoragaInvocationEffect()); + + } + + public JoragaInvocation(final JoragaInvocation card) { + super(card); + } + + @Override + public JoragaInvocation copy() { + return new JoragaInvocation(this); + } +} + +class JoragaInvocationEffect extends OneShotEffect { + + public JoragaInvocationEffect() { + super(Outcome.Detriment); + this.staticText = "and must be blocked this turn if able"; + } + + public JoragaInvocationEffect(final JoragaInvocationEffect effect) { + super(effect); + } + + @Override + public JoragaInvocationEffect copy() { + return new JoragaInvocationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game)) { + ContinuousEffect effect = new MustBeBlockedByAtLeastOneTargetEffect(); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/KytheonsIrregulars.java b/Mage.Sets/src/mage/sets/magicorigins/KytheonsIrregulars.java index cb9133fa199..7a33f22e3cd 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/KytheonsIrregulars.java +++ b/Mage.Sets/src/mage/sets/magicorigins/KytheonsIrregulars.java @@ -50,7 +50,7 @@ public class KytheonsIrregulars extends CardImpl { super(ownerId, 24, "Kytheon's Irregulars", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.expansionSetCode = "ORI"; this.subtype.add("Human"); - this.subtype.add("Solder"); + this.subtype.add("Soldier"); this.power = new MageInt(4); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/sets/magicorigins/KytheonsTactics.java b/Mage.Sets/src/mage/sets/magicorigins/KytheonsTactics.java new file mode 100644 index 00000000000..2bf1dbe507a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/KytheonsTactics.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class KytheonsTactics extends CardImpl { + + public KytheonsTactics(UUID ownerId) { + super(ownerId, 25, "Kytheon's Tactics", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{W}{W}"); + this.expansionSetCode = "ORI"; + + // Creatures you control get +2/+1 until end of turn. + this.getSpellAbility().addEffect(new BoostControlledEffect(2, 1, Duration.EndOfTurn)); + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, those creatures also gain vigilance until end of turn. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), + SpellMasteryCondition.getInstance(), + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, those creatures also gain vigilance until end of turn")); + } + + public KytheonsTactics(final KytheonsTactics card) { + super(card); + } + + @Override + public KytheonsTactics copy() { + return new KytheonsTactics(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/LilianaHereticalHealer.java b/Mage.Sets/src/mage/sets/magicorigins/LilianaHereticalHealer.java index 7d7a1ee93f1..a3a6bc156b0 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/LilianaHereticalHealer.java +++ b/Mage.Sets/src/mage/sets/magicorigins/LilianaHereticalHealer.java @@ -30,6 +30,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileAndReturnTransformedSourceEffect; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.TransformAbility; @@ -42,6 +43,7 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.ZombieToken; /** * @@ -74,7 +76,8 @@ public class LilianaHereticalHealer extends CardImpl { this.addAbility(LifelinkAbility.getInstance()); // Whenever another nontoken creature you control dies, exile Liliana Heretical Healer, then return her to the battlefield transformed under her owner's control. If you do, put a 2/2 black Zombie creature token onto the battlefield. - this.addAbility(new DiesCreatureTriggeredAbility(new ExileAndReturnTransformedSourceEffect(ExileAndReturnTransformedSourceEffect.Gender.FEMAL), false, filter)); + this.addAbility(new DiesCreatureTriggeredAbility(new ExileAndReturnTransformedSourceEffect(ExileAndReturnTransformedSourceEffect.Gender.FEMAL, + new CreateTokenEffect(new ZombieToken(expansionSetCode))), false, filter)); } public LilianaHereticalHealer(final LilianaHereticalHealer card) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/MacabreWaltz.java b/Mage.Sets/src/mage/sets/magicorigins/MacabreWaltz.java new file mode 100644 index 00000000000..5030b5290a8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/MacabreWaltz.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + + +import java.util.UUID; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LoneFox + + */ +public class MacabreWaltz extends CardImpl { + + public MacabreWaltz(UUID ownerId) { + super(ownerId, 107, "Macabre Waltz", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); + this.expansionSetCode = "ORI"; + + // Return up to two target creature cards from your graveyard to your hand, then discard a card. + this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 2, new FilterCreatureCard("creature cards from your graveyard"))); + this.getSpellAbility().addEffect(new DiscardControllerEffect(1)); + } + + public MacabreWaltz(final MacabreWaltz card) { + super(card); + } + + @Override + public MacabreWaltz copy() { + return new MacabreWaltz(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/MageRingBully.java b/Mage.Sets/src/mage/sets/magicorigins/MageRingBully.java new file mode 100644 index 00000000000..98d8baf3898 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/MageRingBully.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksEachTurnStaticAbility; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author Wehk + */ +public class MageRingBully extends CardImpl { + + public MageRingBully(UUID ownerId) { + super(ownerId, 154, "Mage-Ring Bully", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Warrior"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Prowess + this.addAbility(new ProwessAbility()); + + // Mage-Ring Bully attacks each turn if able. + this.addAbility(new AttacksEachTurnStaticAbility()); + } + + public MageRingBully(final MageRingBully card) { + super(card); + } + + @Override + public MageRingBully copy() { + return new MageRingBully(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java b/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java new file mode 100644 index 00000000000..6ee273ea26e --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.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.sets.magicorigins; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveVariableCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.DynamicManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author LoneFox + + */ +public class MageRingNetwork extends CardImpl { + + public MageRingNetwork(UUID ownerId) { + super(ownerId, 249, "Mage-Ring Network", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "ORI"; + + // {t}: Add {1} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + // {1}, {t}: Put a storage counter on Mage-Ring Network. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()), + new ManaCostsImpl("{1}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + // {t}, Remove X storage counters from Mage-Ring Network: Add {x} to your mana pool. + ability = new DynamicManaAbility(Mana.ColorlessMana, new RemovedCountersForCostValue(), "Add {X} to your mana pool"); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), + "Remove X storage counters from {this}")); + this.addAbility(ability); + } + + public MageRingNetwork(final MageRingNetwork card) { + super(card); + } + + @Override + public MageRingNetwork copy() { + return new MageRingNetwork(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/NecromanticSummons.java b/Mage.Sets/src/mage/sets/magicorigins/NecromanticSummons.java index 1028d2e87a3..b8bcb491aa1 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/NecromanticSummons.java +++ b/Mage.Sets/src/mage/sets/magicorigins/NecromanticSummons.java @@ -42,7 +42,7 @@ import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCardInGraveyard; /** * @@ -56,7 +56,7 @@ public class NecromanticSummons extends CardImpl { // Put target creature card from a graveyard onto the battlefield under your control. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); + this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard"))); // Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, that creature enters the battlefield with two additional +1/+1 counters on it. Effect effect = new ConditionalOneShotEffect(new NecromanticSummoningEffect(), diff --git a/Mage.Sets/src/mage/sets/magicorigins/Nightsnare.java b/Mage.Sets/src/mage/sets/magicorigins/Nightsnare.java new file mode 100644 index 00000000000..6c728ad2ad6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/Nightsnare.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class Nightsnare extends CardImpl { + + public Nightsnare(UUID ownerId) { + super(ownerId, 111, "Nightsnare", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{B}"); + this.expansionSetCode = "ORI"; + + // Target opponent reveals his or her hand. You may choose a nonland card from it. If you do, that player discards that card. If you don't, that player discards two cards. + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new NightsnareDiscardEffect()); + } + + public Nightsnare(final Nightsnare card) { + super(card); + } + + @Override + public Nightsnare copy() { + return new Nightsnare(this); + } +} + +class NightsnareDiscardEffect extends OneShotEffect { + + public NightsnareDiscardEffect() { + super(Outcome.Discard); + staticText = "Target opponent reveals his or her hand. You may choose a nonland card from it. If you do, that player discards that card. If you don't, that player discards two cards"; + } + + public NightsnareDiscardEffect(final NightsnareDiscardEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (player != null && controller != null) { + if (!player.getHand().isEmpty()) { + Cards revealedCards = new CardsImpl(Zone.HAND); + revealedCards.addAll(player.getHand()); + player.revealCards(sourceCard != null ? sourceCard.getIdName() : "Discard", revealedCards, game); + // You may choose a nonland card from it. + if (controller.chooseUse(outcome, "Choose a a card to discard? (Otherwise " + player.getLogName() + " has to discard 2 cards).", source, game)) { + TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard()); + if (controller.choose(Outcome.Benefit, revealedCards, target, game)) { + for (Object targetId : target.getTargets()) { + Card card = revealedCards.get((UUID) targetId, game); + if (card != null) { + player.discard(card, source, game); + } + } + } + + } else { + player.discard(2, false, source, game); + } + } + return true; + + } + return false; + + } + + @Override + public NightsnareDiscardEffect copy() { + return new NightsnareDiscardEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java b/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java new file mode 100644 index 00000000000..7fd632cb301 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java @@ -0,0 +1,125 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterBasicLandCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LevelX2 + */ +public class NissasPilgrimage extends CardImpl { + + public NissasPilgrimage(UUID ownerId) { + super(ownerId, 190, "Nissa's Pilgrimage", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{G}"); + this.expansionSetCode = "ORI"; + + // Search your library for up to two basic Forest cards, reveal those cards, and put one onto the battlefield tapped and the rest into your hand. Then shuffle your library. + // Spell Mastery — If there are two or more instant and/or sorcery cards in your graveyard, search your library for up to three basic Forest cards instead of two. + this.getSpellAbility().addEffect(new NissasPilgrimageEffect()); + } + + public NissasPilgrimage(final NissasPilgrimage card) { + super(card); + } + + @Override + public NissasPilgrimage copy() { + return new NissasPilgrimage(this); + } +} + +class NissasPilgrimageEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterBasicLandCard("basic Forest"); + + static { + filter.add(new SubtypePredicate("Forest")); + } + + public NissasPilgrimageEffect() { + super(Outcome.Benefit); + this.staticText = "Search your library for up to two basic Forest cards, reveal those cards, and put one onto the battlefield tapped and the rest into your hand. Then shuffle your library." + + "
Spell Mastery — If there are two or more instant and/or sorcery cards in your graveyard, search your library for up to three basic Forest cards instead of two."; + } + + public NissasPilgrimageEffect(final NissasPilgrimageEffect effect) { + super(effect); + } + + @Override + public NissasPilgrimageEffect copy() { + return new NissasPilgrimageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + int number = 2; + if (SpellMasteryCondition.getInstance().apply(game, source)) { + number++; + } + TargetCardInLibrary target = new TargetCardInLibrary(0, number, filter); + controller.searchLibrary(target, game); + if (!target.getTargets().isEmpty()) { + Cards cards = new CardsImpl(target.getTargets()); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (!cards.isEmpty()) { + Card card = cards.getRandom(game); + if (card != null) { + cards.remove(card); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(cards, Zone.LIBRARY, Zone.HAND, source, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissasRevelation.java b/Mage.Sets/src/mage/sets/magicorigins/NissasRevelation.java new file mode 100644 index 00000000000..975e1d8fbd8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/NissasRevelation.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class NissasRevelation extends CardImpl { + + public NissasRevelation(UUID ownerId) { + super(ownerId, 191, "Nissa's Revelation", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{G}{G}"); + this.expansionSetCode = "ORI"; + + // Scry 5, then reveal the top card of your library. If it's a creature card, you draw cards equal to its power and you gain life equal to its toughness. + this.getSpellAbility().addEffect(new ScryEffect(5)); + this.getSpellAbility().addEffect(new NissasRevelationEffect()); + + } + + public NissasRevelation(final NissasRevelation card) { + super(card); + } + + @Override + public NissasRevelation copy() { + return new NissasRevelation(this); + } +} + +class NissasRevelationEffect extends OneShotEffect { + + public NissasRevelationEffect() { + super(Outcome.DrawCard); + this.staticText = ", then reveal the top card of your library. If it's a creature card, you draw cards equal to its power and you gain life equal to its toughness"; + } + + public NissasRevelationEffect(final NissasRevelationEffect effect) { + super(effect); + } + + @Override + public NissasRevelationEffect copy() { + return new NissasRevelationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(); + Card card = controller.getLibrary().getFromTop(game); + + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.getCardType().contains(CardType.CREATURE)) { + controller.drawCards(card.getPower().getValue(), game); + controller.gainLife(card.getToughness().getValue(), game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/NivixBarrier.java b/Mage.Sets/src/mage/sets/magicorigins/NivixBarrier.java new file mode 100644 index 00000000000..7a3487f855b --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/NivixBarrier.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetAttackingCreature; + +/** + * + * @author LevelX2 + */ +public class NivixBarrier extends CardImpl { + + public NivixBarrier(UUID ownerId) { + super(ownerId, 66, "Nivix Barrier", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Illusion"); + this.subtype.add("Wall"); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Flash + this.addAbility(FlashAbility.getInstance()); + // Defender + this.addAbility(DefenderAbility.getInstance()); + // When Nivix Barrier enters the battlefield, target attacking creature gets -4/-0 until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-4, 0, Duration.EndOfTurn), false); + ability.addTarget(new TargetAttackingCreature()); + this.addAbility(ability); + } + + public NivixBarrier(final NivixBarrier card) { + super(card); + } + + @Override + public NivixBarrier copy() { + return new NivixBarrier(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/OrbsOfWarding.java b/Mage.Sets/src/mage/sets/magicorigins/OrbsOfWarding.java new file mode 100644 index 00000000000..a244007d356 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/OrbsOfWarding.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.continuous.GainAbilityControllerEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class OrbsOfWarding extends CardImpl { + + public OrbsOfWarding(UUID ownerId) { + super(ownerId, 234, "Orbs of Warding", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{5}"); + this.expansionSetCode = "ORI"; + + // You have hexproof. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControllerEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield))); + + // If a creature would deal damage to you, prevent 1 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OrbsOfWardingEffect())); + } + + public OrbsOfWarding(final OrbsOfWarding card) { + super(card); + } + + @Override + public OrbsOfWarding copy() { + return new OrbsOfWarding(this); + } +} + +class OrbsOfWardingEffect extends PreventionEffectImpl { + + public OrbsOfWardingEffect() { + super(Duration.WhileOnBattlefield, 1, false, false); + this.staticText = "If a creature would deal damage to you, prevent 1 of that damage"; + } + + public OrbsOfWardingEffect(OrbsOfWardingEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType().equals(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.getCardType().contains(CardType.CREATURE)) { + return super.applies(event, source, game); + } + } + return false; + } + + @Override + public OrbsOfWardingEffect copy() { + return new OrbsOfWardingEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/PossessedSkaab.java b/Mage.Sets/src/mage/sets/magicorigins/PossessedSkaab.java new file mode 100644 index 00000000000..0bfd93d22f8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/PossessedSkaab.java @@ -0,0 +1,135 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +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.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class PossessedSkaab extends CardImpl { + + private static final FilterCard filter = new FilterCard("instant, sorcery, or creature card from your graveyard"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY), + new CardTypePredicate(CardType.CREATURE))); + } + + public PossessedSkaab(UUID ownerId) { + super(ownerId, 215, "Possessed Skaab", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Zombie"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Possessed Skaab enters the battlefield, return target instant, sorcery, or creature card from your graveyard to your hand. + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + + // If Possessed Skaab would die, exile it instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PossessedSkaabDiesEffect())); + } + + public PossessedSkaab(final PossessedSkaab card) { + super(card); + } + + @Override + public PossessedSkaab copy() { + return new PossessedSkaab(this); + } +} + +class PossessedSkaabDiesEffect extends ReplacementEffectImpl { + + public PossessedSkaabDiesEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + staticText = "If {this} would die, exile it instead"; + } + + public PossessedSkaabDiesEffect(final PossessedSkaabDiesEffect effect) { + super(effect); + } + + @Override + public PossessedSkaabDiesEffect copy() { + return new PossessedSkaabDiesEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent permanent = ((ZoneChangeEvent) event).getTarget(); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && permanent != null) { + return controller.moveCardToExileWithInfo(permanent, null, null, source.getSourceId(), game, Zone.BATTLEFIELD, true); + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(source.getSourceId())) { + ZoneChangeEvent zce = (ZoneChangeEvent) event; + return zce.isDiesEvent(); + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/Prickleboar.java b/Mage.Sets/src/mage/sets/magicorigins/Prickleboar.java new file mode 100644 index 00000000000..768e6f465d4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/Prickleboar.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author Wehk + */ +public class Prickleboar extends CardImpl { + + public Prickleboar(UUID ownerId) { + super(ownerId, 158, "Prickleboar", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Boar"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + /// As long as it's your turn, Prickleboar gets +2/+0 + Effect boostEffect = new ConditionalContinuousEffect( + new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield), + MyTurnCondition.getInstance(), + "As long as it's your turn, {this} gets +2/+0"); + // and has first strike. + Effect gainAbilityEffect = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield), + MyTurnCondition.getInstance(), + "and has first strike"); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, boostEffect); + ability.addEffect(gainAbilityEffect); + this.addAbility(ability); + } + + public Prickleboar(final Prickleboar card) { + super(card); + } + + @Override + public Prickleboar copy() { + return new Prickleboar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/PrismRing.java b/Mage.Sets/src/mage/sets/magicorigins/PrismRing.java new file mode 100644 index 00000000000..6433612fe56 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/PrismRing.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.sets.magicorigins; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; + +/** + * + * @author LevelX2 + */ +public class PrismRing extends CardImpl { + + public PrismRing(UUID ownerId) { + super(ownerId, 235, "Prism Ring", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "ORI"; + + // As Prism Ring enters the battlefield, choose a color. + this.addAbility(new EntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); + + // Whenever you cast a spell of the chosen color, you gain 1 life. + this.addAbility(new PrismRingTriggeredAbility()); + } + + public PrismRing(final PrismRing card) { + super(card); + } + + @Override + public PrismRing copy() { + return new PrismRing(this); + } +} + +class PrismRingTriggeredAbility extends TriggeredAbilityImpl { + + public PrismRingTriggeredAbility() { + super(Zone.BATTLEFIELD, new GainLifeEffect(1), false); + } + + public PrismRingTriggeredAbility(final PrismRingTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + ObjectColor color = (ObjectColor) game.getState().getValue(getSourceId() + "_color"); + if (spell != null && color != null && spell.getColor(game).shares(color)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cast a spell of the chosen color, you gain 1 life."; + } + + @Override + public PrismRingTriggeredAbility copy() { + return new PrismRingTriggeredAbility(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java b/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java new file mode 100644 index 00000000000..cdc1ecbfb18 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/PsychicRebuttal.java @@ -0,0 +1,157 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.filter.predicate.ObjectPlayer; +import mage.filter.predicate.ObjectPlayerPredicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetSpell; + +/** + * + * @author LevelX2 + */ +public class PsychicRebuttal extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("instant or sorcery spell that targets you"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); + filter.add(new PsychicRebuttalPredicate()); + } + + public PsychicRebuttal(UUID ownerId) { + super(ownerId, 67, "Psychic Rebuttal", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "ORI"; + + // Counter target instant or sorcery spell that targets you. + this.getSpellAbility().addEffect(new PsychicRebuttalEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may copy the spell countered this way. You may choose new targets for the copy. + } + + public PsychicRebuttal(final PsychicRebuttal card) { + super(card); + } + + @Override + public PsychicRebuttal copy() { + return new PsychicRebuttal(this); + } +} + +class PsychicRebuttalEffect extends OneShotEffect { + + public PsychicRebuttalEffect() { + super(Outcome.Benefit); + this.staticText = "Counter target instant or sorcery spell that targets you." + + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may copy the spell countered this way. You may choose new targets for the copy"; + } + + public PsychicRebuttalEffect(final PsychicRebuttalEffect effect) { + super(effect); + } + + @Override + public PsychicRebuttalEffect copy() { + return new PsychicRebuttalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + StackObject stackObject = game.getState().getStack().getStackObject(getTargetPointer().getFirst(game, source)); + if (stackObject != null) { + game.getStack().counter(stackObject.getId(), source.getSourceId(), game); + + if (SpellMasteryCondition.getInstance().apply(game, source) + && controller.chooseUse(Outcome.PlayForFree, "Copy " + stackObject.getName() + " (you may choose new targets for the copy)?", source, game)) { + + Spell copy = ((Spell) stackObject).copySpell(); + copy.setControllerId(source.getControllerId()); + copy.setCopiedSpell(true); + game.getStack().push(copy); + copy.chooseNewTargets(game, source.getControllerId()); + Player player = game.getPlayer(source.getControllerId()); + String activateMessage = copy.getActivatedMessage(game); + if (activateMessage.startsWith(" casts ")) { + activateMessage = activateMessage.substring(6); + } + game.informPlayers(player.getLogName() + activateMessage); + } + + return true; + } + return false; + } +} + +class PsychicRebuttalPredicate implements ObjectPlayerPredicate> { + + @Override + public boolean apply(ObjectPlayer input, Game game) { + UUID controllerId = input.getPlayerId(); + if (controllerId == null) { + return false; + } + for (UUID modeId : input.getObject().getStackAbility().getModes().getSelectedModes()) { + input.getObject().getStackAbility().getModes().setActiveMode(modeId); + for (Target target : input.getObject().getStackAbility().getTargets()) { + for (UUID targetId : target.getTargets()) { + if (controllerId.equals(targetId)) { + return true; + } + } + } + } + return false; + } + + @Override + public String toString() { + return "spell that targets you"; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/PyromancersGoggles.java b/Mage.Sets/src/mage/sets/magicorigins/PyromancersGoggles.java new file mode 100644 index 00000000000..f9729a180dd --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/PyromancersGoggles.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.stack.Spell; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class PyromancersGoggles extends CardImpl { + + public PyromancersGoggles(UUID ownerId) { + super(ownerId, 236, "Pyromancer's Goggles", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT}, "{5}"); + this.expansionSetCode = "ORI"; + this.supertype.add("Legendary"); + + // {T}: Add {R} to your mana pool. + Ability ability = new RedManaAbility(); + this.addAbility(ability); + + // When that mana is used to cast a red instant or sorcery spell, copy that spell and you may choose new targets for the copy. + Effect effect = new CopyTargetSpellEffect(); + effect.setText("copy that spell and you may choose new targets for the copy"); + this.addAbility(new PyromancersGogglesTriggeredAbility(ability.getOriginalId(), effect)); + + } + + public PyromancersGoggles(final PyromancersGoggles card) { + super(card); + } + + @Override + public PyromancersGoggles copy() { + return new PyromancersGoggles(this); + } +} + +class PyromancersGogglesTriggeredAbility extends TriggeredAbilityImpl { + + private final static FilterInstantOrSorcerySpell filter = new FilterInstantOrSorcerySpell(); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + String abilityOriginalId; + + public PyromancersGogglesTriggeredAbility(UUID abilityOriginalId, Effect effect) { + super(Zone.ALL, effect, true); + this.abilityOriginalId = abilityOriginalId.toString(); + } + + public PyromancersGogglesTriggeredAbility(final PyromancersGogglesTriggeredAbility ability) { + super(ability); + this.abilityOriginalId = ability.abilityOriginalId; + } + + @Override + public PyromancersGogglesTriggeredAbility copy() { + return new PyromancersGogglesTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType().equals(EventType.MANA_PAYED); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getData().equals(abilityOriginalId)) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && filter.match(spell, getControllerId(), game)) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When that mana is used to cast a red instant or sorcery spell, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/Ramroller.java b/Mage.Sets/src/mage/sets/magicorigins/Ramroller.java new file mode 100644 index 00000000000..2a7c2083899 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/Ramroller.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksEachTurnStaticAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition.CountType; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LoneFox + + */ +public class Ramroller extends CardImpl { + + private static final FilterControlledArtifactPermanent filter = new FilterControlledArtifactPermanent(); + + static { + filter.add(new AnotherPredicate()); + } + + public Ramroller(UUID ownerId) { + super(ownerId, 237, "Ramroller", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Juggernaut"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Ramroller attacks each turn if able. + this.addAbility(new AttacksEachTurnStaticAbility()); + // Ramroller gets +2/+0 as long as you control another artifact. + Condition condition = new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0); + ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new BoostSourceEffect(2, 0, + Duration.WhileOnBattlefield), condition, "{this} gets +2/+0 as long as you control another artifact."); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public Ramroller(final Ramroller card) { + super(card); + } + + @Override + public Ramroller copy() { + return new Ramroller(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java b/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java index 612b08ceacb..cfb3c63e723 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java +++ b/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java @@ -29,7 +29,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.BecomesRenownSourceTriggeredAbility; +import mage.abilities.common.BecomesRenownedSourceTriggeredAbility; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.keyword.RenownAbility; import mage.cards.CardImpl; @@ -44,17 +44,17 @@ import mage.target.common.TargetCardInLibrary; * * @author LevelX2 */ -public class RelicSeeker extends CardImpl { - +public class RelicSeeker extends CardImpl { + private static final FilterCard filter = new FilterCard("an Equipment card"); static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); filter.add(new SubtypePredicate("Equipment")); } - + public RelicSeeker(UUID ownerId) { - super(ownerId, 107, "Relic Seeker", Rarity.SPECIAL, new CardType[]{CardType.CREATURE}, "{1}{W}"); + super(ownerId, 29, "Relic Seeker", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.expansionSetCode = "ORI"; this.subtype.add("Human"); this.subtype.add("Soldier"); @@ -63,10 +63,10 @@ public class RelicSeeker extends CardImpl { // Renown 1 this.addAbility(new RenownAbility(1)); - + // When Relic Seeker becomes renowned, you may search your library for an Equipment card, reveal it, put it into your hand, then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); - this.addAbility(new BecomesRenownSourceTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); + this.addAbility(new BecomesRenownedSourceTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } diff --git a/Mage.Sets/src/mage/sets/magicorigins/ScabClanBerserker.java b/Mage.Sets/src/mage/sets/magicorigins/ScabClanBerserker.java index d325fe9e592..35c7bd9d9e3 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ScabClanBerserker.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ScabClanBerserker.java @@ -30,7 +30,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.condition.common.RenownCondition; +import mage.abilities.condition.common.RenownedSourceCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; @@ -68,7 +68,7 @@ public class ScabClanBerserker extends CardImpl { // Whenever an opponent casts a noncreature spell, if Scab-Clan Berserker is renowned, Scab-Clan Berserker deals 2 damage to that player. this.addAbility(new ConditionalTriggeredAbility( new ScabClanBerserkerTriggeredAbility(), - RenownCondition.getInstance(), + RenownedSourceCondition.getInstance(), "Whenever an opponent casts a noncreature spell, if Scab-Clan Berserker is renowned, Scab-Clan Berserker deals 2 damage to that player")); } diff --git a/Mage.Sets/src/mage/sets/magicorigins/ShadowsOfThePast.java b/Mage.Sets/src/mage/sets/magicorigins/ShadowsOfThePast.java new file mode 100644 index 00000000000..0c70c600fbb --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ShadowsOfThePast.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; + +/** + * + * @author LevelX2 + */ +public class ShadowsOfThePast extends CardImpl { + + public ShadowsOfThePast(UUID ownerId) { + super(ownerId, 118, "Shadows of the Past", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + this.expansionSetCode = "ORI"; + + // Whenever a creature dies, scry 1. + this.addAbility(new DiesCreatureTriggeredAbility(new ScryEffect(1), false)); + + // {4}{B}: Each opponent loses 2 life and you gain 2 life. Activate this ability only if there are four or more creature cards in your graveyard. + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, + new LoseLifeOpponentsEffect(2), new ManaCostsImpl<>("{4}{B}"), new CardsInControllerGraveCondition(4, new FilterCreatureCard())); + Effect effect = new GainLifeEffect(2); + effect.setText("and you gain 2 life"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public ShadowsOfThePast(final ShadowsOfThePast card) { + super(card); + } + + @Override + public ShadowsOfThePast copy() { + return new ShadowsOfThePast(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/SigilOfValor.java b/Mage.Sets/src/mage/sets/magicorigins/SigilOfValor.java new file mode 100644 index 00000000000..4dc297988ff --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/SigilOfValor.java @@ -0,0 +1,154 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardIdPredicate; +import static mage.filter.predicate.permanent.ControllerControlsIslandPredicate.filter; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class SigilOfValor extends CardImpl { + + public SigilOfValor(UUID ownerId) { + super(ownerId, 239, "Sigil of Valor", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Equipment"); + + // Whenever equipped creature attacks alone, it gets +1/+1 until end of turn for each other creature you control. + this.addAbility(new SigilOfValorTriggeredAbility(new SigilOfValorCount())); + + // Equip {1} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1))); + } + + public SigilOfValor(final SigilOfValor card) { + super(card); + } + + @Override + public SigilOfValor copy() { + return new SigilOfValor(this); + } +} + +class SigilOfValorTriggeredAbility extends TriggeredAbilityImpl { + + public SigilOfValorTriggeredAbility(DynamicValue boostValue) { + super(Zone.BATTLEFIELD, new BoostTargetEffect(boostValue, boostValue, Duration.EndOfTurn)); + } + + public SigilOfValorTriggeredAbility(final SigilOfValorTriggeredAbility ability) { + super(ability); + } + + @Override + public SigilOfValorTriggeredAbility copy() { + return new SigilOfValorTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.getCombat().attacksAlone()) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever equipped creature attacks alone, it gets +1/+1 until end of turn for each other creature you control."; + } + +} + +class SigilOfValorCount implements DynamicValue { + + public SigilOfValorCount() { + } + + public SigilOfValorCount(final SigilOfValorCount dynamicValue) { + super(); + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Permanent equipment = game.getPermanent(sourceAbility.getSourceId()); + if (equipment != null && equipment.getAttachedTo() != null) { + FilterPermanent filterPermanent = new FilterControlledCreaturePermanent(); + filterPermanent.add(Predicates.not(new CardIdPredicate(equipment.getAttachedTo()))); + return game.getBattlefield().count(filterPermanent, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game); + } + return 0; + } + + @Override + public DynamicValue copy() { + return new SigilOfValorCount(this); + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return filter.getMessage(); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/SuppressionBonds.java b/Mage.Sets/src/mage/sets/magicorigins/SuppressionBonds.java new file mode 100644 index 00000000000..db0b6fc7325 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/SuppressionBonds.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.CantBlockAttackActivateAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetNonlandPermanent; + +/** + * + * @author LevelX2 + */ +public class SuppressionBonds extends CardImpl { + + public SuppressionBonds(UUID ownerId) { + super(ownerId, 34, "Suppression Bonds", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Aura"); + + // Enchant nonland permanent + TargetPermanent auraTarget = new TargetNonlandPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted permanent can't attack or block, and its activated abilities can't be actiated. + Effect effect = new CantBlockAttackActivateAttachedEffect(); + effect.setText("Enchanted permanent can't attack or block, and its activated abilities can't be actiated"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAttackActivateAttachedEffect())); + } + + public SuppressionBonds(final SuppressionBonds card) { + super(card); + } + + @Override + public SuppressionBonds copy() { + return new SuppressionBonds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/SwiftReckoning.java b/Mage.Sets/src/mage/sets/magicorigins/SwiftReckoning.java new file mode 100644 index 00000000000..2d34a1fe360 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/SwiftReckoning.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.SpellMasteryCondition; +import mage.abilities.decorator.ConditionalAsThoughEffect; +import mage.abilities.effects.AsThoughEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class SwiftReckoning extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); + + static { + filter.add(new TappedPredicate()); + } + + public SwiftReckoning(UUID ownerId) { + super(ownerId, 35, "Swift Reckoning", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{1}{W}"); + this.expansionSetCode = "ORI"; + + // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast Swift Reckoning as though it had flash. + AsThoughEffect effect = new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame); + effect.setText("Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast {this} as though it had flash"); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConditionalAsThoughEffect(effect, + SpellMasteryCondition.getInstance()))); + // Destroy target tapped creature. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public SwiftReckoning(final SwiftReckoning card) { + super(card); + } + + @Override + public SwiftReckoning copy() { + return new SwiftReckoning(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/SwordOfTheAnimist.java b/Mage.Sets/src/mage/sets/magicorigins/SwordOfTheAnimist.java new file mode 100644 index 00000000000..b58fb4be486 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/SwordOfTheAnimist.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterBasicLandCard; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LoneFox + + */ +public class SwordOfTheAnimist extends CardImpl { + + public SwordOfTheAnimist(UUID ownerId) { + super(ownerId, 240, "Sword of the Animist", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "ORI"; + this.supertype.add("Legendary"); + this.subtype.add("Equipment"); + + // Equipped creature gets +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); + // Whenever equipped creature attacks, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard()); + this.addAbility(new AttacksAttachedTriggeredAbility(new SearchLibraryPutInPlayEffect(target, true), true)); + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + } + + public SwordOfTheAnimist(final SwordOfTheAnimist card) { + super(card); + } + + @Override + public SwordOfTheAnimist copy() { + return new SwordOfTheAnimist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java b/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java new file mode 100644 index 00000000000..4b9654bfcf8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java @@ -0,0 +1,152 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileSpellEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInHand; + +/** + * + * @author LevelX2 + */ +public class TheGreatAurora extends CardImpl { + + public TheGreatAurora(UUID ownerId) { + super(ownerId, 179, "The Great Aurora", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{6}{G}{G}{G}"); + this.expansionSetCode = "ORI"; + + // Each player shuffles all cards from his or her hand and all permanents he or she owns into his or her library, then draws that many cards. Each player may put any number of land cards from his or her hand onto the battlefield. Exile The Great Aurora. + this.getSpellAbility().addEffect(new TheGreatAuroraEffect()); + this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); + } + + public TheGreatAurora(final TheGreatAurora card) { + super(card); + } + + @Override + public TheGreatAurora copy() { + return new TheGreatAurora(this); + } +} + +class TheGreatAuroraEffect extends OneShotEffect { + + public TheGreatAuroraEffect() { + super(Outcome.Benefit); + this.staticText = "Each player shuffles all cards from his or her hand and all permanents he or she owns into his or her library, then draws that many cards. Each player may put any number of land cards from his or her hand onto the battlefield"; + } + + public TheGreatAuroraEffect(final TheGreatAuroraEffect effect) { + super(effect); + } + + @Override + public TheGreatAuroraEffect copy() { + return new TheGreatAuroraEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + + Map> permanentsOwned = new HashMap<>(); + Collection permanents = game.getBattlefield().getAllPermanents(); + for (Permanent permanent : permanents) { + List list = permanentsOwned.get(permanent.getOwnerId()); + if (list == null) { + list = new ArrayList<>(); + } + list.add(permanent); + permanentsOwned.put(permanent.getOwnerId(), list); + } + + // shuffle permanents and hand cards into owner's library + Map permanentsCount = new HashMap<>(); + + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int handCards = player.getHand().size(); + player.moveCards(player.getHand(), Zone.HAND, Zone.LIBRARY, source, game); + List list = permanentsOwned.remove(player.getId()); + permanentsCount.put(playerId, handCards + (list != null ? list.size() : 0)); + for (Permanent permanent : list) { + permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + } + player.getLibrary().shuffle(); + } + } + + // Draw cards + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int count = permanentsCount.get(playerId); + if (count > 0) { + player.drawCards(count, game); + } + } + } + + // put lands onto the battlefield + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCard target = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterLandCard("put any number of land cards from your hand onto the battlefield")); + player.chooseTarget(Outcome.PutLandInPlay, player.getHand(), target, source, game); + for (UUID cardId : target.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), true); + } + } + + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ThopterEngineer.java b/Mage.Sets/src/mage/sets/magicorigins/ThopterEngineer.java new file mode 100644 index 00000000000..dd0a4a1c202 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ThopterEngineer.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.permanent.token.Token; + +/** + * + * @author Wehk + */ +public class ThopterEngineer extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Artifact creatures"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public ThopterEngineer(UUID ownerId) { + super(ownerId, 165, "Thopter Engineer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Artificer"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // When Thopter Engineer enters the battlefield, put a 1/1 colorless Thopter artifact creature token with flying onto the battlefield. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ThopterEngineerThopterToken(), 1))); + + // Artifact creatures you control have haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false))); + } + + public ThopterEngineer(final ThopterEngineer card) { + super(card); + } + + @Override + public ThopterEngineer copy() { + return new ThopterEngineer(this); + } +} + +class ThopterEngineerThopterToken extends Token { + ThopterEngineerThopterToken() { + super("Thopter", "a 1/1 colorless Thopter artifact creature token with flying"); + cardType.add(CardType.CREATURE); + cardType.add(CardType.ARTIFACT); + subtype.add("Thopter"); + power = new MageInt(1); + toughness = new MageInt(1); + this.addAbility(FlyingAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ThornbowArcher.java b/Mage.Sets/src/mage/sets/magicorigins/ThornbowArcher.java new file mode 100644 index 00000000000..e1ae93705b1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ThornbowArcher.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class ThornbowArcher extends CardImpl { + + public ThornbowArcher(UUID ownerId) { + super(ownerId, 121, "Thornbow Archer", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{B}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Elf"); + this.subtype.add("Archer"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Whenever Thornbow Archer attacks, each opponent who doesn't control an Elf loses 1 life. + this.addAbility(new AttacksTriggeredAbility(new ThornbowArcherEffect(), false)); + } + + public ThornbowArcher(final ThornbowArcher card) { + super(card); + } + + @Override + public ThornbowArcher copy() { + return new ThornbowArcher(this); + } +} + +class ThornbowArcherEffect extends OneShotEffect { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new SubtypePredicate("Elf")); + } + + public ThornbowArcherEffect() { + super(Outcome.LoseLife); + this.staticText = "each opponent who doesn't control an Elf loses 1 life"; + } + + public ThornbowArcherEffect(final ThornbowArcherEffect effect) { + super(effect); + } + + @Override + public ThornbowArcherEffect copy() { + return new ThornbowArcherEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID opponentId : game.getOpponents(controller.getId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + if (game.getBattlefield().countAll(filter, opponentId, game) == 0) { + opponent.loseLife(1, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ThrowingKnife.java b/Mage.Sets/src/mage/sets/magicorigins/ThrowingKnife.java new file mode 100644 index 00000000000..fa810899d79 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ThrowingKnife.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.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + + */ +public class ThrowingKnife extends CardImpl { + + public ThrowingKnife(UUID ownerId) { + super(ownerId, 241, "Throwing Knife", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Equipment"); + + // Equipped creature gets +2/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0))); + // Whenever equipped creature attacks, you may sacrifice Throwing Knife. If you do, Throwing Knife deals 2 damage to target creature or player. + Effect effect = new SacrificeSourceEffect(); + effect.setText("you may sacrifice {this}. If you do, "); + Ability ability = new AttacksAttachedTriggeredAbility(new SacrificeSourceEffect(), true); + ability.addEffect(new DamageTargetEffect(2)); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + } + + public ThrowingKnife(final ThrowingKnife card) { + super(card); + } + + @Override + public ThrowingKnife copy() { + return new ThrowingKnife(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ThunderclapWyvern.java b/Mage.Sets/src/mage/sets/magicorigins/ThunderclapWyvern.java new file mode 100644 index 00000000000..9b2d7dff977 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ThunderclapWyvern.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; + +/** + * + * @author LevelX2 + */ +public class ThunderclapWyvern extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public ThunderclapWyvern(UUID ownerId) { + super(ownerId, 218, "Thunderclap Wyvern", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Drake"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Other creatures you control with flying get +1/+1. + Effect effect = new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true); + effect.setText("Other creatures you control with flying get +1/+1"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + + } + + public ThunderclapWyvern(final ThunderclapWyvern card) { + super(card); + } + + @Override + public ThunderclapWyvern copy() { + return new ThunderclapWyvern(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/TopanFreeblade.java b/Mage.Sets/src/mage/sets/magicorigins/TopanFreeblade.java index 9d3e7d6f923..813f44a0719 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/TopanFreeblade.java +++ b/Mage.Sets/src/mage/sets/magicorigins/TopanFreeblade.java @@ -30,6 +30,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.MageInt; import mage.abilities.keyword.RenownAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; @@ -49,6 +50,8 @@ public class TopanFreeblade extends CardImpl { this.toughness = new MageInt(2); // Vigilance (Attacking doesn't cause this creature to tap.) + this.addAbility(VigilanceAbility.getInstance()); + // Renown 1 this.addAbility(new RenownAbility(1)); } diff --git a/Mage.Sets/src/mage/sets/magicorigins/TouchOfMoonglove.java b/Mage.Sets/src/mage/sets/magicorigins/TouchOfMoonglove.java new file mode 100644 index 00000000000..b5faf222d09 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/TouchOfMoonglove.java @@ -0,0 +1,167 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +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.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class TouchOfMoonglove extends CardImpl { + + public TouchOfMoonglove(UUID ownerId) { + super(ownerId, 123, "Touch of Moonglove", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}"); + this.expansionSetCode = "ORI"; + + // Target creature you control gets +1/+0 and gains deathtouch until end of turn. + Effect effect = new BoostTargetEffect(1, 0, Duration.EndOfTurn); + effect.setText("Target creature you control gets +1/+0"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( + DeathtouchAbility.getInstance(), Duration.EndOfTurn, "and gains deathtouch until end of turn")); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + // Whenever a creature dealt damage by that creature this turn dies, its controller loses 2 life. + // this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(null)); + this.getSpellAbility().addEffect(new TouchOfMoongloveAddTriggerEffect()); + + } + + public TouchOfMoonglove(final TouchOfMoonglove card) { + super(card); + } + + @Override + public TouchOfMoonglove copy() { + return new TouchOfMoonglove(this); + } +} + +class TouchOfMoongloveAddTriggerEffect extends OneShotEffect { + + public TouchOfMoongloveAddTriggerEffect() { + super(Outcome.Damage); + this.staticText = "Whenever a creature dealt damage by that creature this turn dies, its controller loses 2 life"; + } + + public TouchOfMoongloveAddTriggerEffect(final TouchOfMoongloveAddTriggerEffect effect) { + super(effect); + } + + @Override + public TouchOfMoongloveAddTriggerEffect copy() { + return new TouchOfMoongloveAddTriggerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + DelayedTriggeredAbility delayedAbility = new TouchOfMoongloveDelayedTriggeredAbility(new MageObjectReference(permanent, game)); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + } + return true; + } +} + +class TouchOfMoongloveDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private final MageObjectReference creatureToCheck; + + public TouchOfMoongloveDelayedTriggeredAbility(MageObjectReference creatureToCheck) { + super(new DamageTargetEffect(2), Duration.EndOfTurn); + this.creatureToCheck = creatureToCheck; + } + + public TouchOfMoongloveDelayedTriggeredAbility(TouchOfMoongloveDelayedTriggeredAbility ability) { + super(ability); + this.creatureToCheck = ability.creatureToCheck; + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD + && zEvent.getTarget().getCardType().contains(CardType.CREATURE)) { + boolean damageDealt = false; + for (MageObjectReference mor : zEvent.getTarget().getDealtDamageByThisTurn()) { + if (mor.equals(creatureToCheck)) { + damageDealt = true; + break; + } + } + if (damageDealt) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(zEvent.getTarget().getControllerId())); + } + return true; + } + } + return false; + } + + @Override + public TouchOfMoongloveDelayedTriggeredAbility copy() { + return new TouchOfMoongloveDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature dealt damage by that creature this turn dies, its controller loses 2 life."; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/TragicArrogance.java b/Mage.Sets/src/mage/sets/magicorigins/TragicArrogance.java new file mode 100644 index 00000000000..4cd7dfe7661 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/TragicArrogance.java @@ -0,0 +1,170 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.common.FilterPlaneswalkerPermanent; +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.TargetArtifactPermanent; + +/** + * + * @author LevelX2 + */ +public class TragicArrogance extends CardImpl { + + public TragicArrogance(UUID ownerId) { + super(ownerId, 38, "Tragic Arrogance", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{W}{W}"); + this.expansionSetCode = "ORI"; + + // For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents he or she controls. + this.getSpellAbility().addEffect(new TragicArroganceffect()); + } + + public TragicArrogance(final TragicArrogance card) { + super(card); + } + + @Override + public TragicArrogance copy() { + return new TragicArrogance(this); + } +} + +class TragicArroganceffect extends OneShotEffect { + + public TragicArroganceffect() { + super(Outcome.Benefit); + this.staticText = "For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents he or she controls"; + } + + public TragicArroganceffect(final TragicArroganceffect effect) { + super(effect); + } + + @Override + public TragicArroganceffect copy() { + return new TragicArroganceffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Set choosenPermanent = new HashSet<>(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + FilterArtifactPermanent filterArtifactPermanent = new FilterArtifactPermanent("an artifact of " + player.getName()); + filterArtifactPermanent.add(new ControllerIdPredicate(playerId)); + Target target1 = new TargetArtifactPermanent(1, 1, filterArtifactPermanent, true); + + FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent("a creature of " + player.getName()); + filterCreaturePermanent.add(new ControllerIdPredicate(playerId)); + Target target2 = new TargetPermanent(1, 1, new FilterCreaturePermanent(), true); + + FilterEnchantmentPermanent filterEnchantmentPermanent = new FilterEnchantmentPermanent("an enchantment of " + player.getName()); + filterEnchantmentPermanent.add(new ControllerIdPredicate(playerId)); + Target target3 = new TargetPermanent(1, 1, new FilterEnchantmentPermanent(), true); + + FilterPlaneswalkerPermanent filterPlaneswalkerPermanent = new FilterPlaneswalkerPermanent("a planeswalker of " + player.getName()); + filterPlaneswalkerPermanent.add(new ControllerIdPredicate(playerId)); + Target target4 = new TargetPermanent(1, 1, new FilterPlaneswalkerPermanent(), true); + + if (target1.canChoose(controller.getId(), game)) { + controller.chooseTarget(Outcome.Benefit, target1, source, game); + Permanent artifact = game.getPermanent(target1.getFirstTarget()); + if (artifact != null) { + choosenPermanent.add(artifact); + } + target1.clearChosen(); + } + + if (target2.canChoose(player.getId(), game)) { + controller.chooseTarget(Outcome.Benefit, target2, source, game); + Permanent creature = game.getPermanent(target2.getFirstTarget()); + if (creature != null) { + choosenPermanent.add(creature); + } + target2.clearChosen(); + } + + if (target3.canChoose(player.getId(), game)) { + controller.chooseTarget(Outcome.Benefit, target3, source, game); + Permanent enchantment = game.getPermanent(target3.getFirstTarget()); + if (enchantment != null) { + choosenPermanent.add(enchantment); + } + target3.clearChosen(); + } + + if (target4.canChoose(player.getId(), game)) { + controller.chooseTarget(Outcome.Benefit, target4, source, game); + Permanent planeswalker = game.getPermanent(target4.getFirstTarget()); + if (planeswalker != null) { + choosenPermanent.add(planeswalker); + } + target4.clearChosen(); + } + } + } + // Then each player sacrifices all other nonland permanents he or she controls + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterNonlandPermanent(), game)) { + if (!choosenPermanent.contains(permanent)) { + permanent.sacrifice(playerId, game); + } + } + } + } + + return true; + } + + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/UndeadServant.java b/Mage.Sets/src/mage/sets/magicorigins/UndeadServant.java index d5cd57a2d0c..de8bbce4967 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/UndeadServant.java +++ b/Mage.Sets/src/mage/sets/magicorigins/UndeadServant.java @@ -44,8 +44,9 @@ import mage.game.permanent.token.ZombieToken; * @author fireshoes */ public class UndeadServant extends CardImpl { - - private static final FilterCard filter = new FilterCard(); + + private static final FilterCard filter = new FilterCard("card named Undead Servant"); + static { filter.add(new NamePredicate("Undead Servant")); } diff --git a/Mage.Sets/src/mage/sets/magicorigins/UndercityTroll.java b/Mage.Sets/src/mage/sets/magicorigins/UndercityTroll.java new file mode 100644 index 00000000000..2a7cb637bbf --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/UndercityTroll.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class UndercityTroll extends CardImpl { + + public UndercityTroll(UUID ownerId) { + super(ownerId, 202, "Undercity Troll", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Troll"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Renown 1 + this.addAbility(new RenownAbility(1)); + // {2}{G}: Regenerate Undercity Troll. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl<>("{2}{G}"))); + } + + public UndercityTroll(final UndercityTroll card) { + super(card); + } + + @Override + public UndercityTroll copy() { + return new UndercityTroll(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ValeronWardens.java b/Mage.Sets/src/mage/sets/magicorigins/ValeronWardens.java new file mode 100644 index 00000000000..4a180fd386c --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ValeronWardens.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.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class ValeronWardens extends CardImpl { + + public ValeronWardens(UUID ownerId) { + super(ownerId, 203, "Valeron Wardens", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Monk"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Renown 2 + this.addAbility(new RenownAbility(2)); + + // Whenever a creature you control becomes renowned, draw a card. + this.addAbility(new ValeronWardensTriggeredAbility()); + } + + public ValeronWardens(final ValeronWardens card) { + super(card); + } + + @Override + public ValeronWardens copy() { + return new ValeronWardens(this); + } +} + +class ValeronWardensTriggeredAbility extends TriggeredAbilityImpl { + + public ValeronWardensTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); + } + + public ValeronWardensTriggeredAbility(final ValeronWardensTriggeredAbility ability) { + super(ability); + } + + @Override + public ValeronWardensTriggeredAbility copy() { + return new ValeronWardensTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType().equals(EventType.BECOMES_RENOWNED); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + return permanent != null && permanent.getControllerId().equals(getControllerId()); + } + + @Override + public String getRule() { + return "Whenever a creature you control becomes renowned, draw a card."; + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/VineSnare.java b/Mage.Sets/src/mage/sets/magicorigins/VineSnare.java new file mode 100644 index 00000000000..9890fb2ba0e --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/VineSnare.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.common.PreventAllDamageByAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; + +/** + * + * @author LevelX2 + */ +public class VineSnare extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 4 or less"); + + static { + filter.add(new PowerPredicate(Filter.ComparisonType.LessThan, 5)); + } + + public VineSnare(UUID ownerId) { + super(ownerId, 205, "Vine Snare", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{G}"); + this.expansionSetCode = "ORI"; + + // Prevent all combat damage that would be dealt this turn by creatures with power 4 or less. + this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(filter, Duration.EndOfTurn, true)); + } + + public VineSnare(final VineSnare card) { + super(card); + } + + @Override + public VineSnare copy() { + return new VineSnare(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/VolcanicRambler.java b/Mage.Sets/src/mage/sets/magicorigins/VolcanicRambler.java index 17361c9fc80..76c7e7a90cb 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/VolcanicRambler.java +++ b/Mage.Sets/src/mage/sets/magicorigins/VolcanicRambler.java @@ -31,7 +31,6 @@ 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.common.DamageTargetEffect; import mage.cards.CardImpl; @@ -55,9 +54,8 @@ public class VolcanicRambler extends CardImpl { // {2}{R}: Volcanic Rambler deals 1 damage to target player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{2}{R}")); - ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); - this.addAbility(ability); + this.addAbility(ability); } public VolcanicRambler(final VolcanicRambler card) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/WarHorn.java b/Mage.Sets/src/mage/sets/magicorigins/WarHorn.java new file mode 100644 index 00000000000..cf29b99c74b --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/WarHorn.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterAttackingCreature; + +/** + * + * @author LoneFox + + */ +public class WarHorn extends CardImpl { + + public WarHorn(UUID ownerId) { + super(ownerId, 243, "War Horn", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "ORI"; + + // Attacking creatures you control get +1/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, + Duration.WhileOnBattlefield, new FilterAttackingCreature(), false))); + } + + public WarHorn(final WarHorn card) { + super(card); + } + + @Override + public WarHorn copy() { + return new WarHorn(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/WildInstincts.java b/Mage.Sets/src/mage/sets/magicorigins/WildInstincts.java new file mode 100644 index 00000000000..6c676643bcb --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/WildInstincts.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class WildInstincts extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public WildInstincts(UUID ownerId) { + super(ownerId, 206, "Wild Instincts", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{G}"); + this.expansionSetCode = "ORI"; + + // Target creature you control gets +2/+2 until end of turn. It fights target creature an opponent controls. + Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); + effect.setApplyEffectsAfter(); + getSpellAbility().addEffect(effect); + getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + effect = new FightTargetsEffect(); + effect.setText("It fights target creature an opponent controls (Each deals damage equal to its power to each other)"); + getSpellAbility().addEffect(effect); + getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public WildInstincts(final WildInstincts card) { + super(card); + } + + @Override + public WildInstincts copy() { + return new WildInstincts(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/Willbreaker.java b/Mage.Sets/src/mage/sets/magicorigins/Willbreaker.java index c6dcbe34c62..0480e397f3e 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/Willbreaker.java +++ b/Mage.Sets/src/mage/sets/magicorigins/Willbreaker.java @@ -43,7 +43,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; -import mage.game.stack.StackObject; import mage.players.Player; import mage.target.targetpointer.FixedTarget; @@ -96,8 +95,7 @@ class WillbreakerTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (getControllerId().equals(event.getPlayerId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getCardType().contains(CardType.CREATURE) - && StackObject.class.isInstance(game.getObject(event.getSourceId()))) { + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { Player controller = game.getPlayer(getControllerId()); if (controller != null && controller.hasOpponent(permanent.getControllerId(), game)) { getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage.Sets/src/mage/sets/magicorigins/ZendikarsRoil.java b/Mage.Sets/src/mage/sets/magicorigins/ZendikarsRoil.java new file mode 100644 index 00000000000..5f9940335bc --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/ZendikarsRoil.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterLandPermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LevelX2 + */ +public class ZendikarsRoil extends CardImpl { + + public ZendikarsRoil(UUID ownerId) { + super(ownerId, 209, "Zendikar's Roil", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}{G}"); + this.expansionSetCode = "ORI"; + + // Whenever a land enters the battlefield under your control, put a 2/2 green Elemental creature token onto the battlefield. + Effect effect = new CreateTokenEffect(new ZendikarsRoilElementalToken()); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(effect, new FilterLandPermanent("a land"))); + } + + public ZendikarsRoil(final ZendikarsRoil card) { + super(card); + } + + @Override + public ZendikarsRoil copy() { + return new ZendikarsRoil(this); + } +} + +class ZendikarsRoilElementalToken extends Token { + + public ZendikarsRoilElementalToken() { + super("Elemental", "2/2 green Elemental creature token"); + cardType.add(CardType.CREATURE); + setOriginalExpansionSetCode("ORI"); + subtype.add("Elemental"); + color.setGreen(true); + power = new MageInt(2); + toughness = new MageInt(2); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirage/BlindingLight.java b/Mage.Sets/src/mage/sets/mirage/BlindingLight.java new file mode 100644 index 00000000000..afb96c8c33d --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/BlindingLight.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.sets.mirage; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.TapAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class BlindingLight extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonwhite creatures"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.WHITE))); + } + + public BlindingLight(UUID ownerId) { + super(ownerId, 209, "Blinding Light", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{W}"); + this.expansionSetCode = "MIR"; + + // Tap all nonwhite creatures. + this.getSpellAbility().addEffect(new TapAllEffect(filter)); + } + + public BlindingLight(final BlindingLight card) { + super(card); + } + + @Override + public BlindingLight copy() { + return new BlindingLight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/GrabTheReins.java b/Mage.Sets/src/mage/sets/mirrodin/GrabTheReins.java new file mode 100644 index 00000000000..905ef340f27 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/GrabTheReins.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.sets.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.EntwineAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +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.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class GrabTheReins extends CardImpl { + + public GrabTheReins(UUID ownerId) { + super(ownerId, 95, "Grab the Reins", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{3}{R}"); + this.expansionSetCode = "MRD"; + + // Choose one - + this.getSpellAbility().getModes().setMinModes(1); + this.getSpellAbility().getModes().setMaxModes(1); + // Until end of turn, you gain control of target creature and it gains haste; + Effect effect = new GainControlTargetEffect(Duration.EndOfTurn); + effect.setText("Until end of turn, you gain control of target creature"); + effect.setApplyEffectsAfter(); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and it gains haste"); + this.getSpellAbility().addEffect(effect); + TargetCreaturePermanent target = new TargetCreaturePermanent(); + target.setTargetName("a creature to take control of"); + this.getSpellAbility().addTarget(target); + // or sacrifice a creature, then Grab the Reins deals damage equal to that creature's power to target creature or player. + Mode mode = new Mode(); + mode.getEffects().add(new GrabTheReinsEffect()); + TargetCreatureOrPlayer target2 = new TargetCreatureOrPlayer(); + target2.setTargetName("a creature or player to damage"); + mode.getTargets().add(target2); + this.getSpellAbility().getModes().addMode(mode); + + // Entwine {2}{R} + this.addAbility(new EntwineAbility("{2}{R}")); + } + + public GrabTheReins(final GrabTheReins card) { + super(card); + } + + @Override + public GrabTheReins copy() { + return new GrabTheReins(this); + } +} + +class GrabTheReinsEffect extends OneShotEffect { + + public GrabTheReinsEffect() { + super(Outcome.Damage); + staticText = "sacrifice a creature. {this} deals damage equal to the sacrificed creature's power to target creature or player"; + } + + public GrabTheReinsEffect(final GrabTheReinsEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID controllerId = source.getControllerId(); + Target target = new TargetCreaturePermanent(); + target.setNotTarget(true); + target.setTargetName("a creature to sacrifice"); + if(!target.canChoose(source.getSourceId(), controllerId, game)) { + return false; + } + Player player = game.getPlayer(controllerId); + if(player != null) { + player.chooseTarget(Outcome.Sacrifice, target, source, game); + Permanent creatureToSacrifice = game.getPermanent(target.getTargets().get(0)); + int amount = creatureToSacrifice.getPower().getValue(); + if(!creatureToSacrifice.sacrifice(creatureToSacrifice.getId(), game)) { + return false; + } + if (amount > 0) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + permanent.damage(amount, source.getSourceId(), game, false, true); + return true; + } + player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + player.damage(amount, source.getSourceId(), game, false, true); + return true; + } + } + else { + return true; + } + } + return false; + } + + @Override + public GrabTheReinsEffect copy() { + return new GrabTheReinsEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/newphyrexia/BlindingSouleater.java b/Mage.Sets/src/mage/sets/newphyrexia/BlindingSouleater.java index 34cd7866f8d..97edb201897 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/BlindingSouleater.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/BlindingSouleater.java @@ -28,16 +28,16 @@ package mage.sets.newphyrexia; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.ColoredManaSymbol; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.PhyrexianManaCost; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.common.TargetCreaturePermanent; /** @@ -54,6 +54,7 @@ public class BlindingSouleater extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(3); + // {WP},{T}: Tap target creature. ( can be paid with either or 2 life.) SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new PhyrexianManaCost(ColoredManaSymbol.W)); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/MoltensteelDragon.java b/Mage.Sets/src/mage/sets/newphyrexia/MoltensteelDragon.java index 7a7199cf973..61c0f707e93 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/MoltensteelDragon.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/MoltensteelDragon.java @@ -28,16 +28,17 @@ package mage.sets.newphyrexia; import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.PhyrexianManaCost; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.PhyrexianManaCost; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.cards.CardImpl; /** * @@ -53,6 +54,9 @@ public class MoltensteelDragon extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); + // Flying + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new PhyrexianManaCost(ColoredManaSymbol.R))); diff --git a/Mage.Sets/src/mage/sets/onslaught/CabalSlaver.java b/Mage.Sets/src/mage/sets/onslaught/CabalSlaver.java new file mode 100644 index 00000000000..ac9da8f9eae --- /dev/null +++ b/Mage.Sets/src/mage/sets/onslaught/CabalSlaver.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.sets.onslaught; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author markedagain + */ +public class CabalSlaver extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("Goblin"); + + static { + filter.add(new SubtypePredicate("Goblin")); + } + + public CabalSlaver(UUID ownerId) { + super(ownerId, 131, "Cabal Slaver", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "ONS"; + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever a Goblin deals combat damage to a player, that player discards a card. + this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(new DiscardTargetEffect(1),filter, false, SetTargetPointer.NONE, true)); + } + + public CabalSlaver(final CabalSlaver card) { + super(card); + } + + @Override + public CabalSlaver copy() { + return new CabalSlaver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/BogDown.java b/Mage.Sets/src/mage/sets/planeshift/BogDown.java new file mode 100644 index 00000000000..28601d9c185 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/BogDown.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planeshift; + +import java.util.UUID; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledLandPermanent; +import mage.target.TargetPlayer; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author LoneFox + + */ +public class BogDown extends CardImpl { + + public BogDown(UUID ownerId) { + super(ownerId, 39, "Bog Down", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{B}"); + this.expansionSetCode = "PLS"; + + // Kicker-Sacrifice two lands. + this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("two lands"), true)))); + // Target player discards two cards. If Bog Down was kicked, that player discards three cards instead. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DiscardTargetEffect(3), + new DiscardTargetEffect(2), KickedCondition.getInstance(), + "Target player discards two cards. If {this} was kicked, that player discards three cards instead.")); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public BogDown(final BogDown card) { + super(card); + } + + @Override + public BogDown copy() { + return new BogDown(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/DaringLeap.java b/Mage.Sets/src/mage/sets/planeshift/DaringLeap.java new file mode 100644 index 00000000000..b8d9105ca69 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/DaringLeap.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.sets.planeshift; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class DaringLeap extends CardImpl { + + public DaringLeap(UUID ownerId) { + super(ownerId, 101, "Daring Leap", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{W}{U}"); + this.expansionSetCode = "PLS"; + + // Target creature gets +1/+1 and gains flying and first strike until end of turn. + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); + effect.setText("Target creature gets +1/+1"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains flying"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and first strike until end of turn."); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public DaringLeap(final DaringLeap card) { + super(card); + } + + @Override + public DaringLeap copy() { + return new DaringLeap(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/DiscipleOfKangee.java b/Mage.Sets/src/mage/sets/planeshift/DiscipleOfKangee.java new file mode 100644 index 00000000000..2080755673c --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/DiscipleOfKangee.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.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +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.continuous.BecomesColorTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class DiscipleOfKangee extends CardImpl { + + public DiscipleOfKangee(UUID ownerId) { + super(ownerId, 3, "Disciple of Kangee", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {U}, {T}: Target creature gains flying and becomes blue until end of turn. + Effect effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); + effect.setText("Target creature gains flying"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{U}")); + effect = new BecomesColorTargetEffect(ObjectColor.BLUE, Duration.EndOfTurn); + effect.setText("and becomes blue until end of turn."); + ability.addEffect(effect); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public DiscipleOfKangee(final DiscipleOfKangee card) { + super(card); + } + + @Override + public DiscipleOfKangee copy() { + return new DiscipleOfKangee(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/DoomsdaySpecter.java b/Mage.Sets/src/mage/sets/planeshift/DoomsdaySpecter.java new file mode 100644 index 00000000000..0581059b7e8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/DoomsdaySpecter.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.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class DoomsdaySpecter extends CardImpl { + + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("blue or black creature you control"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.BLACK))); + } + + public DoomsdaySpecter(UUID ownerId) { + super(ownerId, 103, "Doomsday Specter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Specter"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // When Doomsday Specter enters the battlefield, return a blue or black creature you control to its owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter), false)); + // Whenever Doomsday Specter deals combat damage to a player, look at that player's hand and choose a card from it. The player discards that card. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DiscardCardYouChooseTargetEffect(), false, true)); + } + + public DoomsdaySpecter(final DoomsdaySpecter card) { + super(card); + } + + @Override + public DoomsdaySpecter copy() { + return new DoomsdaySpecter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/FallingTimber.java b/Mage.Sets/src/mage/sets/planeshift/FallingTimber.java new file mode 100644 index 00000000000..d20cf266577 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/FallingTimber.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planeshift; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledLandPermanent; +import mage.game.Game; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class FallingTimber extends CardImpl { + + private final UUID originalId; + + public FallingTimber(UUID ownerId) { + super(ownerId, 79, "Falling Timber", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{G}"); + this.expansionSetCode = "PLS"; + + // Kicker-Sacrifice a land. + this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent("a land"), true)))); + // Prevent all combat damage target creature would deal this turn. If Falling Timber was kicked, prevent all combat damage another target creature would deal this turn. + Effect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn, true); + effect.setText("Prevent all combat damage target creature would deal this turn. If {this} was kicked, prevent all combat damage another target creature would deal this turn."); + this.getSpellAbility().addEffect(effect); + originalId = this.getSpellAbility().getOriginalId(); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if(ability.getOriginalId().equals(originalId)) { + ability.addTarget(new TargetCreaturePermanent(KickedCondition.getInstance().apply(game, ability) ? 2 : 1)); + } + } + + public FallingTimber(final FallingTimber card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public FallingTimber copy() { + return new FallingTimber(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/MagmaBurst.java b/Mage.Sets/src/mage/sets/planeshift/MagmaBurst.java new file mode 100644 index 00000000000..868c160b9d8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/MagmaBurst.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.sets.planeshift; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledLandPermanent; +import mage.game.Game; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + + */ +public class MagmaBurst extends CardImpl { + + private final UUID originalId; + + public MagmaBurst(UUID ownerId) { + super(ownerId, 66, "Magma Burst", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{R}"); + this.expansionSetCode = "PLS"; + + // Kicker-Sacrifice two lands. + this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("two lands"), true)))); + // Magma Burst deals 3 damage to target creature or player. If Magma Burst was kicked, it deals 3 damage to another target creature or player. + Effect effect = new DamageTargetEffect(3); + effect.setText("{this} deals 3 damage to target creature or player. If {this} was kicked, it deals 3 damage to another target creature or player."); + this.getSpellAbility().addEffect(effect); + originalId = this.getSpellAbility().getOriginalId(); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if(ability.getOriginalId().equals(originalId)) { + ability.addTarget(new TargetCreatureOrPlayer(KickedCondition.getInstance().apply(game, ability) ? 2 : 1)); + } + } + + public MagmaBurst(final MagmaBurst card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public MagmaBurst copy() { + return new MagmaBurst(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/MarchOfSouls.java b/Mage.Sets/src/mage/sets/planeshift/MarchOfSouls.java new file mode 100644 index 00000000000..d1d0d83b4ea --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/MarchOfSouls.java @@ -0,0 +1,98 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planeshift; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SpiritWhiteToken; + +/** + * + * @author LoneFox + + */ +public class MarchOfSouls extends CardImpl { + + public MarchOfSouls(UUID ownerId) { + super(ownerId, 10, "March of Souls", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{W}"); + this.expansionSetCode = "PLS"; + + // Destroy all creatures. They can't be regenerated. For each creature destroyed this way, its controller puts a 1/1 white Spirit creature token with flying onto the battlefield. + this.getSpellAbility().addEffect(new MarchOfSoulsEffect()); + } + + public MarchOfSouls(final MarchOfSouls card) { + super(card); + } + + @Override + public MarchOfSouls copy() { + return new MarchOfSouls(this); + } +} + +class MarchOfSoulsEffect extends OneShotEffect { + + public MarchOfSoulsEffect() { + super(Outcome.Benefit); + staticText = "Destroy all creatures. They can't be regenerated. For each creature destroyed this way, its controller puts a 1/1 white Spirit creature token with flying onto the battlefield."; + } + + public MarchOfSoulsEffect(final MarchOfSoulsEffect effect) { + super(effect); + } + + @Override + public MarchOfSoulsEffect copy() { + return new MarchOfSoulsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List creatures = game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), + source.getControllerId(), source.getSourceId(), game); + for(Permanent p : creatures) { + UUID controllerId = p.getControllerId(); + if(p.destroy(source.getSourceId(), game, true)) { + SpiritWhiteToken token = new SpiritWhiteToken(); + token.putOntoBattlefield(1, game, source.getSourceId(), controllerId); + } + } + return true; + } + +} diff --git a/Mage.Sets/src/mage/sets/planeshift/MarshCrocodile.java b/Mage.Sets/src/mage/sets/planeshift/MarshCrocodile.java new file mode 100644 index 00000000000..29e4f0752c8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/MarshCrocodile.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class MarshCrocodile extends CardImpl { + + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("blue or black creature you control"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.BLACK))); + } + + public MarshCrocodile(UUID ownerId) { + super(ownerId, 115, "Marsh Crocodile", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Crocodile"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Marsh Crocodile enters the battlefield, return a blue or black creature you control to its owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter), false)); + // When Marsh Crocodile enters the battlefield, each player discards a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(), false)); + } + + public MarshCrocodile(final MarshCrocodile card) { + super(card); + } + + @Override + public MarshCrocodile copy() { + return new MarshCrocodile(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/NaturalEmergence.java b/Mage.Sets/src/mage/sets/planeshift/NaturalEmergence.java new file mode 100644 index 00000000000..45e816753dc --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/NaturalEmergence.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.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureAllEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledEnchantmentPermanent; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class NaturalEmergence extends CardImpl { + + static final private FilterControlledEnchantmentPermanent filter = new FilterControlledEnchantmentPermanent("red or green creature you control"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN))); + } + + public NaturalEmergence(UUID ownerId) { + super(ownerId, 117, "Natural Emergence", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{G}"); + this.expansionSetCode = "PLS"; + + // When Natural Emergence enters the battlefield, return a red or green enchantment you control to its owner's hand. + Effect effect = new ReturnToHandChosenControlledPermanentEffect(filter); + effect.setText("return a red or green enchantment you control to its owner's hand"); + this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false)); + // Lands you control are 2/2 creatures with first strike. They're still lands. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesCreatureAllEffect(new NaturalEmergenceToken(), + "lands", new FilterControlledLandPermanent("lands you control"), Duration.WhileOnBattlefield))); + } + + public NaturalEmergence(final NaturalEmergence card) { + super(card); + } + + @Override + public NaturalEmergence copy() { + return new NaturalEmergence(this); + } +} + +class NaturalEmergenceToken extends Token { + public NaturalEmergenceToken() { + super("Land", "2/2 creature with first strike"); + cardType.add(CardType.CREATURE); + power = new MageInt(2); + toughness = new MageInt(2); + this.addAbility(FirstStrikeAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/PollenRemedy.java b/Mage.Sets/src/mage/sets/planeshift/PollenRemedy.java new file mode 100644 index 00000000000..7e3d7d8b1b7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/PollenRemedy.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.sets.planeshift; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.decorator.ConditionalReplacementEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventDamageToTargetMultiAmountEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledLandPermanent; +import mage.game.Game; +import mage.target.common.TargetCreatureOrPlayerAmount; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author LoneFox + + */ +public class PollenRemedy extends CardImpl { + + private final UUID originalId; + + public PollenRemedy(UUID ownerId) { + super(ownerId, 13, "Pollen Remedy", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "PLS"; + + // Kicker-Sacrifice a land. + this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent("a land"), true)))); + // Prevent the next 3 damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose. If Pollen Remedy was kicked, prevent the next 6 damage this way instead. + Effect effect = new ConditionalReplacementEffect(new PreventDamageToTargetMultiAmountEffect(Duration.EndOfTurn, 6), + KickedCondition.getInstance(), new PreventDamageToTargetMultiAmountEffect(Duration.EndOfTurn, 3)); + effect.setText("Prevent the next 3 damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose. If {this} was kicked, prevent the next 6 damage this way instead."); + this.getSpellAbility().addEffect(effect); + originalId = this.getSpellAbility().getOriginalId(); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if(ability.getOriginalId().equals(originalId)) { + ability.addTarget(new TargetCreatureOrPlayerAmount(KickedCondition.getInstance().apply(game, ability) ? 6 : 3)); + } + } + + public PollenRemedy(final PollenRemedy card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public PollenRemedy copy() { + return new PollenRemedy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/RazingSnidd.java b/Mage.Sets/src/mage/sets/planeshift/RazingSnidd.java new file mode 100644 index 00000000000..3567ba17d8d --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/RazingSnidd.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.effects.common.SacrificeAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class RazingSnidd extends CardImpl { + + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("black or red creature you control"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLACK), new ColorPredicate(ObjectColor.RED))); + } + + public RazingSnidd(UUID ownerId) { + super(ownerId, 121, "Razing Snidd", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Beast"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // 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)); + } + + public RazingSnidd(final RazingSnidd card) { + super(card); + } + + @Override + public RazingSnidd copy() { + return new RazingSnidd(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/Sparkcaster.java b/Mage.Sets/src/mage/sets/planeshift/Sparkcaster.java new file mode 100644 index 00000000000..47ee3f189a9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/Sparkcaster.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.sets.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.TargetPlayer; + +/** + * + * @author LoneFox + + */ +public class Sparkcaster extends CardImpl { + + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("red or green creature you control"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN))); + } + + public Sparkcaster(UUID ownerId) { + super(ownerId, 126, "Sparkcaster", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Kavu"); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // When Sparkcaster enters the battlefield, return a red or green creature you control to its owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter), false)); + // When Sparkcaster enters the battlefield, it deals 1 damage to target player. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1), false); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public Sparkcaster(final Sparkcaster card) { + super(card); + } + + @Override + public Sparkcaster copy() { + return new Sparkcaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/Stratadon.java b/Mage.Sets/src/mage/sets/planeshift/Stratadon.java new file mode 100644 index 00000000000..1d7c4638b9a --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/Stratadon.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.sets.planeshift; + +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.effects.common.cost.CostModificationEffectImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.util.CardUtil; + +/** + * + * @author LoneFox + */ +public class Stratadon extends CardImpl { + + public Stratadon(UUID ownerId) { + super(ownerId, 135, "Stratadon", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{10}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Beast"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Domain - Stratadon costs {1} less to cast for each basic land type among lands you control. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new StratadonCostReductionEffect())); + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + public Stratadon(final Stratadon card) { + super(card); + } + + @Override + public Stratadon copy() { + return new Stratadon(this); + } +} + +class StratadonCostReductionEffect extends CostModificationEffectImpl { + + public StratadonCostReductionEffect() { + super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "Domain - {this} costs {1} less to cast for each basic land type among lands you control."; + } + + protected StratadonCostReductionEffect(final StratadonCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + CardUtil.reduceCost(abilityToModify, new DomainValue().calculate(game, source, this)); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify.getSourceId().equals(source.getSourceId()); + } + + @Override + public StratadonCostReductionEffect copy() { + return new StratadonCostReductionEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/portal/BlindingLight.java b/Mage.Sets/src/mage/sets/portal/BlindingLight.java new file mode 100644 index 00000000000..615d884a504 --- /dev/null +++ b/Mage.Sets/src/mage/sets/portal/BlindingLight.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.sets.portal; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class BlindingLight extends mage.sets.mirage.BlindingLight { + + public BlindingLight(UUID ownerId) { + super(ownerId); + this.cardNumber = 170; + this.expansionSetCode = "POR"; + this.rarity = Rarity.RARE; + } + + public BlindingLight(final BlindingLight card) { + super(card); + } + + @Override + public BlindingLight copy() { + return new BlindingLight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/DryadsCaress.java b/Mage.Sets/src/mage/sets/ravnica/DryadsCaress.java new file mode 100644 index 00000000000..0e7052ceda0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/DryadsCaress.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.sets.ravnica; + +import java.util.UUID; +import mage.abilities.condition.common.ManaWasSpentCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author Wehk + */ +public class DryadsCaress extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature on the battlefield"); + private static final String rule = "untap all creatures you control"; + + public DryadsCaress(UUID ownerId) { + super(ownerId, 160, "Dryad's Caress", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{4}{G}{G}"); + this.expansionSetCode = "RAV"; + + // You gain 1 life for each creature on the battlefield. + + this.getSpellAbility().addEffect(new GainLifeEffect(new PermanentsOnBattlefieldCount(filter))); + + //If {W} was spent to cast Dryad's Caress, untap all creatures you control. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new UntapAllControllerEffect(new FilterControlledCreaturePermanent(), rule), + new ManaWasSpentCondition(ColoredManaSymbol.W), "If {W} was spent to cast {this}, untap all creatures you control")); + } + + public DryadsCaress(final DryadsCaress card) { + super(card); + } + + @Override + public DryadsCaress copy() { + return new DryadsCaress(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/GolgariGermination.java b/Mage.Sets/src/mage/sets/ravnica/GolgariGermination.java new file mode 100644 index 00000000000..c4c3cde7ba2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/GolgariGermination.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.sets.ravnica; + +import java.util.UUID; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.SaprolingToken; + +/** + * + * @author Wehk + */ +public class GolgariGermination extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(Predicates.not(new TokenPredicate())); + } + + public GolgariGermination(UUID ownerId) { + super(ownerId, 209, "Golgari Germination", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{G}"); + this.expansionSetCode = "RAV"; + + // Whenever a nontoken creature you control dies, put a 1/1 green Saproling creature token onto the battlefield. + this.addAbility(new DiesCreatureTriggeredAbility(new CreateTokenEffect(new SaprolingToken()), false, filter)); + } + + public GolgariGermination(final GolgariGermination card) { + super(card); + } + + @Override + public GolgariGermination copy() { + return new GolgariGermination(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/HourOfReckoning.java b/Mage.Sets/src/mage/sets/ravnica/HourOfReckoning.java new file mode 100644 index 00000000000..523d5581683 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/HourOfReckoning.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.sets.ravnica; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.TokenPredicate; + +/** + * + * @author Wehk + */ +public class HourOfReckoning extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + + static { + filter.add(Predicates.not(new TokenPredicate())); + } + + public HourOfReckoning(UUID ownerId) { + super(ownerId, 21, "Hour of Reckoning", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{W}{W}{W}"); + this.expansionSetCode = "RAV"; + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Destroy all nontoken creatures. + this.getSpellAbility().addEffect(new DestroyAllEffect(filter)); + } + + public HourOfReckoning(final HourOfReckoning card) { + super(card); + } + + @Override + public HourOfReckoning copy() { + return new HourOfReckoning(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/RibbonsOfNight.java b/Mage.Sets/src/mage/sets/ravnica/RibbonsOfNight.java new file mode 100644 index 00000000000..a1c03587689 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/RibbonsOfNight.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.ravnica; + +import java.util.UUID; +import mage.abilities.condition.common.ManaWasSpentCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Wehk + */ +public class RibbonsOfNight extends CardImpl { + + public RibbonsOfNight(UUID ownerId) { + super(ownerId, 101, "Ribbons of Night", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{4}{B}"); + this.expansionSetCode = "RAV"; + + // Ribbons of Night deals 4 damage to target creature + Effect effect = new DamageTargetEffect(4); + this.getSpellAbility().addEffect(effect); + + // and you gain 4 life. + effect = new GainLifeEffect(4); + effect.setText("and you gain 4 life"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + //If {U} was spent to cast Ribbons of Night, draw a card. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), + new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast {this}, draw a card")); + } + + public RibbonsOfNight(final RibbonsOfNight card) { + super(card); + } + + @Override + public RibbonsOfNight copy() { + return new RibbonsOfNight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/SeedSpark.java b/Mage.Sets/src/mage/sets/ravnica/SeedSpark.java new file mode 100644 index 00000000000..0818865d24d --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/SeedSpark.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.ravnica; + +import java.util.UUID; +import mage.abilities.condition.common.ManaWasSpentCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Rarity; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; +import mage.game.permanent.token.SaprolingToken; +import mage.target.TargetPermanent; +import mage.abilities.effects.common.CreateTokenEffect; + +/** + * + * @author Wehk + */ +public class SeedSpark extends CardImpl { + + public SeedSpark(UUID ownerId) { + super(ownerId, 30, "Seed Spark", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{3}{W}"); + this.expansionSetCode = "RAV"; + + // Destroy target artifact or enchantment. + this.getSpellAbility().addTarget(new TargetPermanent(new FilterArtifactOrEnchantmentPermanent())); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + + //If {G} was spent to cast Seed Spark, put two 1/1 green Saproling creature tokens onto the battlefield. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new CreateTokenEffect(new SaprolingToken(), 2), + new ManaWasSpentCondition(ColoredManaSymbol.G), "If {G} was spent to cast {this}, put two 1/1 green Saproling creature tokens onto the battlefield")); + } + + public SeedSpark(final SeedSpark card) { + super(card); + } + + @Override + public SeedSpark copy() { + return new SeedSpark(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/Sewerdreg.java b/Mage.Sets/src/mage/sets/ravnica/Sewerdreg.java new file mode 100644 index 00000000000..14d8fe08607 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/Sewerdreg.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.sets.ravnica; + +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.effects.common.ExileTargetEffect; +import mage.abilities.keyword.SwampwalkAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author Wehk + */ +public class Sewerdreg extends CardImpl { + + public Sewerdreg(UUID ownerId) { + super(ownerId, 104, "Sewerdreg", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "RAV"; + this.subtype.add("Spirit"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Swampwalk + this.addAbility(new SwampwalkAbility()); + + // Sacrifice Sewerdreg: Exile target card from a graveyard. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new SacrificeSourceCost()); + ability.addTarget(new TargetCardInGraveyard()); + this.addAbility(ability); + } + + public Sewerdreg(final Sewerdreg card) { + super(card); + } + + @Override + public Sewerdreg copy() { + return new Sewerdreg(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/StoneSeederHierophant.java b/Mage.Sets/src/mage/sets/ravnica/StoneSeederHierophant.java new file mode 100644 index 00000000000..b6aeee6f40c --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/StoneSeederHierophant.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.ravnica; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; +import mage.target.Target; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author Wehk + */ +public class StoneSeederHierophant extends CardImpl { + + public StoneSeederHierophant(UUID ownerId) { + super(ownerId, 184, "Stone-Seeder Hierophant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "RAV"; + this.subtype.add("Human"); + this.subtype.add("Druid"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever a land enters the battlefield under your control, untap Stone-Seeder Hierophant. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new FilterLandPermanent("a land"), false)); + + // {tap}: Untap target land. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new TapSourceCost()); + Target target = new TargetLandPermanent(); + ability.addTarget(target); + this.addAbility(ability); + } + + public StoneSeederHierophant(final StoneSeederHierophant card) { + super(card); + } + + @Override + public StoneSeederHierophant copy() { + return new StoneSeederHierophant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/VindictiveMob.java b/Mage.Sets/src/mage/sets/ravnica/VindictiveMob.java new file mode 100644 index 00000000000..f2b57af28e7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/VindictiveMob.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.ravnica; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.SacrificeControllerEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author Wehk + */ +public class VindictiveMob extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("can't be blocked by Saprolings"); + + static { + filter.add(new SubtypePredicate("Saproling")); + } + + public VindictiveMob(UUID ownerId) { + super(ownerId, 112, "Vindictive Mob", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.expansionSetCode = "RAV"; + this.subtype.add("Human"); + this.subtype.add("Berserker"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // When Vindictive Mob enters the battlefield, sacrifice a creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeControllerEffect(new FilterCreaturePermanent(), 1, null))); + + // Vindictive Mob can't be blocked by Saprolings. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + } + + public VindictiveMob(final VindictiveMob card) { + super(card); + } + + @Override + public VindictiveMob copy() { + return new VindictiveMob(this); + } +} diff --git a/Mage.Sets/src/mage/sets/returntoravnica/AngelOfSerenity.java b/Mage.Sets/src/mage/sets/returntoravnica/AngelOfSerenity.java index e59ab2b006f..d71d7c49ce0 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/AngelOfSerenity.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/AngelOfSerenity.java @@ -29,10 +29,12 @@ package mage.sets.returntoravnica; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -44,10 +46,10 @@ import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCreaturePermanent; @@ -67,7 +69,6 @@ public class AngelOfSerenity extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(6); - // Flying this.addAbility(FlyingAbility.getInstance()); @@ -75,7 +76,7 @@ public class AngelOfSerenity extends CardImpl { this.addAbility(new AngelOfSerenityTriggeredAbility()); // When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands. - this.addAbility(new LeavesBattlefieldTriggeredAbility(new AngelOfSerenityLeaveEffect(), false )); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.HAND, false, true), false)); } public AngelOfSerenity(final AngelOfSerenity card) { @@ -104,7 +105,7 @@ class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility { getTargets().clear(); FilterCreaturePermanent filter = new FilterCreaturePermanent("up to three other target creatures"); filter.add(new AnotherPredicate()); - TargetCreaturePermanent target1 = new TargetCreaturePermanent(0,3, filter, false); + TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, 3, filter, false); game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target1, this, game); if (target1.getTargets().size() > 0) { getTargets().add(target1); @@ -112,8 +113,8 @@ class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility { } int leftTargets = 3 - target1.getTargets().size(); if (leftTargets > 0) { - FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1?"s":"") +" from graveyards"); - TargetCardInGraveyard target2 = new TargetCardInGraveyard(0,leftTargets, filter2); + FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1 ? "s" : "") + " from graveyards"); + TargetCardInGraveyard target2 = new TargetCardInGraveyard(0, leftTargets, filter2); game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target2, this, game); if (target2.getTargets().size() > 0) { getTargets().add(target2); @@ -150,21 +151,24 @@ class AngelOfSerenityEnterEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { boolean result = true; - if (source.getTargets().size() > 0) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null && source.getTargets().size() > 0) { + UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); for (Target target : source.getTargets()) { if (target instanceof TargetCreaturePermanent) { for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); if (permanent != null) { - result |= permanent.moveToExile(CardUtil.getCardExileZoneId(game, source), "Angel of Serenity", source.getSourceId(), game); + result |= controller.moveCardToExileWithInfo(permanent, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); } } - } else if (target instanceof TargetCardInGraveyard){ + } else if (target instanceof TargetCardInGraveyard) { for (UUID cardId : target.getTargets()) { Card card = game.getCard(cardId); if (card != null) { - result |= card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Angel of Serenity", source.getSourceId(), game); + result |= controller.moveCardToExileWithInfo(card, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true); } } } @@ -173,34 +177,3 @@ class AngelOfSerenityEnterEffect extends OneShotEffect { return result; } } - -class AngelOfSerenityLeaveEffect extends OneShotEffect { - - public AngelOfSerenityLeaveEffect() { - super(Outcome.ReturnToHand); - this.staticText = "return the exiled cards to their owners' hands"; - } - - public AngelOfSerenityLeaveEffect(final AngelOfSerenityLeaveEffect effect) { - super(effect); - } - - @Override - public AngelOfSerenityLeaveEffect copy() { - return new AngelOfSerenityLeaveEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - ExileZone exZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); - if (exZone != null) { - for (Card card : exZone.getCards(game)) { - if (card != null) { - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/returntoravnica/UltimatePrice.java b/Mage.Sets/src/mage/sets/returntoravnica/UltimatePrice.java index 168ad1e8f70..2c2e3a4af0e 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/UltimatePrice.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/UltimatePrice.java @@ -34,7 +34,6 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.MonocoloredPredicate; -import mage.target.Target; import mage.target.common.TargetCreaturePermanent; /** @@ -53,7 +52,6 @@ public class UltimatePrice extends CardImpl { super(ownerId, 82, "Ultimate Price", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{B}"); this.expansionSetCode = "RTR"; - // Destroy target monocolored creature. this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/DawnglareInvoker.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/DawnglareInvoker.java index 0a6ed85ffc3..70999f3afea 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/DawnglareInvoker.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/DawnglareInvoker.java @@ -27,23 +27,18 @@ */ package mage.sets.riseoftheeldrazi; -import java.util.List; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; 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.TapAllTargetPlayerControlsEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPlayer; /** @@ -63,7 +58,7 @@ public class DawnglareInvoker extends CardImpl { this.addAbility(FlyingAbility.getInstance()); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new DawnglareInvokerEffect(), + new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures")), new ManaCostsImpl("{8}")); ability.addTarget(new TargetPlayer()); this.addAbility(ability); @@ -78,36 +73,3 @@ public class DawnglareInvoker extends CardImpl { return new DawnglareInvoker(this); } } - -class DawnglareInvokerEffect extends OneShotEffect { - - public DawnglareInvokerEffect() { - super(Outcome.Tap); - staticText = "Tap all creatures target player controls"; - } - - public DawnglareInvokerEffect(final DawnglareInvokerEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getFirstTarget() == null) { - return false; - } - - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new ControllerIdPredicate(source.getFirstTarget())); - - List creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent creature : creatures) { - creature.tap(game); - } - return true; - } - - @Override - public DawnglareInvokerEffect copy() { - return new DawnglareInvokerEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java index 1d54c0cce94..b20a7cfe247 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -29,16 +29,16 @@ package mage.sets.scarsofmirrodin; import java.util.UUID; import mage.MageObject; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.Filter.ComparisonType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; @@ -58,7 +58,6 @@ public class GenesisWave extends CardImpl { super(ownerId, 122, "Genesis Wave", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}{G}{G}"); this.expansionSetCode = "SOM"; - // Reveal the top X cards of your library. You may put any number of permanent cards with converted mana // cost X or less from among them onto the battlefield. Then put all cards revealed this way that weren't // put onto the battlefield into your graveyard. @@ -102,21 +101,21 @@ class GenesisWaveEffect extends OneShotEffect { cards.add(card); } if (cards.size() > 0) { - controller.revealCards(sourceObject.getName(), cards, game); + controller.revealCards(sourceObject.getIdName(), cards, game); FilterCard filter = new FilterCard("cards with converted mana cost " + xValue + " or less to put onto the battlefield"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xValue + 1)); filter.add( Predicates.or(new CardTypePredicate(CardType.ARTIFACT), - new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.ENCHANTMENT), - new CardTypePredicate(CardType.LAND), - new CardTypePredicate(CardType.PLANESWALKER) + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.ENCHANTMENT), + new CardTypePredicate(CardType.LAND), + new CardTypePredicate(CardType.PLANESWALKER) )); TargetCard target1 = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, filter); target1.setRequired(false); controller.choose(Outcome.PutCardInPlay, cards, target1, game); - for (UUID cardId: target1.getTargets()) { + for (UUID cardId : target1.getTargets()) { Card card = cards.get(cardId, game); if (card != null) { cards.remove(card); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/MistmeadowWitch.java b/Mage.Sets/src/mage/sets/shadowmoor/MistmeadowWitch.java index 0b85cca6af5..f5acde0684e 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/MistmeadowWitch.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/MistmeadowWitch.java @@ -36,7 +36,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnFromExileEffect; @@ -62,7 +61,6 @@ public class MistmeadowWitch extends CardImpl { // {2}{W}{U}: Exile target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MistmeadowWitchEffect(), new ManaCostsImpl("{2}{W}{U}")); - ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/BantPanorama.java b/Mage.Sets/src/mage/sets/shardsofalara/BantPanorama.java index 99e9f76453b..d93ffc176f5 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/BantPanorama.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/BantPanorama.java @@ -28,10 +28,6 @@ package mage.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; @@ -40,6 +36,10 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -68,7 +68,10 @@ public class BantPanorama extends CardImpl { super(ownerId, 221, "Bant Panorama", Rarity.COMMON, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ALA"; + // {T}: Add {1} to your mana pool. this.addAbility(new ColorlessManaAbility()); + + // {1}, {T}, Sacrifice Bant Panorama: Search your library for a basic Forest, Plains, or Island card and put it onto the battlefield tapped. Then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(filter); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/NayaCharm.java b/Mage.Sets/src/mage/sets/shardsofalara/NayaCharm.java index ecca5d6752a..cc48836bb53 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/NayaCharm.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/NayaCharm.java @@ -29,19 +29,14 @@ package mage.sets.shardsofalara; import java.util.List; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPlayer; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCreaturePermanent; @@ -56,7 +51,6 @@ public class NayaCharm extends CardImpl { super(ownerId, 180, "Naya Charm", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}{G}{W}"); this.expansionSetCode = "ALA"; - // Choose one - Naya Charm deals 3 damage to target creature; this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -67,7 +61,7 @@ public class NayaCharm extends CardImpl { this.getSpellAbility().addMode(mode); // or tap all creatures target player controls. mode = new Mode(); - mode.getEffects().add(new NayaCharmEffect()); + mode.getEffects().add(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures"))); mode.getTargets().add(new TargetPlayer()); this.getSpellAbility().addMode(mode); } @@ -81,36 +75,3 @@ public class NayaCharm extends CardImpl { return new NayaCharm(this); } } - -class NayaCharmEffect extends OneShotEffect { - - public NayaCharmEffect() { - super(Outcome.Tap); - staticText = "Tap all creatures target player controls"; - } - - public NayaCharmEffect(final NayaCharmEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getFirstTarget() == null) { - return false; - } - - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new ControllerIdPredicate(source.getFirstTarget())); - - List creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent creature : creatures) { - creature.tap(game); - } - return true; - } - - @Override - public NayaCharmEffect copy() { - return new NayaCharmEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/starter1999/BlindingLight.java b/Mage.Sets/src/mage/sets/starter1999/BlindingLight.java new file mode 100644 index 00000000000..2d56300260e --- /dev/null +++ b/Mage.Sets/src/mage/sets/starter1999/BlindingLight.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.sets.starter1999; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class BlindingLight extends mage.sets.mirage.BlindingLight { + + public BlindingLight(UUID ownerId) { + super(ownerId); + this.cardNumber = 8; + this.expansionSetCode = "S99"; + this.rarity = Rarity.RARE; + } + + public BlindingLight(final BlindingLight card) { + super(card); + } + + @Override + public BlindingLight copy() { + return new BlindingLight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/stronghold/StrongholdTaskmaster.java b/Mage.Sets/src/mage/sets/stronghold/StrongholdTaskmaster.java new file mode 100644 index 00000000000..b195202367a --- /dev/null +++ b/Mage.Sets/src/mage/sets/stronghold/StrongholdTaskmaster.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.stronghold; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class StrongholdTaskmaster extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("black creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public StrongholdTaskmaster(UUID ownerId) { + super(ownerId, 22, "Stronghold Taskmaster", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.expansionSetCode = "STH"; + this.subtype.add("Giant"); + this.subtype.add("Minion"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Other black creatures get -1/-1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(-1, -1, + Duration.WhileOnBattlefield, filter, true))); + } + + public StrongholdTaskmaster(final StrongholdTaskmaster card) { + super(card); + } + + @Override + public StrongholdTaskmaster copy() { + return new StrongholdTaskmaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/tempest/Shocker.java b/Mage.Sets/src/mage/sets/tempest/Shocker.java new file mode 100644 index 00000000000..4ed38a71f35 --- /dev/null +++ b/Mage.Sets/src/mage/sets/tempest/Shocker.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.sets.tempest; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author markedagain + */ +public class Shocker extends CardImpl { + + public Shocker(UUID ownerId) { + super(ownerId, 204, "Shocker", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "TMP"; + this.subtype.add("Insect"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Shocker deals damage to a player, that player discards all the cards in his or her hand, then draws that many cards. + this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new ShockerEffect(), false, true)); + } + + public Shocker(final Shocker card) { + super(card); + } + + @Override + public Shocker copy() { + return new Shocker(this); + } +} +class ShockerEffect extends OneShotEffect { + + public ShockerEffect() { + super(Outcome.Discard); + this.staticText = " that player discards all the cards in his or her hand, then draws that many cards"; + } + + public ShockerEffect(final ShockerEffect effect) { + super(effect); + } + + @Override + public ShockerEffect copy() { + return new ShockerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetPlayer != null) { + int count = targetPlayer.getHand().size(); + for (Card card : targetPlayer.getHand().getCards(game)) { + targetPlayer.discard(card, source, game); + } + targetPlayer.drawCards(count, game); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java index e1edcb283c4..6348e83d0dd 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -100,4 +100,4 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect { public TeferisMoatRestrictionEffect copy() { return new TeferisMoatRestrictionEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/timespiral/BarbedShocker.java b/Mage.Sets/src/mage/sets/timespiral/BarbedShocker.java new file mode 100644 index 00000000000..28587af3873 --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/BarbedShocker.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.sets.timespiral; + +import java.util.UUID; + +/** + * + * @author markedagain + */ +public class BarbedShocker extends mage.sets.conspiracy.BarbedShocker { + + public BarbedShocker(UUID ownerId) { + super(ownerId); + this.cardNumber = 144; + this.expansionSetCode = "TSP"; + } + + public BarbedShocker(final BarbedShocker card) { + super(card); + } + + @Override + public BarbedShocker copy() { + return new BarbedShocker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/MwonvuliAcidMoss.java b/Mage.Sets/src/mage/sets/timespiral/MwonvuliAcidMoss.java new file mode 100644 index 00000000000..7bb54c0dd5b --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/MwonvuliAcidMoss.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.timespiral; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterBasicLandCard; +import mage.filter.common.FilterLandCard; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author markedagain + */ +public class MwonvuliAcidMoss extends CardImpl { + + public MwonvuliAcidMoss(UUID ownerId) { + super(ownerId, 207, "Mwonvuli Acid-Moss", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + this.expansionSetCode = "TSP"; + + FilterLandCard filterForest = new FilterLandCard(); + filterForest.add(new SubtypePredicate("Forest")); + + // 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().addTarget(new TargetPermanent(new FilterLandPermanent())); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterForest), false, true)); + } + + public MwonvuliAcidMoss(final MwonvuliAcidMoss card) { + super(card); + } + + @Override + public MwonvuliAcidMoss copy() { + return new MwonvuliAcidMoss(this); + } +} + diff --git a/Mage.Sets/src/mage/sets/urzassaga/UrzasArmor.java b/Mage.Sets/src/mage/sets/urzassaga/UrzasArmor.java index 7fa3650a39f..0953ec58d9e 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/UrzasArmor.java +++ b/Mage.Sets/src/mage/sets/urzassaga/UrzasArmor.java @@ -28,14 +28,14 @@ package mage.sets.urzassaga; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.PreventionEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -66,7 +66,7 @@ public class UrzasArmor extends CardImpl { class UrzasArmorEffect extends PreventionEffectImpl { public UrzasArmorEffect() { - super(Duration.WhileOnBattlefield); + super(Duration.WhileOnBattlefield, 1, false, false); this.staticText = "If a source would deal damage to you, prevent 1 of that damage"; } @@ -75,28 +75,14 @@ class UrzasArmorEffect extends PreventionEffectImpl { } @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), 1, false); - if (!game.replaceEvent(preventEvent)) { - int damage = event.getAmount(); - if (damage > 0) { - event.setAmount(damage - 1); - game.informPlayers("1 damage has been prevented."); - } - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), 1)); - } - return false; - } - - @Override - public boolean apply(Game game, Ability source) { - return true; + public boolean checksEventType(GameEvent event, Game game) { + return event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER); } @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER) && event.getTargetId().equals(source.getControllerId())) { - return super.applies(event, source, game); + if (event.getTargetId().equals(source.getControllerId())) { + return super.applies(event, source, game); } return false; } diff --git a/Mage.Sets/src/mage/sets/urzassaga/VampiricEmbrace.java b/Mage.Sets/src/mage/sets/urzassaga/VampiricEmbrace.java index 6aebd11671e..e8157d73dcb 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/VampiricEmbrace.java +++ b/Mage.Sets/src/mage/sets/urzassaga/VampiricEmbrace.java @@ -28,12 +28,6 @@ package mage.sets.urzassaga; import java.util.UUID; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.DiesAndDealtDamageThisTurnTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -44,6 +38,12 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -59,19 +59,18 @@ public class VampiricEmbrace extends CardImpl { this.expansionSetCode = "USG"; this.subtype.add("Aura"); - // Enchant creature - TargetPermanent auraTarget = new TargetCreaturePermanent(); + 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/+2 and has flying. + + // Enchanted creature gets +2/+2 and has flying. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); - - // Whenever a creature dealt damage by enchanted creature this turn dies, put a +1/+1 counter on that creature. + + // Whenever a creature dealt damage by enchanted creature this turn dies, put a +1/+1 counter on that creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new DiesAndDealtDamageThisTurnTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false), AttachmentType.AURA))); } diff --git a/Mage.Sets/src/mage/sets/weatherlight/HarvestWurm.java b/Mage.Sets/src/mage/sets/weatherlight/HarvestWurm.java new file mode 100644 index 00000000000..075ebcb48e0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/weatherlight/HarvestWurm.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.weatherlight; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.ReturnToHandFromGraveyardCost; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterBasicLandCard; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author markedagain + */ +public class HarvestWurm extends CardImpl { + + public HarvestWurm(UUID ownerId) { + super(ownerId, 72, "Harvest Wurm", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "WTH"; + this.subtype.add("Wurm"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Harvest Wurm enters the battlefield, sacrifice it unless you return a basic land card from your graveyard to your hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandFromGraveyardCost(new TargetCardInYourGraveyard(new FilterBasicLandCard()))))); + } + + public HarvestWurm(final HarvestWurm card) { + super(card); + } + + @Override + public HarvestWurm copy() { + return new HarvestWurm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java index 6766cf3467c..e2fd1b88a42 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java +++ b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java @@ -43,7 +43,6 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.events.GameEvent; @@ -54,7 +53,7 @@ import mage.target.TargetCard; import mage.watchers.Watcher; /** - * + * * @author Rafbill */ public class SummoningTrap extends CardImpl { @@ -65,7 +64,6 @@ public class SummoningTrap extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Trap"); - // If a creature spell you cast this turn was countered by a spell or // ability an opponent controlled, you may pay {0} rather than pay // Summoning Trap's mana cost. @@ -117,7 +115,7 @@ class SummoningTrapWatcher extends Watcher { if (counterObject == null) { counterObject = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK); } - if (stackObject != null && counterObject != null + if (stackObject != null && counterObject != null && stackObject.getCardType().contains(CardType.CREATURE) && game.getOpponents(controllerId).contains(counterObject.getControllerId())) { condition = true; @@ -145,10 +143,7 @@ class SummoningTrapAlternativeCost extends AlternativeCostImpl { @Override public boolean isAvailable(Game game, Ability source) { Watcher watcher = game.getState().getWatchers().get("CreatureSpellCountered", source.getControllerId()); - if (watcher != null && watcher.conditionMet()) { - return true; - } - return false; + return watcher != null && watcher.conditionMet(); } @Override @@ -170,54 +165,32 @@ class SummoningTrapEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - - Cards cards = new CardsImpl(Zone.PICK); - int count = Math.min(player.getLibrary().size(), 7); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; } - + Cards cards = new CardsImpl(Zone.LIBRARY); + cards.addAll(controller.getLibrary().getTopCards(game, 7)); if (!cards.isEmpty()) { - TargetCard target = new TargetCard(Zone.PICK, + TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard( - "creature card to put on the battlefield")); - if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) { + "creature card to put on the battlefield")); + if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.putOntoBattlefield(game, Zone.PICK, - source.getSourceId(), source.getControllerId()); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); } } if (cards.size() > 0) { - TargetCard target2 = new TargetCard(Zone.PICK, - new FilterCard( - "card to put on the bottom of your library")); - while (player.isInGame() && cards.size() > 1) { - player.choose(Outcome.Benefit, cards, target2, - game); - Card card = cards.get(target2.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - player.getLibrary().putOnBottom(card, game); - } - target2.clearChosen(); - } - Card card = cards.get(cards.iterator().next(), game); - cards.remove(card); - player.getLibrary().putOnBottom(card, game); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); } } - - return false; + return true; } @Override public SummoningTrapEffect copy() { return new SummoningTrapEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DashTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DashTest.java index 5305854a07a..e5f3b6f0167 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DashTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DashTest.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 org.mage.test.cards.abilities.keywords; import mage.constants.PhaseStep; @@ -40,26 +39,25 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class DashTest extends CardTestPlayerBase { /** - * 702.108. Dash - * 702.108a Dash represents three abilities: two static abilities that function while the card with dash is - * on the stack, one of which may create a delayed triggered ability, and a static ability that - * functions while the object with dash is on the battlefield. “Dash [cost]” means “You may cast - * this card by paying [cost] rather that its mana cost,” “If this spell’s dash cost was paid, return the - * permanent this spell becomes to its owner’s hand at the beginning of the next end step,” and “As - * long as this permanent’s dash cost was paid, it has haste.” Paying a card’s dash cost follows the - * rules for paying alternative costs in rules 601.2b and 601.2e–g. - * - */ - - /** - * Screamreach Brawler - * Creature — Orc Berserker 2/3, 2R (3) - * Dash {1}{R} (You may cast this spell for its dash cost. If you do, it - * gains haste, and it's returned from the battlefield to its owner's hand - * at the beginning of the next end step.) + * 702.108. Dash 702.108a Dash represents three abilities: two static + * abilities that function while the card with dash is on the stack, one of + * which may create a delayed triggered ability, and a static ability that + * functions while the object with dash is on the battlefield. “Dash [cost]” + * means “You may cast this card by paying [cost] rather that its mana + * cost,” “If this spell’s dash cost was paid, return the permanent this + * spell becomes to its owner’s hand at the beginning of the next end step,” + * and “As long as this permanent’s dash cost was paid, it has haste.” + * Paying a card’s dash cost follows the rules for paying alternative costs + * in rules 601.2b and 601.2e–g. + * + */ + /** + * Screamreach Brawler Creature — Orc Berserker 2/3, 2R (3) Dash {1}{R} (You + * may cast this spell for its dash cost. If you do, it gains haste, and + * it's returned from the battlefield to its owner's hand at the beginning + * of the next end step.) * */ - @Test public void testDash() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); @@ -96,4 +94,30 @@ public class DashTest extends CardTestPlayerBase { } + /** + * Also dash returns creatures to your hand at end of turn even if they died + * that turn. + */ + @Test + public void testDashedCreatureDiesInCombat() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.HAND, playerA, "Screamreach Brawler"); // 2/3 + + addCard(Zone.BATTLEFIELD, playerB, "Geist of the Moors", 1); // 3/1 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Screamreach Brawler"); + setChoice(playerA, "Yes"); + attack(1, playerA, "Screamreach Brawler"); + block(1, playerB, "Geist of the Moors", "Screamreach Brawler"); + + setStopAt(2, PhaseStep.UNTAP); + execute(); + + assertLife(playerB, 20); + assertPermanentCount(playerA, "Screamreach Brawler", 0); + assertHandCount(playerA, "Screamreach Brawler", 0); + assertGraveyardCount(playerA, "Screamreach Brawler", 1); + assertGraveyardCount(playerB, "Geist of the Moors", 1); + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java index 7db71b19598..60e740bb1b3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java @@ -27,9 +27,12 @@ */ package org.mage.test.cards.abilities.keywords; +import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.VigilanceAbility; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -50,17 +53,17 @@ public class RenownTest extends CardTestPlayerBase { attack(3, playerA, "Knight of the Pilgrim's Road"); // 3 damage attack(5, playerA, "Knight of the Pilgrim's Road"); // 4 damage attack(7, playerA, "Knight of the Pilgrim's Road"); // 4 damage - + setStopAt(7, PhaseStep.POSTCOMBAT_MAIN); execute(); assertPowerToughness(playerA, "Knight of the Pilgrim's Road", 4, 3); - + assertLife(playerA, 20); assertLife(playerB, 9); } - + /** * Test renown trigger */ @@ -76,19 +79,19 @@ public class RenownTest extends CardTestPlayerBase { attack(3, playerA, "Relic Seeker"); // 2 damage attack(5, playerA, "Relic Seeker"); // 3 damage - + setStopAt(5, PhaseStep.POSTCOMBAT_MAIN); execute(); assertPowerToughness(playerA, "Relic Seeker", 3, 3); assertHandCount(playerA, "Veteran's Sidearm", 1); - + assertLife(playerA, 20); assertLife(playerB, 15); - } - - /** + } + + /** * Test renown state */ @Test @@ -102,18 +105,19 @@ public class RenownTest extends CardTestPlayerBase { attack(3, playerA, "Honored Hierarch"); // 1 damage attack(5, playerA, "Honored Hierarch"); // 2 damage - + setStopAt(5, PhaseStep.POSTCOMBAT_MAIN); execute(); assertPowerToughness(playerA, "Honored Hierarch", 2, 2); assertTapped("Honored Hierarch", false); assertAbility(playerA, "Honored Hierarch", VigilanceAbility.getInstance(), true); - + assertLife(playerA, 20); assertLife(playerB, 17); - } + } + /** * Test renown > 1 */ @@ -121,7 +125,7 @@ public class RenownTest extends CardTestPlayerBase { public void testRhoxMaulers() { addCard(Zone.BATTLEFIELD, playerA, "Forest", 5); // Trample - // Renown 2 + // Renown 2 addCard(Zone.HAND, playerA, "Rhox Maulers"); // 4/4 castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rhox Maulers"); @@ -129,14 +133,138 @@ public class RenownTest extends CardTestPlayerBase { attack(3, playerA, "Rhox Maulers"); // 4 damage attack(5, playerA, "Rhox Maulers"); // 6 damage attack(7, playerA, "Rhox Maulers"); // 6 damage - + setStopAt(7, PhaseStep.POSTCOMBAT_MAIN); execute(); assertPowerToughness(playerA, "Rhox Maulers", 6, 6); - + assertLife(playerA, 20); assertLife(playerB, 4); - } + } + + /** + * Test renown is gone after zone change + * + * /** + * Test renown is gone after zone change + */ + @Test + public void testRenownGoneAfterZoneChange() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + // Trample + // Renown 2 + addCard(Zone.HAND, playerA, "Rhox Maulers"); // 4/4 + addCard(Zone.HAND, playerA, "Cloudshift"); // 4/4 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rhox Maulers"); + castSpell(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cloudshift", "Rhox Maulers"); + + attack(3, playerA, "Rhox Maulers"); // 4 damage + attack(5, playerA, "Rhox Maulers"); // 6 damage + attack(7, playerA, "Rhox Maulers"); // 4 damage + + setStopAt(7, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 6); + + assertPowerToughness(playerA, "Rhox Maulers", 6, 6); // renown again in turn 7 after the attack + Permanent rhoxMaulers = getPermanent("Rhox Maulers", playerA); + Assert.assertEquals("may not be renown", true, rhoxMaulers.isRenowned()); + + } + + /* + Test renown can be gained again after zone change + */ + @Test + public void testRenownGainedGainAfterZoneChange() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // Renown 1 + // As long as Goblin Glory Chaser is renowned, it has menace. + addCard(Zone.HAND, playerA, "Goblin Glory Chaser"); // 1/1 {R} + addCard(Zone.HAND, playerA, "Cloudshift"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Goblin Glory Chaser"); + castSpell(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cloudshift", "Goblin Glory Chaser"); + + attack(3, playerA, "Goblin Glory Chaser"); // 1 damage + attack(5, playerA, "Goblin Glory Chaser"); // 2 damage + attack(7, playerA, "Goblin Glory Chaser"); // 1 damage + attack(9, playerA, "Goblin Glory Chaser"); // 2 damage + + setStopAt(9, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + Permanent goblin = getPermanent("Goblin Glory Chaser", playerA); + Assert.assertEquals("has has renown", true, goblin.isRenowned()); + assertAbility(playerA, "Goblin Glory Chaser", new MenaceAbility(), true); + assertPowerToughness(playerA, "Goblin Glory Chaser", 2, 2); + + assertLife(playerA, 20); + assertLife(playerB, 14); + + } + + /** + * Ability doesn't trigger when renowned. ("Whenever an opponent casts a + * noncreature spell, if ~ is renowned, ~ deals 2 damage to that player.") + */ + @Test + public void testScabClanBerserker() { + // Renown 1 + // Whenever an opponent casts a noncreature spell, if Scab-Clan Berserker is renowned, Scab-Clan Berserker deals 2 damage to that player. + addCard(Zone.BATTLEFIELD, playerA, "Scab-Clan Berserker"); // 2/2 {1}{R}{R} + + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, "Lightning Bolt"); + + attack(3, playerA, "Scab-Clan Berserker"); // 1 damage + castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + + setStopAt(3, PhaseStep.END_TURN); + execute(); + + Permanent berserker = getPermanent("Scab-Clan Berserker", playerA); + Assert.assertEquals("has has renown", true, berserker.isRenowned()); + assertPowerToughness(playerA, "Scab-Clan Berserker", 3, 3); + + assertLife(playerA, 17); // Lightning Bolt + assertLife(playerB, 16); // 2 from attack 2 from triggered ability + + } + + /** + * Enshrouding Mist (new card from ORI) isn't untapping renowned creatures. + */ + @Test + public void testEnshroudingMist() { + // Renown 1 + // Whenever an opponent casts a noncreature spell, if Scab-Clan Berserker is renowned, Scab-Clan Berserker deals 2 damage to that player. + addCard(Zone.BATTLEFIELD, playerB, "Scab-Clan Berserker"); // 2/2 {1}{R}{R} + + addCard(Zone.BATTLEFIELD, playerB, "Plains", 1); + // Target creature gets +1/+1 until end of turn. Prevent all damage that would dealt to it this turn. If it's renowned, untap it. + addCard(Zone.HAND, playerB, "Enshrouding Mist"); + + attack(2, playerB, "Scab-Clan Berserker"); // 1 damage + castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Enshrouding Mist", "Scab-Clan Berserker"); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + Permanent berserker = getPermanent("Scab-Clan Berserker", playerB); + Assert.assertEquals("has has renown", true, berserker.isRenowned()); + assertPowerToughness(playerB, "Scab-Clan Berserker", 4, 4); // +1 from renowned + 1 from Enshrouding Mist + assertTapped("Scab-Clan Berserker", false); + + assertLife(playerA, 18); // Lightning Bolt + assertLife(playerB, 20); + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java index 8ed4b751656..14e6c0db6a3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java @@ -87,6 +87,41 @@ public class TransformTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Liliana, Heretical Healer", 0); assertPermanentCount(playerA, "Liliana, Defiant Necromancer", 1); assertCounterCount("Liliana, Defiant Necromancer", CounterType.LOYALTY, 3); + + assertPermanentCount(playerA, "Zombie", 1); + + } + + /** + * The creature-Liliana and another creature was out, Languish is cast + * killing both, Liliana comes back transformed and no zombie. I'm fairly + * certain she's not supposed to come back due to her exile trigger + * shouldn't be able to exile her cos she's dead. + */ + @Test + public void LilianaHereticalHealer2() { + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + + // Lifelink + // Whenever another nontoken creature you control dies, exile Liliana Heretical Healer, then return her to the battlefield transformed under her owner's control. If you do, put a 2/2 black Zombie creature token onto the battlefield. + addCard(Zone.BATTLEFIELD, playerA, "Liliana, Heretical Healer"); + + // All creatures get -4/-4 until end of turn. + addCard(Zone.HAND, playerB, "Languish"); + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Languish"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, "Languish", 1); + assertPermanentCount(playerA, "Liliana, Defiant Necromancer", 0); + assertPermanentCount(playerA, "Zombie", 0); + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerA, "Liliana, Heretical Healer", 1); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java new file mode 100644 index 00000000000..6f6eca531c9 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.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 org.mage.test.cards.abilities.other; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class EndTurnEffectTest extends CardTestPlayerBase { + + /** + * Additional bug: Days Undoing and Sphinx's Tutelage are broken. You + * shouldn't get triggers off of Tutelage, since the turn ends, but it has + * you resolve them in your cleanup step. + * + * http://tabakrules.tumblr.com/post/122350751009/days-undoing-has-been-officially-spoiled-on + * + */ + @Test + public void testSpellsAffinity() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + // Whenever you draw a card, target opponent puts the top two cards of his or her library into his or her graveyard. If they're both nonland cards that share a color, repeat this process. + // {5}{U}: Draw a card, then discard a card. + addCard(Zone.BATTLEFIELD, playerA, "Sphinx's Tutelage"); + + // Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. If it's your turn, end the turn. + addCard(Zone.HAND, playerA, "Day's Undoing"); //Sorcery {2}{U} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Day's Undoing"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertExileCount("Day's Undoing", 1); + + assertHandCount(playerA, 7); + assertHandCount(playerB, 7); + + assertGraveyardCount(playerB, 0); // because the trigegrs of Sphinx's Tutelage cease to exist + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/EnsoulArtifactTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/EnsoulArtifactTest.java new file mode 100644 index 00000000000..666bc718b50 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/EnsoulArtifactTest.java @@ -0,0 +1,62 @@ +/* + * 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 org.mage.test.cards.continuous; + +import mage.abilities.keyword.IndestructibleAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class EnsoulArtifactTest extends CardTestPlayerBase { + + /** + * Tests boost disappeared after creature died + */ + @Test + public void testBoostWithUndying() { + addCard(Zone.BATTLEFIELD, playerA, "Darksteel Citadel", 1); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + + // Enchanted artifact is a creature with base power and toughness 5/5 in addition to its other types. + addCard(Zone.HAND, playerA, "Ensoul Artifact"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ensoul Artifact", "Darksteel Citadel"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertAbility(playerA, "Darksteel Citadel", IndestructibleAbility.getInstance(), true); + assertPowerToughness(playerA, "Darksteel Citadel", 5, 5); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/requirement/BlockRequirementTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/requirement/BlockRequirementTest.java index cbd8ba96d6c..6797cdc95a5 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/requirement/BlockRequirementTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/requirement/BlockRequirementTest.java @@ -76,4 +76,40 @@ public class BlockRequirementTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Silvercoat Lion", 1); assertPermanentCount(playerB, "Prized Unicorn", 1); } + + /** + * Joraga Invocation is bugged big time. He cast it with 2 creatures out. I + * only had one untapped creature. Blocked one of his, hit Done, error + * message popped up saying the other one needed to be blocked in an + * infinite loop. Had to shut down the program via Task Manager. + */ + @Test + public void testJoragaInvocationTest() { + addCard(Zone.BATTLEFIELD, playerB, "Forest", 6); + // Each creature you control gets +3/+3 until end of turn and must be blocked this turn if able. + addCard(Zone.HAND, playerB, "Joraga Invocation"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox"); // 2/4 + + // Swampwalk + addCard(Zone.BATTLEFIELD, playerA, "Bog Wraith"); // 3/3 + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Joraga Invocation"); + + // Silvercoat Lion has not to block because it has to pay {3} to block + attack(2, playerB, "Silvercoat Lion"); + attack(2, playerB, "Pillarfield Ox"); + block(2, playerA, "Bog Wraith", "Pillarfield Ox"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 15); + + assertGraveyardCount(playerB, "Joraga Invocation", 1); + assertPowerToughness(playerB, "Silvercoat Lion", 5, 5); + assertPowerToughness(playerB, "Pillarfield Ox", 5, 7); + assertGraveyardCount(playerA, "Bog Wraith", 1); + } + } 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 new file mode 100644 index 00000000000..a6bb72f4050 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java @@ -0,0 +1,71 @@ +/* + * 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 org.mage.test.cards.triggers; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class BecomesTheTargetTest extends CardTestPlayerBase { + + /** + * Willbreaker is not working when an ability is targeting the opponet's + * creature. Only spells. + * + */ + @Test + public void testWillbreakerAbility() { + // Whenever a creature an opponent controls becomes the target of a spell or ability you control, gain control of that creature for as long as you control Willbreaker. + addCard(Zone.BATTLEFIELD, playerB, "Willbreaker", 1); + addCard(Zone.BATTLEFIELD, playerB, "Blinding Souleater", 1); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 1); + + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{WP},{T}: Tap target creature", "Silvercoat Lion"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertPermanentCount(playerA, "Silvercoat Lion", 0); + assertTapped("Silvercoat Lion", true); + + assertPermanentCount(playerB, "Silvercoat Lion", 1); + assertPermanentCount(playerB, "Willbreaker", 1); + assertPermanentCount(playerB, "Blinding Souleater", 1); + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EnterLeaveBattlefieldExileTargetTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EnterLeaveBattlefieldExileTargetTest.java new file mode 100644 index 00000000000..a8088969696 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EnterLeaveBattlefieldExileTargetTest.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 org.mage.test.cards.triggers; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class EnterLeaveBattlefieldExileTargetTest extends CardTestPlayerBase { + + @Test + public void testAngelOfSerenityExile() { + // Flying + // When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards. + // When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands. + addCard(Zone.HAND, playerA, "Angel of Serenity"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 7); + + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Serenity"); + addTarget(playerA, "Silvercoat Lion^Pillarfield Ox"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Angel of Serenity", 1); + assertExileCount("Silvercoat Lion", 1); + assertExileCount("Pillarfield Ox", 1); + + } + + /** + * When Angel of Serenity entered the battlefield on my opponent's main + * phase it exiled 3 of my creatures (as it should), I cast Ultimate Price + * (destroy monocolored creature) on my next main phase and destroyed the + * Angel of Serenity. The log said the exiled cards were returned to my hand + * but they remained in exile indefinitely. + */ + @Test + public void testAngelOfSerenityExileReturn() { + // Flying + // When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards. + // When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands. + addCard(Zone.HAND, playerA, "Angel of Serenity"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 7); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1); + addCard(Zone.HAND, playerB, "Ultimate Price", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Serenity"); + addTarget(playerA, "Silvercoat Lion^Pillarfield Ox"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ultimate Price", "Angel of Serenity"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, "Ultimate Price", 1); + assertGraveyardCount(playerA, "Angel of Serenity", 1); + assertHandCount(playerB, "Silvercoat Lion", 1); + assertHandCount(playerB, "Pillarfield Ox", 1); + assertExileCount(playerB, 0); + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/JournexToNowhereTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/JourneyToNowhereTest.java similarity index 96% rename from Mage.Tests/src/test/java/org/mage/test/cards/triggers/JournexToNowhereTest.java rename to Mage.Tests/src/test/java/org/mage/test/cards/triggers/JourneyToNowhereTest.java index 9199ba892e2..8cef82f8998 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/JournexToNowhereTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/JourneyToNowhereTest.java @@ -37,7 +37,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * @author LeveX2 */ -public class JournexToNowhereTest extends CardTestPlayerBase { +public class JourneyToNowhereTest extends CardTestPlayerBase { /* Journey to Nowhere Enchantment {1}{W} diff --git a/Mage.Tests/src/test/java/org/mage/test/combat/RemoveFromCombatTest.java b/Mage.Tests/src/test/java/org/mage/test/combat/RemoveFromCombatTest.java new file mode 100644 index 00000000000..e77aa7428d7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/combat/RemoveFromCombatTest.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 org.mage.test.combat; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class RemoveFromCombatTest extends CardTestPlayerBase { + + /** + * In a test game against the AI, it attacked me with a Stomping Ground + * animated by an Ambush Commander and boosted it with the Commander's + * second ability. I killed the Commander. The now non-creature land + * continued attacking and dealt 3 damage to me. + */ + @Test + public void testLeavesCombatIfNoLongerACreature() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + + // Forests you control are 1/1 green Elf creatures that are still lands. + // {1}{G}, Sacrifice an Elf: Target creature gets +3/+3 until end of turn. + addCard(Zone.BATTLEFIELD, playerB, "Ambush Commander", 1); + addCard(Zone.BATTLEFIELD, playerB, "Stomping Ground"); + + attack(2, playerB, "Stomping Ground"); + castSpell(2, PhaseStep.DECLARE_BLOCKERS, playerA, "Lightning Bolt", "Ambush Commander"); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, "Lightning Bolt", 1); + assertGraveyardCount(playerB, "Ambush Commander", 1); + + assertPowerToughness(playerB, "Stomping Ground", 0, 0); + + } + +} diff --git a/Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java b/Mage/src/mage/abilities/common/BecomesRenownedSourceTriggeredAbility.java similarity index 68% rename from Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java rename to Mage/src/mage/abilities/common/BecomesRenownedSourceTriggeredAbility.java index 0864328cee7..290215f9239 100644 --- a/Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BecomesRenownedSourceTriggeredAbility.java @@ -15,28 +15,27 @@ import mage.game.events.GameEvent; * * @author LevelX2 */ - -public class BecomesRenownSourceTriggeredAbility extends TriggeredAbilityImpl { +public class BecomesRenownedSourceTriggeredAbility extends TriggeredAbilityImpl { private int renownValue; - public BecomesRenownSourceTriggeredAbility(Effect effect, boolean optional) { + public BecomesRenownedSourceTriggeredAbility(Effect effect, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); } - public BecomesRenownSourceTriggeredAbility(final BecomesRenownSourceTriggeredAbility ability) { + public BecomesRenownedSourceTriggeredAbility(final BecomesRenownedSourceTriggeredAbility ability) { super(ability); this.renownValue = ability.renownValue; } @Override - public BecomesRenownSourceTriggeredAbility copy() { - return new BecomesRenownSourceTriggeredAbility(this); + public BecomesRenownedSourceTriggeredAbility copy() { + return new BecomesRenownedSourceTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.BECOMES_RENOWN; + return event.getType() == GameEvent.EventType.BECOMES_RENOWNED; } @Override @@ -54,6 +53,6 @@ public class BecomesRenownSourceTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When {this} becomes monstrous, " + super.getRule(); + return "When {this} becomes renowned, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java b/Mage/src/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java new file mode 100644 index 00000000000..7045c08433b --- /dev/null +++ b/Mage/src/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java @@ -0,0 +1,52 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.SpellAbility; +import mage.abilities.costs.mana.ManaCosts; +import mage.cards.Card; +import mage.constants.SpellAbilityType; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class PayMoreToCastAsThoughtItHadFlashAbility extends SpellAbility { + + private final ManaCosts costsToAdd; + + public PayMoreToCastAsThoughtItHadFlashAbility(Card card, ManaCosts costsToAdd) { + super(card.getSpellAbility().getManaCosts().copy(), card.getName() + " as though it had flash", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); + this.costsToAdd = costsToAdd; + this.timing = TimingRule.INSTANT; + + CardUtil.increaseCost(this, costsToAdd); + } + + public PayMoreToCastAsThoughtItHadFlashAbility(final PayMoreToCastAsThoughtItHadFlashAbility ability) { + super(ability); + this.costsToAdd = ability.costsToAdd; + } + + @Override + public PayMoreToCastAsThoughtItHadFlashAbility copy() { + return new PayMoreToCastAsThoughtItHadFlashAbility(this); + } + + @Override + public String getRule(boolean all) { + return getRule(); + } + + @Override + public String getRule() { + return "You may cast {this} as though it had flash if you pay " + costsToAdd.getText() + " more to cast it. (You may cast it any time you could cast an instant)"; + } + +} diff --git a/Mage/src/mage/abilities/condition/common/CardsInControllerGraveCondition.java b/Mage/src/mage/abilities/condition/common/CardsInControllerGraveCondition.java index d36c9c96870..2cd6cef755e 100644 --- a/Mage/src/mage/abilities/condition/common/CardsInControllerGraveCondition.java +++ b/Mage/src/mage/abilities/condition/common/CardsInControllerGraveCondition.java @@ -2,6 +2,7 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; @@ -14,20 +15,31 @@ import mage.util.CardUtil; public class CardsInControllerGraveCondition implements Condition { private final int value; + private final FilterCard filter; public CardsInControllerGraveCondition(int value) { + this(value, null); + } + + public CardsInControllerGraveCondition(int value, FilterCard filter) { this.value = value; + this.filter = filter; } @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); + if (filter != null) { + return player != null && player.getGraveyard().count(filter, source.getSourceId(), source.getControllerId(), game) >= value; + } return player != null && player.getGraveyard().size() >= value; } @Override public String toString() { - return "there are " + CardUtil.numberToText(value, "one") + " or more cards in your graveyard"; + return "there are " + CardUtil.numberToText(value, "one") + " or more " + + (filter == null ? "cards" : filter.getMessage()) + + " in your graveyard"; } } diff --git a/Mage/src/mage/abilities/condition/common/RenownCondition.java b/Mage/src/mage/abilities/condition/common/RenownedSourceCondition.java similarity index 69% rename from Mage/src/mage/abilities/condition/common/RenownCondition.java rename to Mage/src/mage/abilities/condition/common/RenownedSourceCondition.java index 1e00bba4426..edd058a64b2 100644 --- a/Mage/src/mage/abilities/condition/common/RenownCondition.java +++ b/Mage/src/mage/abilities/condition/common/RenownedSourceCondition.java @@ -16,15 +16,15 @@ import mage.game.permanent.Permanent; * @author LevelX2 */ -public class RenownCondition implements Condition { +public class RenownedSourceCondition implements Condition { - private static RenownCondition fInstance = null; + private static RenownedSourceCondition fInstance = null; - private RenownCondition() {} + private RenownedSourceCondition() {} - public static RenownCondition getInstance() { + public static RenownedSourceCondition getInstance() { if (fInstance == null) { - fInstance = new RenownCondition(); + fInstance = new RenownedSourceCondition(); } return fInstance; } @@ -33,7 +33,7 @@ public class RenownCondition implements Condition { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { - return permanent.isRenown(); + return permanent.isRenowned(); } return false; } diff --git a/Mage/src/mage/abilities/condition/common/RenownedTargetCondition.java b/Mage/src/mage/abilities/condition/common/RenownedTargetCondition.java new file mode 100644 index 00000000000..0d822b288d5 --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/RenownedTargetCondition.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.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class RenownedTargetCondition implements Condition { + + private static RenownedTargetCondition fInstance = null; + + private RenownedTargetCondition() { + } + + public static RenownedTargetCondition getInstance() { + if (fInstance == null) { + fInstance = new RenownedTargetCondition(); + } + return fInstance; + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget()); + if (permanent != null) { + return permanent.isRenowned(); + } + return false; + } + + @Override + public String toString() { + return "it's renowned"; + } + +} diff --git a/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java b/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java new file mode 100644 index 00000000000..91b85072c9a --- /dev/null +++ b/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.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.abilities.costs.common; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.CostImpl; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author markedagain + */ +public class ReturnToHandFromGraveyardCost extends CostImpl { + + public ReturnToHandFromGraveyardCost(TargetCardInYourGraveyard target) { + this.addTarget(target); + if (target.getMaxNumberOfTargets() > 1 && target.getMaxNumberOfTargets() == target.getNumberOfTargets()) { + this.text = new StringBuilder("return ").append(target.getMaxNumberOfTargets()).append(" ").append(target.getTargetName()).append(" from graveyard to it's owner's hand").toString(); + } else { + this.text = new StringBuilder("return ").append(target.getTargetName()).append(" from graveyard to it's owner's hand").toString(); + } + } + public ReturnToHandFromGraveyardCost(ReturnToHandFromGraveyardCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Player controller = game.getPlayer(controllerId); + if (controller != null) { + if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) { + for (UUID targetId: targets.get(0).getTargets()) { + mage.cards.Card targetCard = game.getCard(targetId); + if (targetCard == null) { + return false; + } + paid |= controller.moveCardToHandWithInfo(targetCard, sourceId, game, Zone.HAND); + } + } + } + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + return targets.canChoose(controllerId, game); + } + + @Override + public ReturnToHandFromGraveyardCost copy() { + return new ReturnToHandFromGraveyardCost(this); + } + +} diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index 9f8f39211e3..a6030dc051b 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -214,12 +214,16 @@ public class ContinuousEffects implements Serializable { case WhileOnStack: case WhileInGraveyard: HashSet abilities = layeredEffects.getAbility(effect.getId()); - for (Ability ability : abilities) { - // If e.g. triggerd abilities (non static) created the effect, the ability must not be in usable zone (e.g. Unearth giving Haste effect) - if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) { - layerEffects.add(effect); - break; + if (abilities != null) { + for (Ability ability : abilities) { + // If e.g. triggerd abilities (non static) created the effect, the ability must not be in usable zone (e.g. Unearth giving Haste effect) + if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) { + layerEffects.add(effect); + break; + } } + } else { + logger.error("No abilities for continuous effect: " + effect.toString()); } break; default: @@ -1058,14 +1062,16 @@ public class ContinuousEffects implements Serializable { private void setControllerForEffect(ContinuousEffectsList effects, UUID cardId, UUID controllerId) { for (Effect effect : effects) { HashSet abilities = effects.getAbility(effect.getId()); - for (Ability ability : abilities) { - if (ability.getSourceId() != null) { - if (ability.getSourceId().equals(cardId)) { - ability.setControllerId(controllerId); - } - } else { - if (!ability.getZone().equals(Zone.COMMAND)) { - logger.fatal(new StringBuilder("No sourceId Ability: ").append(ability)); + if (abilities != null) { + for (Ability ability : abilities) { + if (ability.getSourceId() != null) { + if (ability.getSourceId().equals(cardId)) { + ability.setControllerId(controllerId); + } + } else { + if (!ability.getZone().equals(Zone.COMMAND)) { + logger.fatal(new StringBuilder("No sourceId Ability: ").append(ability)); + } } } } diff --git a/Mage/src/mage/abilities/effects/common/CopyTargetSpellEffect.java b/Mage/src/mage/abilities/effects/common/CopyTargetSpellEffect.java index 6d02c2cb8e0..fcec4c594c6 100644 --- a/Mage/src/mage/abilities/effects/common/CopyTargetSpellEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyTargetSpellEffect.java @@ -1,38 +1,36 @@ /* -* 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. -*/ - - + * 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.constants.Outcome; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.stack.Spell; @@ -82,8 +80,11 @@ public class CopyTargetSpellEffect extends OneShotEffect { return new CopyTargetSpellEffect(this); } - @Override + @Override public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } StringBuilder sb = new StringBuilder(); sb.append("copy target ").append(mode.getTargets().get(0).getTargetName()).append(". You may choose new targets for the copy"); return sb.toString(); diff --git a/Mage/src/mage/abilities/effects/common/EndTurnEffect.java b/Mage/src/mage/abilities/effects/common/EndTurnEffect.java index 287e6b6b4e4..2a5608c0f73 100644 --- a/Mage/src/mage/abilities/effects/common/EndTurnEffect.java +++ b/Mage/src/mage/abilities/effects/common/EndTurnEffect.java @@ -25,12 +25,11 @@ * 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.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.game.Game; public class EndTurnEffect extends OneShotEffect { @@ -46,8 +45,9 @@ public class EndTurnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers("The current turn ends"); + } return game.endTurn(); } @@ -56,4 +56,3 @@ public class EndTurnEffect extends OneShotEffect { return new EndTurnEffect(this); } } - diff --git a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java index 3e6bd508bb4..6b57e657d3c 100644 --- a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java @@ -5,49 +5,73 @@ */ package mage.abilities.effects.common; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; /** * * @author LevelX2 */ - public class ExileAndReturnTransformedSourceEffect extends OneShotEffect { - - public static enum Gender { MALE, FEMAL }; - + + public static enum Gender { + + MALE, FEMAL + }; + + protected Effect additionalEffect; + public ExileAndReturnTransformedSourceEffect(Gender gender) { - super(Outcome.Benefit); - this.staticText = "exile {this}, then return " + (gender.equals(Gender.MALE) ? "him":"her") - + " to the battlefield transformed under" + (gender.equals(Gender.MALE) ? "his":"her")+ " owner's control"; + this(gender, null); } - + + /** + * @param gender + * @param additionalEffect that effect is applies as source is exiled + */ + public ExileAndReturnTransformedSourceEffect(Gender gender, Effect additionalEffect) { + super(Outcome.Benefit); + this.additionalEffect = additionalEffect; + this.staticText = "exile {this}, then return " + (gender.equals(Gender.MALE) ? "him" : "her") + + " to the battlefield transformed under" + (gender.equals(Gender.MALE) ? "his" : "her") + " owner's control"; + } + public ExileAndReturnTransformedSourceEffect(final ExileAndReturnTransformedSourceEffect effect) { super(effect); + this.additionalEffect = effect.additionalEffect; } - + @Override public ExileAndReturnTransformedSourceEffect copy() { return new ExileAndReturnTransformedSourceEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - MageObject sourceObject = source.getSourceObjectIfItStillExists(game); + // Creature has to be on the battlefield to get exiled and be able to return transformed + Permanent sourceObject = game.getPermanent(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); if (sourceObject != null && controller != null) { Card card = (Card) sourceObject; if (controller.moveCards(card, Zone.BATTLEFIELD, Zone.EXILED, source, game)) { game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + if (additionalEffect != null) { + if (additionalEffect instanceof ContinuousEffect) { + game.addEffect((ContinuousEffect) additionalEffect, source); + } else { + additionalEffect.apply(game, source); + } + } } } return true; diff --git a/Mage/src/mage/abilities/effects/common/RegenerateAllEffect.java b/Mage/src/mage/abilities/effects/common/RegenerateAllEffect.java index fd53bae45be..c23b072fbf3 100644 --- a/Mage/src/mage/abilities/effects/common/RegenerateAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/RegenerateAllEffect.java @@ -25,12 +25,11 @@ * 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.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -40,10 +39,9 @@ import mage.target.targetpointer.FixedTarget; * * @author LevelX2 */ +public class RegenerateAllEffect extends OneShotEffect { - public class RegenerateAllEffect extends OneShotEffect { - - private FilterPermanent filter; + private final FilterPermanent filter; public RegenerateAllEffect(FilterPermanent filter) { super(Outcome.DestroyPermanent); diff --git a/Mage/src/mage/abilities/effects/common/ReturnFromExileForSourceEffect.java b/Mage/src/mage/abilities/effects/common/ReturnFromExileForSourceEffect.java index f1e23475651..181bb35f94c 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnFromExileForSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnFromExileForSourceEffect.java @@ -1,35 +1,32 @@ /* -* 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. -*/ - + * 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 java.util.LinkedList; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -41,6 +38,7 @@ import static mage.constants.Zone.GRAVEYARD; import static mage.constants.Zone.HAND; import mage.game.ExileZone; import mage.game.Game; +import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.util.CardUtil; @@ -55,7 +53,7 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect { private boolean previousZone; /** - * + * * @param zone Zone the card should return to */ public ReturnFromExileForSourceEffect(Zone zone) { @@ -65,12 +63,13 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect { public ReturnFromExileForSourceEffect(Zone zone, boolean tapped) { this(zone, tapped, true); } - + /** - * + * * @param zone * @param tapped - * @param previousZone if this is used from a dies leave battlefield or destroyed trigger, the exile zone is based on previous zone of the object + * @param previousZone if this is used from a dies leave battlefield or + * destroyed trigger, the exile zone is based on previous zone of the object */ public ReturnFromExileForSourceEffect(Zone zone, boolean tapped, boolean previousZone) { super(Outcome.PutCardInPlay); @@ -94,24 +93,25 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - int zoneChangeCounter = source.getSourceObjectZoneChangeCounter() - (previousZone ? 1:0); - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter); - ExileZone exile = game.getExile().getExileZone(exileId); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null) { + int zoneChangeCounter = source.getSourceObjectZoneChangeCounter(); + if (zoneChangeCounter > 0 && previousZone && !(sourceObject instanceof PermanentToken)) { + zoneChangeCounter--; + } + ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); if (exile != null) { // null is valid if source left battlefield before enters the battlefield effect resolved - LinkedList cards = new LinkedList<>(exile); - for (UUID cardId: cards) { - Card card = game.getCard(cardId); - if (card == null) { - return false; + if (returnToZone.equals(Zone.BATTLEFIELD)) { + for (Card card : exile.getCards(game)) { + Player owner = game.getPlayer(card.getOwnerId()); + if (owner != null) { + owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + } } - if (!game.isSimulation()) { - game.informPlayers(controller.getLogName() + " moves " + card.getLogName() + " from exile to " + returnToZone.toString().toLowerCase()); - } - card.moveToZone(returnToZone, source.getSourceId(), game, tapped); + } else { + controller.moveCards(exile, Zone.EXILED, returnToZone, source, game); } - exile.clear(); } return true; } @@ -121,7 +121,7 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); sb.append("return the exiled cards "); - switch(returnToZone) { + switch (returnToZone) { case BATTLEFIELD: sb.append("to the battlefield under its owner's control"); if (tapped) { diff --git a/Mage/src/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java b/Mage/src/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java new file mode 100644 index 00000000000..0ad564a7211 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.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.abilities.effects.common; + +import java.util.List; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LoneFox + */ +public class TapAllTargetPlayerControlsEffect extends OneShotEffect { + + private FilterPermanent filter; + + public TapAllTargetPlayerControlsEffect(FilterPermanent filter) { + super(Outcome.Tap); + this.filter = filter; + } + + public TapAllTargetPlayerControlsEffect(final TapAllTargetPlayerControlsEffect effect) { + super(effect); + filter = effect.filter.copy(); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if(player != null) { + filter.add(new ControllerIdPredicate(player.getId())); + List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); + for(Permanent p : permanents) { + p.tap(game); + } + return true; + } + return false; + } + + @Override + public TapAllTargetPlayerControlsEffect copy() { + return new TapAllTargetPlayerControlsEffect(this); + } + + @Override + public String getText(Mode mode) { + if(staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "tap all " + filter.getMessage() + " target player controls"; + } +} diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java index 18463843955..4c359b4aa37 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java @@ -1,7 +1,29 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * 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.combat; diff --git a/Mage/src/mage/abilities/effects/common/combat/CantBlockUnlessPayManaAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantBlockUnlessPayManaAllEffect.java new file mode 100644 index 00000000000..f8d42a4c4b9 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/combat/CantBlockUnlessPayManaAllEffect.java @@ -0,0 +1,88 @@ +/* + * 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.combat; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.effects.PayCostToAttackBlockEffectImpl; +import mage.abilities.effects.PayCostToAttackBlockEffectImpl.RestrictType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class CantBlockUnlessPayManaAllEffect extends PayCostToAttackBlockEffectImpl { + + private final FilterCreaturePermanent filterCreaturePermanent; + + public CantBlockUnlessPayManaAllEffect(ManaCosts manaCosts) { + this(manaCosts, false); + } + + public CantBlockUnlessPayManaAllEffect(ManaCosts manaCosts, boolean payAlsoForAttackingPlaneswalker) { + this(manaCosts, payAlsoForAttackingPlaneswalker, null); + } + + public CantBlockUnlessPayManaAllEffect(ManaCosts manaCosts, boolean payAlsoForAttackingPlaneswalker, FilterCreaturePermanent filter) { + super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.BLOCK, manaCosts); + this.filterCreaturePermanent = filter; + staticText = (filterCreaturePermanent == null ? "Creatures" : filterCreaturePermanent.getMessage()) + + " can't block " + + "unless their controller pays " + + (manaCosts == null ? "" : manaCosts.getText()) + + " for each blocking creature he or she controls"; + } + + public CantBlockUnlessPayManaAllEffect(CantBlockUnlessPayManaAllEffect effect) { + super(effect); + this.filterCreaturePermanent = effect.filterCreaturePermanent; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + // check if blocking creature fullfills filter criteria + if (filterCreaturePermanent != null) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (!filterCreaturePermanent.match(permanent, source.getSourceId(), source.getControllerId(), game)) { + return false; + } + } + return true; + } + + @Override + public CantBlockUnlessPayManaAllEffect copy() { + return new CantBlockUnlessPayManaAllEffect(this); + } +} diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java index cf5a907365e..1658b00fc80 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java @@ -155,14 +155,9 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl { break; case PTChangingEffects_7: if (sublayer == SubLayer.SetPT_7b) { - switch (loseType) { - case ALL: - case ALL_BUT_COLOR: - case ABILITIES_AND_PT: - permanent.getPower().setValue(token.getPower().getValue()); - permanent.getToughness().setValue(token.getToughness().getValue()); - break; - } + permanent.getPower().setValue(token.getPower().getValue()); + permanent.getToughness().setValue(token.getToughness().getValue()); + break; } } } diff --git a/Mage/src/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java b/Mage/src/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java index c617a4cf249..775b4cdb745 100644 --- a/Mage/src/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/cost/SpellCostReductionSourceEffect.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.cost; import mage.abilities.Ability; @@ -39,19 +38,17 @@ import mage.constants.Outcome; import mage.game.Game; import mage.util.CardUtil; - /** * * @author LevelX2 */ - public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { private final int amount; private ManaCosts manaCostsToReduce = null; private final Condition condition; - public SpellCostReductionSourceEffect(ManaCosts manaCostsToReduce, Condition condition) { + public SpellCostReductionSourceEffect(ManaCosts manaCostsToReduce, Condition condition) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.amount = 0; this.manaCostsToReduce = manaCostsToReduce; @@ -59,14 +56,13 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { StringBuilder sb = new StringBuilder(); sb.append("{this} costs "); - for (String manaSymbol :manaCostsToReduce.getSymbols()) { + for (String manaSymbol : manaCostsToReduce.getSymbols()) { sb.append(manaSymbol); } sb.append(" less to if ").append(this.condition.toString()); this.staticText = sb.toString(); } - public SpellCostReductionSourceEffect(int amount, Condition condition) { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); this.amount = amount; @@ -76,7 +72,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { this.staticText = sb.toString(); } - protected SpellCostReductionSourceEffect(SpellCostReductionSourceEffect effect) { + protected SpellCostReductionSourceEffect(final SpellCostReductionSourceEffect effect) { super(effect); this.amount = effect.amount; this.manaCostsToReduce = effect.manaCostsToReduce; @@ -85,7 +81,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { - if (manaCostsToReduce != null){ + if (manaCostsToReduce != null) { CardUtil.adjustCost((SpellAbility) abilityToModify, manaCostsToReduce, false); } else { CardUtil.reduceCost(abilityToModify, this.amount); @@ -95,7 +91,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) { + if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) { return condition.apply(game, source); } return false; diff --git a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java index e88dd52e0b4..76462b5b011 100644 --- a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java @@ -73,9 +73,9 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { public DiscardCardYouChooseTargetEffect(FilterCard filter) { this(filter, TargetController.OPPONENT); } - + public DiscardCardYouChooseTargetEffect(TargetController targetController, int numberCardsToReveal) { - this(new FilterCard("one card"), targetController, + this(new FilterCard("one card"), targetController, new StaticValue(numberCardsToReveal, new StringBuilder(CardUtil.numberToText(numberCardsToReveal)).append(" cards").toString())); } @@ -87,28 +87,28 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { super(Outcome.Discard); this.targetController = targetController; this.filter = filter; - + this.revealAllCards = false; this.numberCardsToReveal = numberCardsToReveal; this.numberCardsToDiscard = new StaticValue(1); - - staticText = this.setText(); + + staticText = this.setText(); } - + public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController) { this(new StaticValue(1), filter, targetController); } - + public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, FilterCard filter, TargetController targetController) { super(Outcome.Discard); this.targetController = targetController; this.filter = filter; - + this.numberCardsToDiscard = numberCardsToDiscard; this.numberCardsToReveal = null; this.revealAllCards = true; - - staticText = this.setText(); + + staticText = this.setText(); } public DiscardCardYouChooseTargetEffect(final DiscardCardYouChooseTargetEffect effect) { @@ -117,12 +117,12 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { this.targetController = effect.targetController; this.numberCardsToDiscard = effect.numberCardsToDiscard; this.numberCardsToReveal = effect.numberCardsToReveal; - this.revealAllCards = effect.revealAllCards; + this.revealAllCards = effect.revealAllCards; } @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); + Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); Card sourceCard = game.getCard(source.getSourceId()); if (player != null && controller != null) { @@ -131,7 +131,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { } int numberToReveal = this.numberCardsToReveal.calculate(game, source, this); if (numberToReveal > 0) { - Cards revealedCards = new CardsImpl(Zone.HAND); + Cards revealedCards = new CardsImpl(Zone.HAND); numberToReveal = Math.min(player.getHand().size(), numberToReveal); if (player.getHand().size() > numberToReveal) { TargetCardInHand chosenCards = new TargetCardInHand(numberToReveal, numberToReveal, new FilterCard("card in "+ player.getLogName() +"'s hand")); @@ -149,10 +149,10 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { } } else { revealedCards.addAll(player.getHand()); - } + } player.revealCards(sourceCard != null ? sourceCard.getName() :"Discard", revealedCards, game); - + boolean result = true; int filteredCardsCount = revealedCards.count(filter, source.getSourceId(), source.getControllerId(), game); int numberToDiscard = Math.min(this.numberCardsToDiscard.calculate(game, source, this), filteredCardsCount); @@ -220,7 +220,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { } else { sb.append(" of them."); } - + sb.append(" That player discards ").append(discardMultipleCards ? "those cards" : "that card").toString(); return sb.toString(); } diff --git a/Mage/src/mage/abilities/keyword/DashAbility.java b/Mage/src/mage/abilities/keyword/DashAbility.java index 4072e1a8563..4a2d96170f0 100644 --- a/Mage/src/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/mage/abilities/keyword/DashAbility.java @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.common.EntersBattlefieldAbility; @@ -44,7 +45,7 @@ import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.Card; @@ -76,12 +77,9 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts Ability ability = new EntersBattlefieldAbility( new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), DashedCondition.getInstance(), false, "", ""); - Effect effect = new ReturnToHandTargetEffect(); - effect.setText("return the dashed creature from the battlefield to its owner's hand"); - effect.setTargetPointer(new FixedTarget(card.getId())); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), false)); + ability.addEffect(new DashAddDelayedTriggeredAbilityEffect()); addSubAbility(ability); - + } public DashAbility(final DashAbility ability) { @@ -134,7 +132,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts this.resetDash(); for (AlternativeCost2 dashCost : alternativeSourceCosts) { if (dashCost.canPay(ability, sourceId, controllerId, game) - && player.chooseUse(Outcome.Benefit, new StringBuilder(KEYWORD).append(" the creature for ").append(dashCost.getText(true)).append(" ?").toString(), ability, game)) { + && player.chooseUse(Outcome.Benefit, KEYWORD + " the creature for " + dashCost.getText(true) + " ?", ability, game)) { activateDash(dashCost, game); ability.getManaCostsToPay().clear(); ability.getCosts().clear(); @@ -209,3 +207,35 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts return alterCosts; } } + +class DashAddDelayedTriggeredAbilityEffect extends OneShotEffect { + + public DashAddDelayedTriggeredAbilityEffect() { + super(Outcome.Benefit); + this.staticText = "return the dashed creature from the battlefield to its owner's hand"; + } + + public DashAddDelayedTriggeredAbilityEffect(final DashAddDelayedTriggeredAbilityEffect effect) { + super(effect); + } + + @Override + public DashAddDelayedTriggeredAbilityEffect copy() { + return new DashAddDelayedTriggeredAbilityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Effect effect = new ReturnToHandTargetEffect(); + effect.setText("return the dashed creature from the battlefield to its owner's hand"); + effect.setTargetPointer(new FixedTarget(source.getSourceId())); + // init target pointer now because the dashed creature will only be returned from current zone + effect.getTargetPointer().init(game, source); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + return false; + } +} diff --git a/Mage/src/mage/abilities/keyword/ExaltedAbility.java b/Mage/src/mage/abilities/keyword/ExaltedAbility.java index d35381cda91..bc0bd895a89 100644 --- a/Mage/src/mage/abilities/keyword/ExaltedAbility.java +++ b/Mage/src/mage/abilities/keyword/ExaltedAbility.java @@ -1,40 +1,38 @@ /* -* 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. -*/ - + * 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.keyword; -import mage.constants.Duration; -import mage.constants.Zone; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.Duration; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.target.targetpointer.FixedTarget; /** @@ -63,7 +61,7 @@ public class ExaltedAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId) ) { + if (game.getActivePlayerId().equals(this.controllerId)) { if (game.getCombat().attacksAlone()) { this.getEffects().get(0).setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); return true; @@ -74,7 +72,7 @@ public class ExaltedAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Exalted"; + return "Exalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.)"; } } diff --git a/Mage/src/mage/abilities/keyword/MenaceAbility.java b/Mage/src/mage/abilities/keyword/MenaceAbility.java index 0ae88b54d06..8735b17d3ff 100644 --- a/Mage/src/mage/abilities/keyword/MenaceAbility.java +++ b/Mage/src/mage/abilities/keyword/MenaceAbility.java @@ -5,7 +5,6 @@ */ package mage.abilities.keyword; -import java.io.ObjectStreamException; import mage.abilities.Ability; import mage.abilities.StaticAbility; import mage.abilities.effects.common.combat.CantBeBlockedByOneEffect; @@ -16,33 +15,23 @@ import mage.constants.Zone; * @author LevelX2 */ public class MenaceAbility extends StaticAbility { - - private static final MenaceAbility fINSTANCE = new MenaceAbility(); public MenaceAbility() { super(Zone.BATTLEFIELD, new CantBeBlockedByOneEffect(2)); } - public MenaceAbility(MenaceAbility ability) { + public MenaceAbility(final MenaceAbility ability) { super(ability); } - - private Object readResolve() throws ObjectStreamException { - return fINSTANCE; - } - public static MenaceAbility getInstance() { - return fINSTANCE; - } - @Override public Ability copy() { - return fINSTANCE; - } + return new MenaceAbility(this); + } @Override public String getRule() { return "Menace (This creature can't be blocked except by two or more creatures.)"; - } - + } + } diff --git a/Mage/src/mage/abilities/keyword/RenownAbility.java b/Mage/src/mage/abilities/keyword/RenownAbility.java index b6920d6d946..878a7659768 100644 --- a/Mage/src/mage/abilities/keyword/RenownAbility.java +++ b/Mage/src/mage/abilities/keyword/RenownAbility.java @@ -22,14 +22,12 @@ import mage.util.CardUtil; * * @author LevelX2 */ - - public class RenownAbility extends TriggeredAbilityImpl { private int renownValue; - + public RenownAbility(int renownValue) { - super(Zone.BATTLEFIELD, new BecomeRenownSourceEffect(renownValue), false); + super(Zone.BATTLEFIELD, new BecomesRenownedSourceEffect(renownValue), false); this.renownValue = renownValue; } @@ -50,7 +48,8 @@ public class RenownAbility extends TriggeredAbilityImpl { @Override public boolean checkInterveningIfClause(Game game) { - return getSourceObject(game) != null && !((Permanent)getSourceObject(game)).isRenown(); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(getSourceId()); + return sourcePermanent != null && !sourcePermanent.isRenowned(); } @Override @@ -59,45 +58,40 @@ public class RenownAbility extends TriggeredAbilityImpl { && ((DamagedPlayerEvent) event).isCombatDamage(); } - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " + super.getRule(); - } - public int getRenownValue() { return renownValue; } } -class BecomeRenownSourceEffect extends OneShotEffect { +class BecomesRenownedSourceEffect extends OneShotEffect { - public BecomeRenownSourceEffect(int renownValue) { + public BecomesRenownedSourceEffect(int renownValue) { super(Outcome.BoostCreature); this.staticText = setText(renownValue); } - public BecomeRenownSourceEffect(final BecomeRenownSourceEffect effect) { + public BecomesRenownedSourceEffect(final BecomesRenownedSourceEffect effect) { super(effect); } @Override - public BecomeRenownSourceEffect copy() { - return new BecomeRenownSourceEffect(this); + public BecomesRenownedSourceEffect copy() { + return new BecomesRenownedSourceEffect(this); } @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null && source instanceof RenownAbility) { - game.informPlayers(permanent.getLogName() + " is now renown"); + game.informPlayers(permanent.getLogName() + " is now renowned"); int renownValue = ((RenownAbility) source).getRenownValue(); // handle renown = X if (renownValue == Integer.MAX_VALUE) { renownValue = source.getManaCostsToPay().getX(); } - new AddCountersSourceEffect(CounterType.P1P1.createInstance(renownValue),true).apply(game, source); - permanent.setRenown(true); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BECOMES_RENOWN, source.getSourceId(), source.getSourceId(), source.getControllerId(), renownValue)); + new AddCountersSourceEffect(CounterType.P1P1.createInstance(renownValue), true).apply(game, source); + permanent.setRenowned(true); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BECOMES_RENOWNED, source.getSourceId(), source.getSourceId(), source.getControllerId(), renownValue)); return true; } return false; @@ -106,9 +100,9 @@ class BecomeRenownSourceEffect extends OneShotEffect { private String setText(int renownValue) { // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned.) StringBuilder sb = new StringBuilder("Renown "); - sb.append(renownValue == Integer.MAX_VALUE ? "X":renownValue) + sb.append(renownValue == Integer.MAX_VALUE ? "X" : renownValue) .append(". (When this creature deals combat damage to a player, if it isn't renowned, put ") - .append(renownValue == Integer.MAX_VALUE ? "X":CardUtil.numberToText(renownValue, "a")) + .append(renownValue == Integer.MAX_VALUE ? "X" : CardUtil.numberToText(renownValue, "a")) .append(" +1/+1 counter on it and it becomes renowned.)").toString(); return sb.toString(); } diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index ebddaf05ab8..970c5670c3d 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -60,7 +60,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 39; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 21; + private static final long CARD_CONTENT_VERSION = 23; private final Random random = new Random(); private Dao cardDao; diff --git a/Mage/src/mage/filter/common/FilterBasicLandCard.java b/Mage/src/mage/filter/common/FilterBasicLandCard.java index 87ed9fcf95e..9c4a4dc52c0 100644 --- a/Mage/src/mage/filter/common/FilterBasicLandCard.java +++ b/Mage/src/mage/filter/common/FilterBasicLandCard.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * 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.filter.common; import mage.constants.CardType; @@ -40,7 +39,11 @@ import mage.filter.predicate.mageobject.SupertypePredicate; public class FilterBasicLandCard extends FilterCard { public FilterBasicLandCard() { - super("basic land card"); + this("basic land card"); + } + + public FilterBasicLandCard(String name) { + super(name); this.add(new CardTypePredicate(CardType.LAND)); this.add(new SupertypePredicate("Basic")); } diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index cdfdd6ccc90..d33aac385a0 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -757,6 +757,13 @@ public class GameState implements Serializable, Copyable { } } + /** + * Removes all waiting triggers (needed for turn end effects) + */ + public void clearTriggeredAbilities() { + this.triggered.clear(); + } + public void addTriggeredAbility(TriggeredAbility ability) { this.triggered.add(ability); } diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index 5c8a5154da7..5ba13a273a3 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -665,7 +665,7 @@ public class Combat implements Serializable, Copyable { } - // check attacking creature mustBeBlockedByAtLeastOne + // check if for attacking creatures with mustBeBlockedByAtLeastOne requirements are fulfilled for (UUID toBeBlockedCreatureId : mustBeBlockedByAtLeastOne.keySet()) { for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (combatGroup.getBlockers().isEmpty() && combatGroup.getAttackers().contains(toBeBlockedCreatureId)) { @@ -675,56 +675,27 @@ public class Combat implements Serializable, Copyable { if (toBeBlockedCreature != null) { // check if all possible blocker block other creatures they are forced to block // read through all possible blockers - boolean possibleBlockerAvailable = false; for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) { - Set forcingAttackers = creatureMustBlockAttackers.get(possibleBlockerId); - if (forcingAttackers == null) { - // no other creature forces the blocker to block -> it's available - possibleBlockerAvailable = true; - break; + String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, mustBeBlockedByAtLeastOne, game); + if (blockRequiredMessage != null) { // message means not required + game.informPlayer(controller, blockRequiredMessage + "It's a requirement to block " + toBeBlockedCreature.getIdName()); + return false; } - // get the attackers he blocks - List blockedAttackers = null; - for (CombatGroup combatGroupToCheck : game.getCombat().getGroups()) { - if (combatGroupToCheck.getBlockers().contains(possibleBlockerId)) { - blockedAttackers = combatGroupToCheck.getAttackers(); - break; - } - } - if (blockedAttackers == null) { - // he blocks no other creature -> it's available - possibleBlockerAvailable = true; - break; - } - - // get attackers forcing the possible blocker to block - possibleBlockerAvailable = true; - for (UUID blockedAttackerId : blockedAttackers) { - if (creatureMustBlockAttackers.get(possibleBlockerId).contains(blockedAttackerId)) { - possibleBlockerAvailable = false; - break; - } - } - if (possibleBlockerAvailable) { - break; - } - } - if (possibleBlockerAvailable) { - if (!game.isSimulation()) { - game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString()); - } - return false; } } } else { // take the first potential blocker from the set to block for the AI - UUID blockingCreatureId = mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId).iterator().next(); - Permanent blockingCreature = game.getPermanent(blockingCreatureId); - if (blockingCreature != null) { - Player defender = game.getPlayer(blockingCreature.getControllerId()); - if (defender != null) { - defender.declareBlocker(defender.getId(), blockingCreatureId, toBeBlockedCreatureId, game); + for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) { + String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, mustBeBlockedByAtLeastOne, game); + if (blockRequiredMessage != null) { + // set the block + Permanent possibleBlocker = game.getPermanent(possibleBlockerId); + Player defender = game.getPlayer(possibleBlocker.getControllerId()); + if (defender != null) { + defender.declareBlocker(defender.getId(), possibleBlockerId, toBeBlockedCreatureId, game); + } + break; } } } @@ -800,6 +771,48 @@ public class Combat implements Serializable, Copyable { return true; } + /** + * Checks if a possible creature for a block is already doing another + * required block + * + * @param possibleBlockerId + * @param mustBeBlockedByAtLeastOne + * @param game + * @return null block is required otherwise message with reason why not + */ + protected String isCreatureDoingARequiredBlock(UUID possibleBlockerId, Map> mustBeBlockedByAtLeastOne, Game game) { + Permanent possibleBlocker = game.getPermanent(possibleBlockerId); + if (possibleBlocker != null) { + if (possibleBlocker.getBlocking() == 0) { + return possibleBlocker.getIdName() + " does not block, but could block creatures with requirement to be blocked."; + } + Set forcingAttackers = creatureMustBlockAttackers.get(possibleBlockerId); + if (forcingAttackers == null) { + // no other creature forces the blocker to block -> it's available + // check now, if it already blocks a creature that mustBeBlockedByAtLeastOne + if (possibleBlocker.getBlocking() > 0) { + CombatGroup combatGroupOfPossibleBlocker = findGroupOfBlocker(possibleBlockerId); + for (UUID blockedAttackerId : combatGroupOfPossibleBlocker.getAttackers()) { + if (mustBeBlockedByAtLeastOne.containsKey(blockedAttackerId)) { + // blocks a creature that has to be blocked by at least one + if (combatGroupOfPossibleBlocker.getBlockers().size() == 1) { + // the creature blocks alone already a creature that has to be blocked by at least one, + // so this is ok + return null; + } + // TODO: Check if the attacker is already blocked by another creature + // and despite there is need that this attacker blocks this attacker also + // I don't know why + Permanent blockedAttacker = game.getPermanent(blockedAttackerId); + return possibleBlocker.getIdName() + " blocks with other creatures " + blockedAttacker.getIdName() + ", which has to be blocked by only one creature. "; + } + } + } + } + } + return null; + } + /** * Checks the canBeBlockedCheckAfter RestrictionEffect Is the block still * valid after all block decisions are done @@ -1037,6 +1050,15 @@ public class Combat implements Serializable, Copyable { return null; } + public CombatGroup findGroupOfBlocker(UUID blockerId) { + for (CombatGroup group : groups) { + if (group.getBlockers().contains(blockerId)) { + return group; + } + } + return null; + } + // public int totalUnblockedDamage(Game game) { // int total = 0; // for (CombatGroup group : groups) { diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index 4b0c5223b67..433ad158c39 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.events; import java.io.Serializable; @@ -52,9 +51,9 @@ public class GameEvent implements Serializable { public enum EventType { //Game events +//Game events BEGINNING, PREVENT_DAMAGE, PREVENTED_DAMAGE, - //Turn-based events PLAY_TURN, EXTRA_TURN, CHANGE_PHASE, PHASE_CHANGED, @@ -78,15 +77,14 @@ public class GameEvent implements Serializable { CLEANUP_STEP_PRE, CLEANUP_STEP, CLEANUP_STEP_POST, EMPTY_MANA_POOL, AT_END_OF_TURN, - //player events /* ZONE_CHANGE - targetId id of the zone changing object - sourceId sourceId of the ability with the object moving effect - playerId controller of the moved object - amount not used for this event - flag not used for this event - */ + targetId id of the zone changing object + sourceId sourceId of the ability with the object moving effect + playerId controller of the moved object + amount not used for this event + flag not used for this event + */ ZONE_CHANGE, ZONE_CHANGE_GROUP, EMPTY_DRAW, @@ -96,77 +94,69 @@ public class GameEvent implements Serializable { DISCARDED_CARD, CYCLE_CARD, CYCLED_CARD, CLASH, CLASHED, - DAMAGE_PLAYER, - + DAMAGE_PLAYER, /* DAMAGED_PLAYER - targetId the id of the damged player - sourceId sourceId of the ability which caused the damage - playerId the id of the damged player - amount amount of damage - flag true = comabat damage - other damage = false - */ + targetId the id of the damged player + sourceId sourceId of the ability which caused the damage + playerId the id of the damged player + amount amount of damage + flag true = comabat damage - other damage = false + */ DAMAGED_PLAYER, - DAMAGE_CAUSES_LIFE_LOSS, PLAYER_LIFE_CHANGE, GAIN_LIFE, GAINED_LIFE, LOSE_LIFE, LOST_LIFE, PLAY_LAND, LAND_PLAYED, - CAST_SPELL, - + CAST_SPELL, /* SPELL_CAST - targetId id of the spell that's cast - sourceId sourceId of the spell that's cast - playerId player that casts the spell - amount not used for this event - flag not used for this event - zone zone the spell is cast from - */ + targetId id of the spell that's cast + sourceId sourceId of the spell that's cast + playerId player that casts the spell + amount not used for this event + flag not used for this event + zone zone the spell is cast from + */ SPELL_CAST, - ACTIVATE_ABILITY, ACTIVATED_ABILITY, - ADD_MANA, MANA_ADDED, - + ADD_MANA, MANA_ADDED, /* MANA_PAYED - targetId id if the ability the mana was paid for (not the sourceId) - sourceId sourceId of the mana source - playerId controller of the ability the mana was paid for - amount not used for this event - flag indicates a special condition - */ - MANA_PAYED, - + targetId id if the ability the mana was paid for (not the sourceId) + sourceId sourceId of the mana source + playerId controller of the ability the mana was paid for + amount not used for this event + flag indicates a special condition + data originalId of the mana producing ability + */ + MANA_PAYED, LOSES, LOST, WINS, TARGET, TARGETED, - /* COUNTER - targetId id of the spell or id of stack ability - sourceId sourceId of the ability countering the spell or stack ability - playerId controller of the countered spell or stack ability - amount not used for this event - flag not used for this event - */ + targetId id of the spell or id of stack ability + sourceId sourceId of the ability countering the spell or stack ability + playerId controller of the countered spell or stack ability + amount not used for this event + flag not used for this event + */ COUNTER, COUNTERED, DECLARING_ATTACKERS, DECLARED_ATTACKERS, DECLARE_ATTACKER, - /* ATTACKER_DECLARED - targetId id of the defending player or planeswalker attacked - sourceId id of the attacking creature - playerId player defining the attacking creatures - amount not used for this event - flag not used for this event - */ + targetId id of the defending player or planeswalker attacked + sourceId id of the attacking creature + playerId player defining the attacking creatures + amount not used for this event + flag not used for this event + */ ATTACKER_DECLARED, - /* DECLARING_BLOCKERS - targetId attackerId - sourceId not used for this event - playerId attackerId - amount not used for this event - flag not used for this event - */ + targetId attackerId + sourceId not used for this event + playerId attackerId + amount not used for this event + flag not used for this event + */ DECLARING_BLOCKERS, DECLARED_BLOCKERS, DECLARE_BLOCKER, BLOCKER_DECLARED, @@ -176,7 +166,6 @@ public class GameEvent implements Serializable { ENCHANT_PLAYER, ENCHANTED_PLAYER, CAN_TAKE_MULLIGAN, FLIP_COIN, COIN_FLIPPED, SCRY, FATESEAL, - //permanent events ENTERS_THE_BATTLEFIELD, TAP, TAPPED, TAPPED_FOR_MANA, @@ -185,24 +174,22 @@ public class GameEvent implements Serializable { UNFLIP, UNFLIPPED, TRANSFORM, TRANSFORMED, BECOMES_MONSTROUS, - BECOMES_RENOWN, + BECOMES_RENOWNED, PHASE_OUT, PHASED_OUT, PHASE_IN, PHASED_IN, TURNFACEUP, TURNEDFACEUP, TURNFACEDOWN, TURNEDFACEDOWN, DAMAGE_CREATURE, DAMAGED_CREATURE, DAMAGE_PLANESWALKER, DAMAGED_PLANESWALKER, - DESTROY_PERMANENT, - + DESTROY_PERMANENT, /* DESTROYED_PERMANENT - targetId id of the destroyed creature - sourceId sourceId of the ability with the destroy effect - playerId controller of the creature - amount not used for this event - flag true if no regeneration is allowed - */ + targetId id of the destroyed creature + sourceId sourceId of the ability with the destroy effect + playerId controller of the creature + amount not used for this event + flag true if no regeneration is allowed + */ DESTROYED_PERMANENT, - SACRIFICE_PERMANENT, SACRIFICED_PERMANENT, FIGHTED_PERMANENT, EXPLOITED_CREATURE, @@ -211,31 +198,27 @@ public class GameEvent implements Serializable { ADD_COUNTER, COUNTER_ADDED, ADD_COUNTERS, COUNTERS_ADDED, COUNTER_REMOVED, - LOSE_CONTROL, - + LOSE_CONTROL, /* LOST_CONTROL - targetId id of the creature that lost control - sourceId id of the creature that lost control - playerId player that controlles the creature before - amount not used for this event - flag not used for this event - */ + targetId id of the creature that lost control + sourceId id of the creature that lost control + playerId player that controlles the creature before + amount not used for this event + flag not used for this event + */ LOST_CONTROL, GAIN_CONTROL, GAINED_CONTROL, CREATE_TOKEN, - /* REGENERATE - targetId id of the creature to regenerate - sourceId sourceId of the effect doing the regeneration - playerId controller of the creature - amount not used for this event - flag not used for this event - */ + targetId id of the creature to regenerate + sourceId sourceId of the effect doing the regeneration + playerId controller of the creature + amount not used for this event + flag not used for this event + */ REGENERATE, - REGENERATED, CHANGE_COLOR, COLOR_CHANGED, - //combat events COMBAT_DAMAGE_APPLIED, SELECTED_ATTACKER, SELECTED_BLOCKER; @@ -268,7 +251,7 @@ public class GameEvent implements Serializable { } public static GameEvent getEvent(EventType type, UUID targetId, UUID playerId, String data, int amount) { - GameEvent event = getEvent(type, targetId,playerId); + GameEvent event = getEvent(type, targetId, playerId); event.setAmount(amount); event.setData(data); return event; @@ -310,7 +293,6 @@ public class GameEvent implements Serializable { this.flag = flag; } - public String getData() { return data; } @@ -326,17 +308,18 @@ public class GameEvent implements Serializable { public void setZone(Zone zone) { this.zone = zone; } + /** * used to store which replacement effects were already applied to an event * or or any modified events that may replace it * - * 614.5. A replacement effect doesn't invoke itself repeatedly; it gets only one - * opportunity to affect an event or any modified events that may replace it. - * Example: A player controls two permanents, each with an ability that reads - * "If a creature you control would deal damage to a creature or player, it - * deals double that damage to that creature or player instead." A creature - * that normally deals 2 damage will deal 8 damage--not just 4, and not an - * infinite amount. + * 614.5. A replacement effect doesn't invoke itself repeatedly; it gets + * only one opportunity to affect an event or any modified events that may + * replace it. Example: A player controls two permanents, each with an + * ability that reads "If a creature you control would deal damage to a + * creature or player, it deals double that damage to that creature or + * player instead." A creature that normally deals 2 damage will deal 8 + * damage--not just 4, and not an infinite amount. * * @return */ diff --git a/Mage/src/mage/game/permanent/Permanent.java b/Mage/src/mage/game/permanent/Permanent.java index 22e6319590d..33221ea2fb7 100644 --- a/Mage/src/mage/game/permanent/Permanent.java +++ b/Mage/src/mage/game/permanent/Permanent.java @@ -75,8 +75,8 @@ public interface Permanent extends Card, Controllable { boolean isMonstrous(); void setMonstrous(boolean value); - boolean isRenown(); - void setRenown(boolean value); + boolean isRenowned(); + void setRenowned(boolean value); void setCardNumber(int cid); void setExpansionSetCode(String expansionSetCode); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index c44b666bff4..5ba200bae69 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -90,7 +90,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { protected boolean flipped; protected boolean transformed; protected boolean monstrous; - protected boolean renown; + protected boolean renowned; protected boolean manifested = false; protected boolean morphed = false; protected UUID originalControllerId; @@ -176,6 +176,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.maxBlockedBy = permanent.maxBlockedBy; this.transformed = permanent.transformed; this.monstrous = permanent.monstrous; + this.renowned = permanent.renowned; this.pairedCard = permanent.pairedCard; this.timesLoyaltyUsed = permanent.timesLoyaltyUsed; @@ -1267,13 +1268,13 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } @Override - public boolean isRenown() { - return this.renown; + public boolean isRenowned() { + return this.renowned; } @Override - public void setRenown(boolean value) { - this.renown = value; + public void setRenowned(boolean value) { + this.renowned = value; } @Override diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 6674065cafc..2adc38b5e2c 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.stack; import java.util.ArrayList; @@ -101,10 +100,10 @@ public class Spell extends StackObjImpl implements Card { public Spell(final Spell spell) { this.id = spell.id; - for (SpellAbility spellAbility: spell.spellAbilities) { + for (SpellAbility spellAbility : spell.spellAbilities) { this.spellAbilities.add(spellAbility.copy()); } - for (Card spellCard: spell.spellCards) { + for (Card spellCard : spell.spellCards) { this.spellCards.add(spellCard.copy()); } if (spell.spellAbilities.get(0).equals(spell.ability)) { @@ -124,7 +123,6 @@ public class Spell extends StackObjImpl implements Card { this.color = spell.color.copy(); } - public boolean activate(Game game, boolean noMana) { if (!spellAbilities.get(0).activate(game, noMana)) { return false; @@ -132,7 +130,7 @@ public class Spell extends StackObjImpl implements Card { // if there are more abilities (fused split spell) or first ability added new abilities (splice), activate the additional abilities boolean ignoreAbility = true; boolean payNoMana = noMana; - for (SpellAbility spellAbility: spellAbilities) { + for (SpellAbility spellAbility : spellAbilities) { // costs for spliced abilities were added to main spellAbility, so pay no mana for spliced abilities payNoMana |= spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE); if (ignoreAbility) { @@ -174,19 +172,19 @@ public class Spell extends StackObjImpl implements Card { result = false; boolean legalParts = false; // check for legal parts - for(SpellAbility spellAbility: this.spellAbilities) { - // if muliple modes are selected, and there are modes with targets, then at least one mode has to have a legal target or - // When resolving a fused split spell with multiple targets, treat it as you would any spell with multiple targets. - // If all targets are illegal when the spell tries to resolve, the spell is countered and none of its effects happen. + for (SpellAbility spellAbility : this.spellAbilities) { + // if muliple modes are selected, and there are modes with targets, then at least one mode has to have a legal target or + // When resolving a fused split spell with multiple targets, treat it as you would any spell with multiple targets. + // If all targets are illegal when the spell tries to resolve, the spell is countered and none of its effects happen. // If at least one target is still legal at that time, the spell resolves, but an illegal target can't perform any actions - // or have any actions performed on it. + // or have any actions performed on it. legalParts |= spellAbilityHasLegalParts(spellAbility, game); } // resolve if legal parts if (legalParts) { - for(SpellAbility spellAbility: this.spellAbilities) { + for (SpellAbility spellAbility : this.spellAbilities) { if (spellAbilityHasLegalParts(spellAbility, game)) { - for (UUID modeId :spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().stillLegal(spellAbility, game)) { if (!spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { @@ -216,14 +214,14 @@ public class Spell extends StackObjImpl implements Card { if (ability.getTargets().stillLegal(ability, game)) { updateOptionalCosts(0); boolean bestow = this.getSpellAbility() instanceof BestowAbility; - if (bestow) { + if (bestow) { // Must be removed first time, after that will be removed by continous effect // Otherwise effects like evolve trigger from creature comes into play event card.getCardType().remove(CardType.CREATURE); - card.getSubtype().add("Aura"); + card.getSubtype().add("Aura"); } if (card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId)) { - if (bestow) { + if (bestow) { // card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed // TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities Permanent permanent = game.getPermanent(card.getId()); @@ -234,16 +232,16 @@ public class Spell extends StackObjImpl implements Card { } card.getCardType().add(CardType.CREATURE); card.getSubtype().remove("Aura"); - } + } return ability.resolve(game); } - if (bestow) { + if (bestow) { card.getCardType().add(CardType.CREATURE); - } + } return false; } // Aura has no legal target and its a bestow enchantment -> Add it to battlefield as creature - if (this.getSpellAbility() instanceof BestowAbility) { + if (this.getSpellAbility() instanceof BestowAbility) { updateOptionalCosts(0); result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId); return result; @@ -263,17 +261,17 @@ public class Spell extends StackObjImpl implements Card { } private boolean spellAbilityHasLegalParts(SpellAbility spellAbility, Game game) { - if (spellAbility.getModes().getSelectedModes().size() > 1) { + if (spellAbility.getModes().getSelectedModes().size() > 1) { boolean targetedMode = false; boolean legalTargetedMode = false; - for (UUID modeId :spellAbility.getModes().getSelectedModes()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().size() > 0) { targetedMode = true; if (spellAbility.getTargets().stillLegal(spellAbility, game)) { legalTargetedMode = true; - } - } + } + } } if (targetedMode) { return legalTargetedMode; @@ -283,11 +281,11 @@ public class Spell extends StackObjImpl implements Card { return spellAbility.getTargets().stillLegal(spellAbility, game); } } - + /** - * As we have ability in the stack, we need to update optional costs in original card. - * This information will be used later by effects, e.g. to determine whether card was kicked or not. - * E.g. Desolation Angel + * As we have ability in the stack, we need to update optional costs in + * original card. This information will be used later by effects, e.g. to + * determine whether card was kicked or not. E.g. Desolation Angel */ private void updateOptionalCosts(int index) { Ability abilityOrig = spellCards.get(index).getAbilities().get(spellAbilities.get(index).getId()); @@ -307,9 +305,7 @@ public class Spell extends StackObjImpl implements Card { } } } - - @Override public void counter(UUID sourceId, Game game) { this.countered = true; @@ -319,10 +315,10 @@ public class Spell extends StackObjImpl implements Card { Ability counteringAbility = null; MageObject counteringObject = game.getObject(sourceId); if (counteringObject instanceof StackObject) { - counteringAbility = ((StackObject)counteringObject).getStackAbility(); + counteringAbility = ((StackObject) counteringObject).getStackAbility(); } player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, counteringAbility, game); - } + } } } @@ -340,18 +336,18 @@ public class Spell extends StackObjImpl implements Card { public String getName() { return card.getName(); } - + @Override public String getIdName() { String idName; if (card != null) { - idName = card.getId().toString().substring(0,3); + idName = card.getId().toString().substring(0, 3); } else { - idName = getId().toString().substring(0,3); + idName = getId().toString().substring(0, 3); } - return getName() + " ["+idName+"]"; + return getName() + " [" + idName + "]"; } - + @Override public String getLogName() { return GameLog.getColoredObjectIdName(card); @@ -363,7 +359,8 @@ public class Spell extends StackObjImpl implements Card { } @Override - public void setName(String name) {} + public void setName(String name) { + } @Override public Rarity getRarity() { @@ -415,7 +412,6 @@ public class Spell extends StackObjImpl implements Card { return card.getSupertype(); } - public List getSpellAbilities() { return spellAbilities; } @@ -429,7 +425,7 @@ public class Spell extends StackObjImpl implements Card { public Abilities getAbilities(Game game) { return card.getAbilities(game); } - + @Override public boolean hasAbility(UUID abilityId, Game game) { return card.hasAbility(abilityId, game); @@ -446,9 +442,11 @@ public class Spell extends StackObjImpl implements Card { } /** - * 202.3b When calculating the converted mana cost of an object with an {X} in its - * mana cost, X is treated as 0 while the object is not on the stack, and X is - * treated as the number chosen for it while the object is on the stack. + * 202.3b When calculating the converted mana cost of an object with an {X} + * in its mana cost, X is treated as 0 while the object is not on the stack, + * and X is treated as the number chosen for it while the object is on the + * stack. + * * @return */ @Override @@ -457,9 +455,9 @@ public class Spell extends StackObjImpl implements Card { if (faceDown) { return 0; } - for (Ability spellAbility: spellAbilities) { + for (Ability spellAbility : spellAbilities) { int xMultiplier = 0; - for (String symbolString :spellAbility.getManaCosts().getSymbols()) { + for (String symbolString : spellAbility.getManaCosts().getSymbols()) { int index = symbolString.indexOf("{X}"); while (index != -1) { xMultiplier++; @@ -471,14 +469,14 @@ public class Spell extends StackObjImpl implements Card { cmc += spellAbility.getManaCostsToPay().getX() * xMultiplier; } else { cmc += spellAbility.getManaCosts().convertedManaCost() + spellAbility.getManaCostsToPay().getX() * xMultiplier; - } + } } if (this.getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.BASE_ALTERNATE)) { cmc += getCard().getManaCost().convertedManaCost(); } return cmc; } - + @Override public MageInt getPower() { return card.getPower(); @@ -503,7 +501,8 @@ public class Spell extends StackObjImpl implements Card { spellAbilities.add(spellAbility); } - public void addAbility(Ability ability) {} + public void addAbility(Ability ability) { + } @Override public SpellAbility getSpellAbility() { @@ -512,14 +511,15 @@ public class Spell extends StackObjImpl implements Card { public void setControllerId(UUID controllerId) { this.ability.setControllerId(controllerId); - for (SpellAbility spellAbility: spellAbilities) { + for (SpellAbility spellAbility : spellAbilities) { spellAbility.setControllerId(controllerId); } this.controllerId = controllerId; } @Override - public void setOwnerId(UUID controllerId) {} + public void setOwnerId(UUID controllerId) { + } @Override public List getRules() { @@ -608,7 +608,7 @@ public class Spell extends StackObjImpl implements Card { card.adjustChoices(ability, game); } } - + @Override public void adjustCosts(Ability ability, Game game) { if (card != null) { @@ -623,7 +623,6 @@ public class Spell extends StackObjImpl implements Card { } } - @Override public boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag) { return moveToZone(zone, sourceId, game, flag, null); @@ -635,7 +634,7 @@ public class Spell extends StackObjImpl implements Card { // If a copy of a card is in any zone other than the stack or the battlefield, it ceases to exist. // These are state-based actions. See rule 704. if (this.isCopiedSpell() && !zone.equals(Zone.STACK)) { - return true; + return true; } throw new UnsupportedOperationException("Unsupported operation"); } @@ -646,7 +645,7 @@ public class Spell extends StackObjImpl implements Card { } @Override - public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList appliedEffects) { + public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList appliedEffects) { ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), sourceId, this.getOwnerId(), Zone.STACK, Zone.EXILED, appliedEffects); if (!game.replaceEvent(event)) { game.getStack().remove(this); @@ -667,8 +666,6 @@ public class Spell extends StackObjImpl implements Card { return false; } - - @Override public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId) { throw new UnsupportedOperationException("Unsupported operation"); @@ -711,7 +708,7 @@ public class Spell extends StackObjImpl implements Card { @Override public void updateZoneChangeCounter(Game game) { - throw new UnsupportedOperationException("Unsupported operation"); + throw new UnsupportedOperationException("Unsupported operation"); } @Override @@ -762,7 +759,8 @@ public class Spell extends StackObjImpl implements Card { } @Override - public void build() {} + public void build() { + } @Override public Counters getCounters(Game game) { @@ -815,7 +813,7 @@ public class Spell extends StackObjImpl implements Card { @Override public void setSpellAbility(SpellAbility ability) { - throw new UnsupportedOperationException("Not supported."); + throw new UnsupportedOperationException("Not supported."); } public boolean isCountered() { diff --git a/Mage/src/mage/game/stack/SpellStack.java b/Mage/src/mage/game/stack/SpellStack.java index 174ac51cb32..62ea3bb72ca 100644 --- a/Mage/src/mage/game/stack/SpellStack.java +++ b/Mage/src/mage/game/stack/SpellStack.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.stack; import java.util.ArrayDeque; @@ -44,11 +43,12 @@ public class SpellStack extends ArrayDeque { protected Date dateLastAdded; - public SpellStack () {} + public SpellStack() { + } public SpellStack(final SpellStack stack) { - - for (StackObject spell: stack) { + + for (StackObject spell : stack) { this.addLast(spell.copy()); } } @@ -67,7 +67,7 @@ public class SpellStack extends ArrayDeque { } public void remove(StackObject object) { - for (StackObject spell: this) { + for (StackObject spell : this) { if (spell.getId().equals(object.getId())) { super.remove(spell); return; @@ -77,7 +77,7 @@ public class SpellStack extends ArrayDeque { public boolean counter(UUID objectId, UUID sourceId, Game game) { // the counter logic is copied by some spells to handle replacement effects of the countered spell - // so if logic is changed here check those spells for needed changes too + // so if logic is changed here check those spells for needed changes too // Concerned cards to check: Hinder, Spell Crumple StackObject stackObject = getStackObject(objectId); MageObject sourceObject = game.getObject(sourceId); @@ -87,7 +87,7 @@ public class SpellStack extends ArrayDeque { if (targetSourceObject == null) { targetSourceName = "[Object not found]"; } else { - targetSourceName = game.getObject(stackObject.getSourceId()).getName(); + targetSourceName = game.getObject(stackObject.getSourceId()).getLogName(); } if (stackObject instanceof Spell) { counteredObjectName = targetSourceName; @@ -95,12 +95,12 @@ public class SpellStack extends ArrayDeque { counteredObjectName = "Ability (" + stackObject.getStackAbility().getRule(targetSourceName) + ") of " + targetSourceName; } if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) { - if ( stackObject instanceof Spell ) { - game.rememberLKI(objectId, Zone.STACK, (Spell)stackObject); + if (stackObject instanceof Spell) { + game.rememberLKI(objectId, Zone.STACK, (Spell) stackObject); } else { - this.remove(stackObject); + this.remove(stackObject); } - stackObject.counter(sourceId, game); + stackObject.counter(sourceId, game); if (!game.isSimulation()) { game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName()); } @@ -114,7 +114,7 @@ public class SpellStack extends ArrayDeque { } public StackObject getStackObject(UUID id) { - for (StackObject stackObject: this) { + for (StackObject stackObject : this) { UUID objectId = stackObject.getId(); if (objectId.equals(id)) { return stackObject; @@ -128,10 +128,10 @@ public class SpellStack extends ArrayDeque { } public Spell getSpell(UUID id) { - for (StackObject stackObject: this) { + for (StackObject stackObject : this) { if (stackObject instanceof Spell) { if (stackObject.getId().equals(id) || stackObject.getSourceId().equals(id)) { - return (Spell)stackObject; + return (Spell) stackObject; } } } diff --git a/Mage/src/mage/game/turn/Turn.java b/Mage/src/mage/game/turn/Turn.java index c781a711d2d..ec5d2f81ca1 100644 --- a/Mage/src/mage/game/turn/Turn.java +++ b/Mage/src/mage/game/turn/Turn.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.turn; import java.io.Serializable; @@ -56,7 +55,7 @@ public class Turn implements Serializable { private final List phases = new ArrayList<>(); private boolean declareAttackersStepStarted = false; private boolean endTurn; // indicates that an end turn effect has resolved. - + public Turn() { endTurn = false; phases.add(new BeginningPhase()); @@ -71,7 +70,7 @@ public class Turn implements Serializable { this.currentPhase = turn.currentPhase.copy(); } this.activePlayerId = turn.activePlayerId; - for (Phase phase: turn.phases) { + for (Phase phase : turn.phases) { this.phases.add(phase.copy()); } this.declareAttackersStepStarted = turn.declareAttackersStepStarted; @@ -91,7 +90,7 @@ public class Turn implements Serializable { } public Phase getPhase(TurnPhase turnPhase) { - for (Phase phase: phases) { + for (Phase phase : phases) { if (phase.getType() == turnPhase) { return phase; } @@ -133,7 +132,7 @@ public class Turn implements Serializable { this.activePlayerId = activePlayer.getId(); resetCounts(); game.getPlayer(activePlayer.getId()).beginTurn(game); - for (Phase phase: phases) { + for (Phase phase : phases) { if (game.isPaused() || game.gameOver(null)) { return; } @@ -142,11 +141,11 @@ public class Turn implements Serializable { game.fireEvent(new GameEvent(GameEvent.EventType.PHASE_CHANGED, activePlayer.getId(), null, activePlayer.getId())); if (!game.getState().getTurnMods().skipPhase(activePlayer.getId(), currentPhase.getType())) { if (phase.play(game, activePlayer.getId())) { - if(game.executingRollback()) { + if (game.executingRollback()) { return; } //20091005 - 500.4/703.4n - game.emptyManaPools(); + game.emptyManaPools(); game.saveState(false); //20091005 - 500.8 @@ -208,7 +207,7 @@ public class Turn implements Serializable { } private void resetCounts() { - for (Phase phase: phases) { + for (Phase phase : phases) { phase.resetCount(); } } @@ -223,7 +222,7 @@ public class Turn implements Serializable { return false; } Phase phase; - switch(extraPhase) { + switch (extraPhase) { case BEGINNING: phase = new BeginningPhase(); break; @@ -251,52 +250,51 @@ public class Turn implements Serializable { } /*protected void playExtraTurns(Game game) { - while (game.getState().getTurnMods().extraTurn(activePlayerId)) { - this.play(game, activePlayerId); - } - }*/ -/** - * Used for some spells with end turn effect (e.g. Time Stop). - * - * @param game - * @param activePlayerId - */ + while (game.getState().getTurnMods().extraTurn(activePlayerId)) { + this.play(game, activePlayerId); + } + }*/ + /** + * Used for some spells with end turn effect (e.g. Time Stop). + * + * @param game + * @param activePlayerId + */ public void endTurn(Game game, UUID activePlayerId) { - // Ending the turn this way (Time Stop) means the following things happen in order: - + // Ending the turn this way (Time Stop) means the following things happen in order: + setEndTurnRequested(true); - - // 1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve. - // It also includes spells and abilities that can't be countered. + + // 1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve. + // It also includes spells and abilities that can't be countered. while (!game.getStack().isEmpty()) { StackObject stackObject = game.getStack().removeLast(); if (stackObject instanceof Spell) { ((Spell) stackObject).moveToExile(null, "", null, game); } } - // 2) All attacking and blocking creatures are removed from combat. - for (UUID attackerId: game.getCombat().getAttackers()) { + // 2) All attacking and blocking creatures are removed from combat. + for (UUID attackerId : game.getCombat().getAttackers()) { Permanent permanent = game.getPermanent(attackerId); if (permanent != null) { permanent.removeFromCombat(game); } game.getCombat().removeAttacker(attackerId, game); } - for (UUID blockerId: game.getCombat().getBlockers()) { + for (UUID blockerId : game.getCombat().getBlockers()) { Permanent permanent = game.getPermanent(blockerId); if (permanent != null) { permanent.removeFromCombat(game); } } - - // 3) State-based actions are checked. No player gets priority, and no triggered abilities are put onto the stack. - + // 3) State-based actions are checked. No player gets priority, and no triggered abilities are put onto the stack. + // seems like trigger events have to be removed: http://tabakrules.tumblr.com/post/122350751009/days-undoing-has-been-officially-spoiled-on + game.getState().clearTriggeredAbilities(); game.checkStateAndTriggered(); // triggered effects don't go to stack because check of endTurnRequested - - // 4) The current phase and/or step ends. + + // 4) The current phase and/or step ends. // The game skips straight to the cleanup step. The cleanup step happens in its entirety. // this is caused by the endTurnRequest state - } public boolean isDeclareAttackersStepStarted() { @@ -310,23 +308,23 @@ public class Turn implements Serializable { public void setEndTurnRequested(boolean endTurn) { this.endTurn = endTurn; } - + public boolean isEndTurnRequested() { return endTurn; } - + public Turn copy() { return new Turn(this); } - + public String getValue(int turnNum) { StringBuilder sb = threadLocalBuilder.get(); sb.append("[").append(turnNum) - .append(":").append(currentPhase.getType()) - .append(":").append(currentPhase.getStep().getType()) - .append("]"); + .append(":").append(currentPhase.getType()) + .append(":").append(currentPhase.getStep().getType()) + .append("]"); return sb.toString(); } - + } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 9f04992fc8e..052ab43222f 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -227,8 +227,6 @@ public abstract class PlayerImpl implements Player, Serializable { protected UserData userData; protected MatchPlayer matchPlayer; - protected String flagName; - /** * During some steps we can't play anything */ @@ -2916,6 +2914,12 @@ public abstract class PlayerImpl implements Player, Serializable { result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone); } return result; + case BATTLEFIELD: + result = false; + for (Card card : cards) { + result |= putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId()); + } + return result; default: throw new UnsupportedOperationException("to Zone not supported yet"); } diff --git a/Mage/src/mage/watchers/common/CreatureWasCastWatcher.java b/Mage/src/mage/watchers/common/CreatureWasCastWatcher.java new file mode 100644 index 00000000000..e693a010556 --- /dev/null +++ b/Mage/src/mage/watchers/common/CreatureWasCastWatcher.java @@ -0,0 +1,93 @@ +/* + * 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.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.cards.Card; +import mage.constants.CardType; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.stack.Spell; +import mage.watchers.Watcher; + +/** + * + * @author LevelX2 + */ +public class CreatureWasCastWatcher extends Watcher { + + private final Set creaturesCasted = new HashSet<>(); + + public CreatureWasCastWatcher() { + super("CreatureWasCast", WatcherScope.GAME); + } + + public CreatureWasCastWatcher(final CreatureWasCastWatcher watcher) { + super(watcher); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST) { + Spell spell = (Spell) game.getObject(event.getTargetId()); + if (spell != null) { + Card card = game.getCard(spell.getSourceId()); + if (card != null && card.getCardType().contains(CardType.CREATURE)) { + creaturesCasted.add(card.getId()); + } + } + } + if (event.getType() == GameEvent.EventType.ZONE_CHANGE + && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { + Card card = game.getCard(event.getTargetId()); + if (card != null && card.getCardType().contains(CardType.CREATURE)) { + creaturesCasted.remove(card.getId()); + } + } + } + + public boolean wasCreatureCastThisTurn(UUID creatureSourceId) { + return creaturesCasted.contains(creatureSourceId); + } + + @Override + public void reset() { + super.reset(); + creaturesCasted.clear(); + } + + @Override + public CreatureWasCastWatcher copy() { + return new CreatureWasCastWatcher(this); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c0e8ba5b3d5..4535fb23d1f 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -26130,7 +26130,7 @@ Valor in Akros|Magic Origins|39|U|{3}{W}|Enchantment|||Whenever a creature enter Vryn Wingmare|Magic Origins|40|R|{2}{W}|Creature - Pegasus|2|1|Flying$Noncreature spells cost {1} more to cast.| War Oracle|Magic Origins|41|U|{2}{W}{W}|Creature - Human Cleric|3|3|Lifelink$Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned)| Yoked Ox|Magic Origins|42|C|{W}|Creature - Ox|0|4|| -Alhammarret, High Arbiter|Magic Origins|43|R|{5}{U}{U}|Legendary Creature - Sphinx|5|5|Flying$As Alhammarret, High Arbiter enters the battlefield, each opponent reveals his or her hand. You choose the name of a nonland card revealed this way.$Your opponent can't cast spells with the chosen name (as long as this creature is on the battlefield).| +Alhammarret, High Arbiter|Magic Origins|43|R|{5}{U}{U}|Legendary Creature - Sphinx|5|5|Flying$As Alhammarret, High Arbiter enters the battlefield, each opponent reveals his or her hand. You choose the name of a nonland card revealed this way.$Your opponents can't cast spells with the chosen name (as long as this creature is on the battlefield).| Anchor to the AEther|Magic Origins|44|U|{2}{U}|Sorcery|||Put target creature on top of its owner's library. Scry 1.| Artificer's Epiphany|Magic Origins|45|C|{2}{U}|Instant|||Draw two cards. If you control no artifacts, discard a card.| Aspiring Aeronaut|Magic Origins|46|C|{3}{U}|Creature - Human Artificer|1|2|Flying$When Aspiring Aeronaut enters the battlefield, put a 1/1 colorless Thopter artifact creature token with flying onto the battlefield.| diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt index 9fd9eceae25..9efee636722 100644 --- a/Utils/release/getting_implemented_cards.txt +++ b/Utils/release/getting_implemented_cards.txt @@ -146,6 +146,9 @@ git log 757b9ea99ec1f0ce46bb533f9f86f3473d122a60..HEAD --diff-filter=A --name-st since 1.4.2.v0 git log cd0cba6ec7d8799bb85247b7b4f5d545e170b093..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +since 1.4.2.v1 +git log 0b26aaff6ec033a538179bf607b1c7a7736aedb2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt + 3. Copy added_cards.txt to trunk\Utils folder 4. Run script: > perl extract_in_wiki_format.perl