From 66c4aec499de2fdc38b1b95e1ccf818498cb1cda Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 8 Sep 2017 12:14:18 +0200 Subject: [PATCH 01/25] * Conspiracy - Fixed that it doesn't revert creature types of non-permanent cards when it leaves the battlefield (fixes #3911). --- .../SubTypeChangingEffectsTest.java | 174 ++++++++++++++++++ .../main/java/mage/game/CardAttribute.java | 25 +-- 2 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java new file mode 100644 index 00000000000..3e6a2548199 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java @@ -0,0 +1,174 @@ +/* + * 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.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class SubTypeChangingEffectsTest extends CardTestPlayerBase { + + @Test + public void testConspiracyGiveType() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Conspiracy", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + silvercoatLion = getPermanent("Silvercoat Lion", playerB); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should not have CAT type", false, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerB.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAR type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerB.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + + } + for (Card card : playerB.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + + } + } + + } + + /** + * Conspiracy doesn't revert creature types of non-permanent cards when it + * leaves the battlefield + */ + @Test + public void testConspiracyIsRestCorrectly() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Disenchant", 1); // Instant + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Disenchant", "Conspiracy"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Conspiracy", 1); + assertGraveyardCount(playerB, "Disenchant", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + + } + + } +} diff --git a/Mage/src/main/java/mage/game/CardAttribute.java b/Mage/src/main/java/mage/game/CardAttribute.java index 5aa24b9e5fd..7a5908c5f73 100644 --- a/Mage/src/main/java/mage/game/CardAttribute.java +++ b/Mage/src/main/java/mage/game/CardAttribute.java @@ -5,42 +5,43 @@ */ package mage.game; +import java.io.Serializable; import mage.ObjectColor; import mage.cards.Card; import mage.util.SubTypeList; -import java.io.Serializable; - /** - * This class saves changed attributes of cards (e.g. in graveyard, exile or player hands or libraries). - * + * This class saves changed attributes of cards (e.g. in graveyard, exile or + * player hands or libraries). + * * @author LevelX2 */ -public class CardAttribute implements Serializable { - +public class CardAttribute implements Serializable { + protected ObjectColor color; protected SubTypeList subtype; public CardAttribute(Card card) { color = card.getColor(null).copy(); - subtype = card.getSubtype(null); + subtype = new SubTypeList(); + subtype.addAll(subtype); } public CardAttribute(CardAttribute cardAttribute) { this.color = cardAttribute.color; this.subtype = cardAttribute.subtype; } - + public CardAttribute copy() { return new CardAttribute(this); } - + public ObjectColor getColor() { - return color; + return color; } - + public SubTypeList getSubtype() { return subtype; } - + } From 2355d35e0478791dfbd1da1cfeba037b7f9e03b3 Mon Sep 17 00:00:00 2001 From: igoudt Date: Fri, 8 Sep 2017 13:11:58 +0200 Subject: [PATCH 02/25] small fixes --- Mage.Sets/src/mage/cards/f/FrenziedGoblin.java | 5 +++-- Mage.Sets/src/mage/cards/l/LilianaVess.java | 9 +++++---- Mage.Sets/src/mage/cards/n/NaturesLore.java | 5 +++-- Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java | 7 ++++--- Mage.Sets/src/mage/cards/r/RecklessSpite.java | 5 +++-- Mage.Sets/src/mage/cards/s/SylvanRanger.java | 2 +- Mage.Sets/src/mage/cards/t/TrueConviction.java | 9 +++++---- Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java | 5 +++-- .../AttacksCreatureYouControlTriggeredAbility.java | 2 +- .../mage/abilities/common/EntersBattlefieldAbility.java | 4 ++-- .../mage/abilities/effects/common/CreateTokenEffect.java | 7 ++++--- .../ReturnToHandChosenControlledPermanentEffect.java | 7 ++++++- 12 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java index fbaae281280..d1e29fd8697 100644 --- a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java +++ b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java @@ -27,7 +27,6 @@ */ package mage.cards.f; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -41,6 +40,8 @@ import mage.constants.Duration; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -57,7 +58,7 @@ public class FrenziedGoblin extends CardImpl { // Whenever Frenzied Goblin attacks, you may pay {R}. If you do, target creature can't block this turn. Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid(new CantBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{R}")),false, - "Whenever {this} attacks you may pay {R}. If you do, target creature can't block this turn."); + "Whenever {this} attacks you, may pay {R}. If you do, target creature can't block this turn."); Target target = new TargetCreaturePermanent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LilianaVess.java b/Mage.Sets/src/mage/cards/l/LilianaVess.java index 193f718a78d..7e2681a93b0 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaVess.java +++ b/Mage.Sets/src/mage/cards/l/LilianaVess.java @@ -27,9 +27,6 @@ */ package mage.cards.l; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; @@ -49,6 +46,10 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -89,7 +90,7 @@ class LilianaVessEffect extends OneShotEffect { public LilianaVessEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Put all creature cards in all graveyards onto the battlefield under your control"; + staticText = "Put all creature cards from all graveyards onto the battlefield under your control"; } public LilianaVessEffect(final LilianaVessEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NaturesLore.java b/Mage.Sets/src/mage/cards/n/NaturesLore.java index c07a21d4548..1f73d2deaaa 100644 --- a/Mage.Sets/src/mage/cards/n/NaturesLore.java +++ b/Mage.Sets/src/mage/cards/n/NaturesLore.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,13 +36,15 @@ import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** * * @author LevelX2 */ public class NaturesLore extends CardImpl { - private static final FilterCard filter = new FilterCard("a Forest card"); + private static final FilterCard filter = new FilterCard("Forest card"); static { filter.add(new SubtypePredicate(SubType.FOREST)); diff --git a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java index 7936a680836..1558de8636c 100644 --- a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java +++ b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; @@ -54,13 +53,15 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author spjspj */ public class NazahnReveredBladesmith extends CardImpl { - private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creatures you control"); + private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creature you control"); static { equippedFilter.add(new EquippedPredicate()); @@ -88,7 +89,7 @@ public class NazahnReveredBladesmith extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandOrOnBattlefieldEffect(target, true, true, "Hammer of Nazahn"), true)); // Whenever an equipped creature you control attacks, you may tap target creature defending player controls. - Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), false, equippedFilter, true); + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), true, equippedFilter, true); ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RecklessSpite.java b/Mage.Sets/src/mage/cards/r/RecklessSpite.java index c2b1f67de8d..040b7de8489 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessSpite.java +++ b/Mage.Sets/src/mage/cards/r/RecklessSpite.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -39,13 +38,15 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author Loki */ public class RecklessSpite extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creatures"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); diff --git a/Mage.Sets/src/mage/cards/s/SylvanRanger.java b/Mage.Sets/src/mage/cards/s/SylvanRanger.java index f3adf52350d..9ffcb4728b2 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanRanger.java +++ b/Mage.Sets/src/mage/cards/s/SylvanRanger.java @@ -55,7 +55,7 @@ public class SylvanRanger extends CardImpl { // When Sylvan Ranger enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } public SylvanRanger(final SylvanRanger card) { diff --git a/Mage.Sets/src/mage/cards/t/TrueConviction.java b/Mage.Sets/src/mage/cards/t/TrueConviction.java index 9e3e4051f46..66a2312b49d 100644 --- a/Mage.Sets/src/mage/cards/t/TrueConviction.java +++ b/Mage.Sets/src/mage/cards/t/TrueConviction.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; @@ -39,7 +38,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; + +import java.util.UUID; /** * @@ -51,8 +52,8 @@ public class TrueConviction extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}{W}"); // Creatures you control have double strike and lifelink. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent())); - Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent()); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)); + Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES); effect.setText(" and lifelink"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java index ca0b7598511..1d87a743ab5 100644 --- a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java +++ b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; @@ -49,6 +48,8 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -72,7 +73,7 @@ public class WalkerOfSecretWays extends CardImpl { this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{1}{U}"))); // Whenever Walker of Secret Ways deals combat damage to a player, look at that player's hand. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), true, true)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), false, true)); // {1}{U}: Return target Ninja you control to its owner's hand. Activate this ability only during your turn. Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{1}{U}"), MyTurnCondition.instance); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 2445b391bb9..1649cc3ab5e 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -97,7 +97,7 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI @Override public String getRule() { - return "Whenever a " + filter.getMessage() + " attacks, " + super.getRule(); + return "Whenever a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java index a7cb368a6c6..5dc4dd0e8ec 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java @@ -95,7 +95,7 @@ public class EntersBattlefieldAbility extends StaticAbility { return; } } - super.addEffect(effect); //To change body of generated methods, choose Tools | Templates. + super.addEffect(effect); } @Override @@ -108,6 +108,6 @@ public class EntersBattlefieldAbility extends StaticAbility { if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield " + super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield" + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 025cebb7acc..c2d2623af41 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -27,8 +27,6 @@ */ package mage.abilities.effects.common; -import java.util.ArrayList; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; @@ -43,6 +41,9 @@ import mage.game.permanent.token.Token; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -151,7 +152,7 @@ public class CreateTokenEffect extends OneShotEffect { } sb.append(token.getDescription()); if (token.getDescription().endsWith("token")) { - sb.append("s "); + sb.append("s"); } } if (attacking) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java index 6a6949d37ec..dced11b2a74 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java @@ -66,7 +66,12 @@ public class ReturnToHandChosenControlledPermanentEffect extends ReturnToHandCho protected String getText() { StringBuilder sb = new StringBuilder("return "); if (!filter.getMessage().startsWith("another")) { - sb.append(CardUtil.numberToText(number, "a")); + if(filter.getMessage().startsWith("a")){ + sb.append("an"); + } + else { + sb.append(CardUtil.numberToText(number, "a")); + } } sb.append(' ').append(filter.getMessage()); if (number > 1) { From b40078be5833a0b3927fe76eafe683b16091fdcb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 18:20:16 -0400 Subject: [PATCH 03/25] small change --- Utils/cardClass.tmpl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/cardClass.tmpl b/Utils/cardClass.tmpl index 587020011cd..5b676d13093 100644 --- a/Utils/cardClass.tmpl +++ b/Utils/cardClass.tmpl @@ -37,6 +37,9 @@ if ($power || $power eq 0) { if ($hasSubTypes eq 'true') { $OUT .="\nimport mage.constants.SubType;" } +if ($hasSuperTypes eq 'true') { + $OUT .="\nimport mage.constants.SuperType;" +} } =][=$abilitiesImports=] import mage.cards.CardImpl; From b516dbca461d0a934b5e1dddb82d85f2c843d2a8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 15:18:58 -0400 Subject: [PATCH 04/25] updated XLN spoiler --- Utils/mtg-cards-data.txt | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 54711708481..5acf19ba03f 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32342,25 +32342,31 @@ Settle the Wreckage|Ixalan|34|R|{2}{W}{W}|Instant|||Exile all attacking creature Tocatli Honor Guard|Ixalan|42|R|{1}{W}|Creature - Human Soldier|1|3|Creatures entering the battlefield don't cause abilities to trigger.| Wakening Sun's Avatar|Ixalan|44|M|{5}{W}{W}{W}|Creature - Dinosaur Avatar|7|7|When Wakening Sun's Avatar enters the battlefield, if you cast if from you hand, destroy all non-Dinosaur creatures.| Arcane Adaptation|Ixalan|46|R|{2}{U}|Enchantment|||As Arcane Adaptation enters the battlefield, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| +Chart a Course|Ixalan|48|U|{1}{U}|Sorcery|||| Daring Saboteur|Ixalan|49|R|{1}{U}|Creature - Human Pirate|2|1|{2}{U}: Daring Saboteur can't be blocked this turn.$Whenever Daring Saboteur deals combat damage to a player, you may draw a card. If you do, discard a card.| Deadeye Quartermaster|Ixalan|50|U|{3}{U}|Creature - Human Pirate|2|2|When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library.| Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| Favorable Winds|Ixalan|56|U|{1}{U}|Enchantment|||Creatures you control with flying get +1/+1.| -Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| +Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| +Lookout's Dispersal|Ixalan|62|U|{2}{U}|Instant|||Lookout's Dispersal costs {1} less to cast if you control a Pirate.$Counter target spell unless its controller pays {4}.| Storm Fleet Aerialist|Ixalan|63|U|{1}{U}|Creature - Human Pirate|1|2|Flying$Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| +Azcanta, The Sunken Ruin|Ixalan|74|R||Legendary Land|||(Transforms from Search for Azcanta)/${t} : Add {U} to your mana pool.${2U} , {t} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. | +Search for Azcanta|Ixalan|74|R|{1}{U}|Legendary Enchantment|||| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| +Storm Fleet Spy|Ixalan|84|U|{2}{U}|Creature - Human Pirate|2|2|Raid/ — When Storm Fleet Spy enters the battlefield, if you attacked with a creature this turn, draw a card.| Arguel's Blood Fast|Ixalan|90|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.| Temple of Aclazotz|Ixalan|90|R||Legendary Land|||{T}: Add {B} to your mana pool${T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness.| +Bishop of the Bloodstained|Ixalan|91|U|{3}{B}{B}|Creature - Vampire Cleric|3|3|When Bishop of the Bloodstained enters the battlefield, target player loses 1 life for each vampire you control.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| @@ -32369,18 +32375,24 @@ Deathless Ancient|Ixalan|100|U|{4}{B}{B}|Creature - Vampire Knight|4|4|Flying$Ta Duress|Ixalan|105|C|{B}|Sorcery|||Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.| Fathom Fleet Captain|Ixalan|106|R|{1}{B}|Creature - Human Pirate|2|1|Menace$Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace.| Kitesail Freebooter|Ixalan|110|U|{1}{B}|Creature - Human Pirate|1|2|Flying$When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield.| +Lurking Chupacabra|Ixalan|111|U|{3}{B}|Creature - Beast Horror|2|3|Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn| Queen's Bay Soldier|Ixalan|115|C|{1}{B}|Creature - Vampire Soldier|2|2|| Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponent controls dies, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your upkeep, if you control ten or more Treasures, you win the game.| Ruin Raider|Ixalan|118|R|{2}{B}|Creature - Orc Pirate|3|2|Raid — At the beginning of your end step, if you attacked with a creature this turn, reveal the top card of your library and put that card into your hand. You lose life equal to the card's converted mana cost.| Sanctum Seeker|Ixalan|120|R|{2}{B}{B}|Creature - Vampire Knight|3|4|Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life.| +Skittering Heartstopper|Ixalan|122|C|{B}|Creature - Insect|1|2|{B}: Skittering Heartstopper gains deathtouch until end of turn. (Any amount of damage it deals to a creature is enough to destroy it.)/| Vraska's Contempt|Ixalan|129|R|{2}{B}{B}|Instant|||Exile target creature or planeswalker. You gain 2 life.| Walk the Plank|Ixalan|130|U|{B}{B}|Sorcery|||Destroy target non-Merfolk creature.| Wanted Scoundrels|Ixalan|131|U|{1}{B}|Creature - Human Pirate|4|3|When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Angrath's Marauders|Ixalan|132|R|{5}{R}{R}|Creature - Human Pirate|4|4|If a source you control would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.| Burning Sun's Avatar|Ixalan|135|R|{3}{R}{R}{R}|Creature - Dinosaur Avatar|6|6|When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.| Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2|Haste$Whenever Captain lannery Storm attacks, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Whenever you sacrifice a Treasure, Captain Lannery Storm gets +1/+0 until end of turn.| +Dinosaur Stampede|Ixalan|140|U|{2}{R}|Instant|||| Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| Raptor Hatchling|Ixalan|149|U|{1}{R}|Creature - Dinosaur|1|1|Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample.| +Otepec Huntmaster|Ixalan|153|U|{1}{R}|Creature - Human Shaman|1|2|Dinosaur spells you cast cost {1} less to cast.${T}: Target Dinosaur gains haste until end of turn.| +Rampaging Ferocidon|Ixalan|154|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters the battlefield, Rampaging Ferocidon deals 1 damage to that creature's controller.| +Rile|Ixalan|158|C|{R}|Sorcery|||Rile deals 1 damage to target creature you control. That creature gains trample until end of turn.$Draw a card.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| Storm Fleet Arsonist|Ixalan|162|U|{4}{R}|Creature - Orc Pirate|4|4|Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent.| @@ -32391,10 +32403,14 @@ Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to target creature or player.| Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| -Deathgorge Scavenger|Ixalan|???|R|???|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you may gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| +Commune with Dinosaurs|Ixalan|181|C|{G}|Sorcery|||| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| +Grazing Whiptail|Ixalan|190|C|{2}{G}{G}|Creature - Dinosaur|3|4|Reach (This creature can block creatures with flying.)/| +Itlimoc, Cradle of the Sun|Ixalan|191|R||Legendary Land|||(Transforms from Growing Rites of Itlimoc.)/${T}: Add {G} to your mana pool.${T}: Add {G} to your mana pool for each creature you control.| +Growing Rites of Itlimoc|Ixalan|191|R|{2}{G}|Legendary Enchantment|||When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order.$At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc.| Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| +Merfolk Branchwalker|Ixalan|197|U|{1}{G}|Creature - Merfolk Scout|2|1|When Merfolk Branchwalker enters the battlefield, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put that card back or put it into your graveyard.)/| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| Ranging Raptors|Ixalan|201|U|{2}{G}|Creature - Dinosaur|2|3|Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library.| Ravenous Daggertooth|Ixalan|202|C|{2}{G}|Creature - Dinosaur|3|2|Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life.| @@ -32402,6 +32418,7 @@ Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage &mdas Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| Slice in Twain|Ixalan|207|U|{2}{G}{G}|Instant|||Destroy target artifact or enchantment.$Draw a card.| +Thundering Spineback|Ixalan|210|U|{5}{G}{G}|Creature - Dinosaur|5|5|Other Dinosaurs you control get +1/+1.${5}{G}: Create a 3/3 green Dinosaur creature token with trample.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| @@ -32419,9 +32436,12 @@ Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Ra Regisaur Alpha|Ixalan|227|R|{3}{R}{G}|Creature - Dinosaur|4|4|Other Dinosaurs you control have haste.$When Regisaur Alpha enters the battlefield, create a 3/3 green Dinosaur creature token with trample.| Shapers of Nature|Ixalan|228|U|{1}{G}{U}|Creature - Merfolk Shaman|3|3|{3}{G}: Put a +1/+1 counter on target creature.${2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| +Vona, Butcher of Magan|Ixalan|231|M|{3}{W}{B}|Legendary Creature - Vampire Knight|4|4|Vigilance, lifelink${t}, Pay 7 life: Destroy target nonland permanent. Activate this ability only during your turn.| +Vraska, Relic Seeker|Ixalan|232|M|{4}{B}{G}|Legendary Planeswalker - Vraska|||+2: Create a 2/2 Black Pirate with Menace$-3: Destroy target artifact, creature or enchantment, create a treasure$-10: Target players life total becomes 1| Conqueror's Galleon|Ixalan|234|R|{4}|Artifact - Vehicle|2|10|When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.$Crew 4| Conqueror's Foothold|Ixalan|234|R||Land|||{T}: Add {C} to your mana pool.${2}, {T}: Draw a card, then discard a card.${4}, {T}: Draw a card.${6}, {T}: Return target card from your graveyard to your hand.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| +Fell Flagship|Ixalan|238|R|{3}|Artifact - Vehicle|||Pirates you control get +1/+0.$Whenever Fell Flagship deals combat damage to a player, that player discards a card.$Crew 3| Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| Pirate's Cutlass|Ixalan|242|C|{3}|Artifact - Equipment|||When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control.$Equipped creature gets +2/+1.$Equip 2| Primal Amulet|Ixalan|243|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| From 63df22d1b1e4ebb7e260849e31c2805135fb8a93 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 15:45:52 -0400 Subject: [PATCH 05/25] fixed Dovescape not using LKI for countered spells --- Mage.Sets/src/mage/cards/d/Dovescape.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/cards/d/Dovescape.java b/Mage.Sets/src/mage/cards/d/Dovescape.java index 9d63bde0fc3..1b97b32810c 100644 --- a/Mage.Sets/src/mage/cards/d/Dovescape.java +++ b/Mage.Sets/src/mage/cards/d/Dovescape.java @@ -36,6 +36,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SetTargetPointer; +import mage.constants.Zone; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -94,6 +95,9 @@ class DovescapeEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); int spellCMC = 0; UUID spellControllerID = null; + if (spell == null) { + spell = (Spell) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK); + } if (spell != null) { spellCMC = spell.getConvertedManaCost(); spellControllerID = spell.getControllerId(); From 5109e6e620a250781e635c1894e8a11da4211d07 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 16:10:10 -0400 Subject: [PATCH 06/25] Implemented Grazing Whiptail --- .../src/mage/cards/g/GrazingWhiptail.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GrazingWhiptail.java diff --git a/Mage.Sets/src/mage/cards/g/GrazingWhiptail.java b/Mage.Sets/src/mage/cards/g/GrazingWhiptail.java new file mode 100644 index 00000000000..acaf2265dd8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrazingWhiptail.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.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.ReachAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class GrazingWhiptail extends CardImpl { + + public GrazingWhiptail(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Reach + this.addAbility(ReachAbility.getInstance()); + } + + public GrazingWhiptail(final GrazingWhiptail card) { + super(card); + } + + @Override + public GrazingWhiptail copy() { + return new GrazingWhiptail(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 5ec8f519e20..306482ef7c6 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -71,6 +71,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); + cards.add(new SetCardInfo("Grazing Whiptail", 190, Rarity.COMMON, mage.cards.g.GrazingWhiptail.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); From e6bf3c51bfcfcf727b2e09f949be4e703cbc1057 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 16:23:03 -0400 Subject: [PATCH 07/25] Implemented Otepec Huntmaster and Commune with Dinosaurs --- .../mage/cards/c/CommuneWithDinosaurs.java | 72 +++++++++++++++ .../src/mage/cards/o/OtepecHuntmaster.java | 89 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 3 files changed, 163 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java create mode 100644 Mage.Sets/src/mage/cards/o/OtepecHuntmaster.java diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java b/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java new file mode 100644 index 00000000000..8d657813de8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class CommuneWithDinosaurs extends CardImpl { + + private static final FilterCard filter = new FilterCard("a Dinosaur or land card"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.LAND), + new SubtypePredicate(SubType.DINOSAUR) + )); + } + + public CommuneWithDinosaurs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}"); + + //Look at the top five cards of your library. You may reveal a Dinosaur or land card from among them and put it into your hand. Put the rest on the bottom of your library in any order. + this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(new StaticValue(5), false, new StaticValue(1), filter, false)); + } + + public CommuneWithDinosaurs(final CommuneWithDinosaurs card) { + super(card); + } + + @Override + public CommuneWithDinosaurs copy() { + return new CommuneWithDinosaurs(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OtepecHuntmaster.java b/Mage.Sets/src/mage/cards/o/OtepecHuntmaster.java new file mode 100644 index 00000000000..bb12dd7fb42 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OtepecHuntmaster.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.keyword.HasteAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class OtepecHuntmaster extends CardImpl { + + private static final FilterCard filter = new FilterCard("Dinosaur spells"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Dinosaur"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter2.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public OtepecHuntmaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Dinosaur spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // {T}: Target Dinosaur gains haste until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter2)); + this.addAbility(ability); + } + + public OtepecHuntmaster(final OtepecHuntmaster card) { + super(card); + } + + @Override + public OtepecHuntmaster copy() { + return new OtepecHuntmaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 306482ef7c6..1842a9d3a7b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -45,6 +45,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); + cards.add(new SetCardInfo("Commune with Dinosaurs", 181, Rarity.COMMON, mage.cards.c.CommuneWithDinosaurs.class)); cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); @@ -92,6 +93,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); + cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); From 83d2ae388e48cac1cc6089802d6bbb652d605811 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 16:26:37 -0400 Subject: [PATCH 08/25] Implemented Merfolk Branchwalker --- .../src/mage/cards/m/MerfolkBranchwalker.java | 65 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MerfolkBranchwalker.java diff --git a/Mage.Sets/src/mage/cards/m/MerfolkBranchwalker.java b/Mage.Sets/src/mage/cards/m/MerfolkBranchwalker.java new file mode 100644 index 00000000000..320bf1fe585 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MerfolkBranchwalker.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.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class MerfolkBranchwalker extends CardImpl { + + public MerfolkBranchwalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // When Merfolk Branchwalker enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public MerfolkBranchwalker(final MerfolkBranchwalker card) { + super(card); + } + + @Override + public MerfolkBranchwalker copy() { + return new MerfolkBranchwalker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1842a9d3a7b..83132c170ee 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -91,6 +91,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); + cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); From 9918b8894eab80c84b2cf491e3e5dcc92a2cbdf0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 16:35:28 -0400 Subject: [PATCH 09/25] Implemented Lookout's Dispersal --- .../src/mage/cards/l/LookoutsDispersal.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LookoutsDispersal.java diff --git a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java new file mode 100644 index 00000000000..556e32d4fd2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.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.cards.l; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CounterUnlessPaysEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.TargetSpell; + +/** + * + * @author TheElk801 + */ +public class LookoutsDispersal extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + } + + public LookoutsDispersal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + // Lookout's Dispersal costs {1} less to cast if you control a Pirate. + Ability ability = new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(1, new PermanentsOnTheBattlefieldCondition(filter))); + ability.setRuleAtTheTop(true); + this.addAbility(ability); + + // Counter target spell unless its controller pays {4}. + this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(4))); + this.getSpellAbility().addTarget(new TargetSpell()); + } + + public LookoutsDispersal(final LookoutsDispersal card) { + super(card); + } + + @Override + public LookoutsDispersal copy() { + return new LookoutsDispersal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 83132c170ee..69519d76eca 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -89,6 +89,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kopala, Warden of Waves", 61, Rarity.RARE, mage.cards.k.KopalaWardenOfWaves.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); + cards.add(new SetCardInfo("Lookout's Dispersal", 62, Rarity.UNCOMMON, mage.cards.l.LookoutsDispersal.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); From b463c5331d01b551116d5cc9c3f599321ed8c2ec Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 16:42:11 -0400 Subject: [PATCH 10/25] Implemented Vona, Butcher of Magan --- .../src/mage/cards/v/VonaButcherOfMagan.java | 84 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VonaButcherOfMagan.java diff --git a/Mage.Sets/src/mage/cards/v/VonaButcherOfMagan.java b/Mage.Sets/src/mage/cards/v/VonaButcherOfMagan.java new file mode 100644 index 00000000000..6eb27ad110c --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VonaButcherOfMagan.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.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetNonlandPermanent; + +/** + * + * @author TheElk801 + */ +public class VonaButcherOfMagan extends CardImpl { + + public VonaButcherOfMagan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // {T}, Pay 7 life: Destroy target nonland permanent. Activate this ability only during your turn. + Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost(), MyTurnCondition.instance); + ability.addCost(new PayLifeCost(7)); + ability.addTarget(new TargetNonlandPermanent()); + this.addAbility(ability); + } + + public VonaButcherOfMagan(final VonaButcherOfMagan card) { + super(card); + } + + @Override + public VonaButcherOfMagan copy() { + return new VonaButcherOfMagan(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 69519d76eca..ba83cbd4a28 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -148,6 +148,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); + cards.add(new SetCardInfo("Vona, Butcher of Magan", 231, Rarity.MYTHIC, mage.cards.v.VonaButcherOfMagan.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Wakening Sun's Avatar", 44, Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); From 3e39158d8300cf71b3706130c9fffdd9c6b3e2bd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 17:02:50 -0400 Subject: [PATCH 11/25] Implemented Vraska, Relic Seeker --- .../src/mage/cards/v/VraskaRelicSeeker.java | 142 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/cardClass.tmpl | 2 +- 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java diff --git a/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java new file mode 100644 index 00000000000..4795a2c12f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java @@ -0,0 +1,142 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.PirateToken; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class VraskaRelicSeeker extends CardImpl { + + public VraskaRelicSeeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{B}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.VRASKA); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); + + //+2: Create a 2/2 black Pirate creature token with menace. + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new PirateToken()), 2)); + + //-3: Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with "T, Sacrfice this artifact. Add one mana of any color to your mana pool." + Ability ability = new LoyaltyAbility(new VraskaRelicSeekerDestroyEffect(), -3); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE_OR_ENCHANTMENT)); + this.addAbility(ability); + + //-10: Target player's life total becomes 1 + ability = new LoyaltyAbility(new VraskaRelicSeekerLifeTotalEffect(), -10); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public VraskaRelicSeeker(final VraskaRelicSeeker card) { + super(card); + } + + @Override + public VraskaRelicSeeker copy() { + return new VraskaRelicSeeker(this); + } +} + +class VraskaRelicSeekerDestroyEffect extends OneShotEffect { + + VraskaRelicSeekerDestroyEffect() { + super(Outcome.Benefit); + this.staticText = "Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with \"{T}, Sacrfice this artifact. Add one mana of any color to your mana pool.\""; + } + + VraskaRelicSeekerDestroyEffect(final VraskaRelicSeekerDestroyEffect effect) { + super(effect); + } + + @Override + public VraskaRelicSeekerDestroyEffect copy() { + return new VraskaRelicSeekerDestroyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID permanentId : targetPointer.getTargets(game, source)) { + Permanent permanent = game.getPermanent(permanentId); + if (permanent != null) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return new CreateTokenEffect(new TreasureToken()).apply(game, source); + } +} + +class VraskaRelicSeekerLifeTotalEffect extends OneShotEffect { + + public VraskaRelicSeekerLifeTotalEffect() { + super(Outcome.Benefit); + staticText = "Target player's life total becomes 1"; + } + + public VraskaRelicSeekerLifeTotalEffect(VraskaRelicSeekerLifeTotalEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + player.setLife(1, game); + return true; + } + return false; + } + + @Override + public VraskaRelicSeekerLifeTotalEffect copy() { + return new VraskaRelicSeekerLifeTotalEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index ba83cbd4a28..2d824d64cf3 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -150,6 +150,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vona, Butcher of Magan", 231, Rarity.MYTHIC, mage.cards.v.VonaButcherOfMagan.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); + cards.add(new SetCardInfo("Vraska, Relic Seeker", 232, Rarity.MYTHIC, mage.cards.v.VraskaRelicSeeker.class)); cards.add(new SetCardInfo("Wakening Sun's Avatar", 44, Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); diff --git a/Utils/cardClass.tmpl b/Utils/cardClass.tmpl index 5b676d13093..6d1f92149df 100644 --- a/Utils/cardClass.tmpl +++ b/Utils/cardClass.tmpl @@ -34,13 +34,13 @@ if ($power || $power eq 0) { }else { $OUT .= "\nimport mage.MageInt;" } +} if ($hasSubTypes eq 'true') { $OUT .="\nimport mage.constants.SubType;" } if ($hasSuperTypes eq 'true') { $OUT .="\nimport mage.constants.SuperType;" } -} =][=$abilitiesImports=] import mage.cards.CardImpl; import mage.cards.CardSetInfo; From 93cab598fd6ea5e47ecbe4b1a1186a06e7937b3b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 17:10:23 -0400 Subject: [PATCH 12/25] Implemented Lurking Chupacabra --- .../src/mage/cards/l/LurkingChupacabra.java | 118 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LurkingChupacabra.java diff --git a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java new file mode 100644 index 00000000000..6c011ea8f05 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class LurkingChupacabra extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public LurkingChupacabra(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.BEAST); + this.subtype.add(SubType.HORROR); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn + Ability ability = new LurkingChupacabraTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } + + public LurkingChupacabra(final LurkingChupacabra card) { + super(card); + } + + @Override + public LurkingChupacabra copy() { + return new LurkingChupacabra(this); + } +} + +class LurkingChupacabraTriggeredAbility extends TriggeredAbilityImpl { + + LurkingChupacabraTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + LurkingChupacabraTriggeredAbility(final LurkingChupacabraTriggeredAbility effect) { + super(effect); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.EXPLORED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null) { + return creature.getControllerId().equals(controllerId); + } + return false; + } + + @Override + public LurkingChupacabraTriggeredAbility copy() { + return new LurkingChupacabraTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn"; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2d824d64cf3..80c3dbf9949 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -90,6 +90,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Lookout's Dispersal", 62, Rarity.UNCOMMON, mage.cards.l.LookoutsDispersal.class)); + cards.add(new SetCardInfo("Lurking Chupacabra", 111, Rarity.UNCOMMON, mage.cards.l.LurkingChupacabra.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); From da6e1a5f0dbfd368c5c1c774b3164960caa3a6c3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 17:43:14 -0400 Subject: [PATCH 13/25] Implemented Thundering Spineback --- .../src/mage/cards/t/ThunderingSpineback.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThunderingSpineback.java diff --git a/Mage.Sets/src/mage/cards/t/ThunderingSpineback.java b/Mage.Sets/src/mage/cards/t/ThunderingSpineback.java new file mode 100644 index 00000000000..29df536a798 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThunderingSpineback.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.permanent.token.DinosaurToken; + +/** + * + * @author TheElk801 + */ +public class ThunderingSpineback extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public ThunderingSpineback(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Other Dinosaurs you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + + // {5}{G}: Create a 3/3 green Dinosaur creature token with trample. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DinosaurToken()), new ManaCostsImpl("{5}{G}"))); + } + + public ThunderingSpineback(final ThunderingSpineback card) { + super(card); + } + + @Override + public ThunderingSpineback copy() { + return new ThunderingSpineback(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 80c3dbf9949..0cef9e893df 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -139,6 +139,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); + cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); From f73abc2c3f32c9911120e1de8bafea7d3db8f5b8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 8 Sep 2017 23:50:32 +0200 Subject: [PATCH 14/25] [XLN] Added 5 cards. --- Mage.Sets/src/mage/cards/a/ArrowStorm.java | 5 +- .../mage/cards/a/AzcantaTheSunkenRuin.java | 88 ++++++++++++ .../src/mage/cards/b/BloodsoakedChampion.java | 12 +- .../src/mage/cards/m/MaraudingLooter.java | 2 +- .../src/mage/cards/m/MarduHordechief.java | 4 +- .../src/mage/cards/m/MarduWarshrieker.java | 4 +- Mage.Sets/src/mage/cards/p/PerfectedForm.java | 7 +- .../src/mage/cards/r/RampagingFerocidon.java | 132 ++++++++++++++++++ Mage.Sets/src/mage/cards/r/Rile.java | 67 +++++++++ .../src/mage/cards/s/SearchForAzcanta.java | 121 ++++++++++++++++ .../mage/cards/s/SkitteringHeartstopper.java | 70 ++++++++++ .../src/mage/cards/s/StormFleetArsonist.java | 7 +- Mage.Sets/src/mage/cards/s/StormFleetSpy.java | 73 ++++++++++ .../src/mage/cards/t/TimelyHordemate.java | 4 +- .../src/mage/cards/w/WarNameAspirant.java | 4 +- Mage.Sets/src/mage/cards/w/WingmateRoc.java | 2 +- Mage.Sets/src/mage/sets/Ixalan.java | 6 + 17 files changed, 583 insertions(+), 25 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java create mode 100644 Mage.Sets/src/mage/cards/r/RampagingFerocidon.java create mode 100644 Mage.Sets/src/mage/cards/r/Rile.java create mode 100644 Mage.Sets/src/mage/cards/s/SearchForAzcanta.java create mode 100644 Mage.Sets/src/mage/cards/s/SkitteringHeartstopper.java create mode 100644 Mage.Sets/src/mage/cards/s/StormFleetSpy.java diff --git a/Mage.Sets/src/mage/cards/a/ArrowStorm.java b/Mage.Sets/src/mage/cards/a/ArrowStorm.java index 4783ceb2552..741c85126ab 100644 --- a/Mage.Sets/src/mage/cards/a/ArrowStorm.java +++ b/Mage.Sets/src/mage/cards/a/ArrowStorm.java @@ -45,8 +45,7 @@ import mage.watchers.common.PlayerAttackedWatcher; public class ArrowStorm extends CardImpl { public ArrowStorm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}"); // Arrow Storm deals 4 damage to target creature or player. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( @@ -58,7 +57,7 @@ public class ArrowStorm extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new DamageTargetEffect(5, false), RaidCondition.instance, - "

Raid - If you attacked with a creature this turn, instead {this} deals 5 damage to that creature or player and the damage can't be prevented")); + "

Raid — If you attacked with a creature this turn, instead {this} deals 5 damage to that creature or player and the damage can't be prevented")); this.getSpellAbility().addWatcher(new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java new file mode 100644 index 00000000000..1e9c001d240 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.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.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.mana.BlueManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author LevelX2 + */ +public class AzcantaTheSunkenRuin extends CardImpl { + + private static final FilterCard filter = new FilterCard("noncreature, nonland card"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + } + + public AzcantaTheSunkenRuin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + + // this card is the second face of double-faced card + this.nightCard = true; + this.transformable = true; + + // (Transforms from Search for Azcanta)/ + // {T} : Add {U} to your mana pool. + this.addAbility(new BlueManaAbility()); + + // {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new LookLibraryAndPickControllerEffect(new StaticValue(4), false, new StaticValue(1), filter, false), new ManaCostsImpl<>("{2}{U}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public AzcantaTheSunkenRuin(final AzcantaTheSunkenRuin card) { + super(card); + } + + @Override + public AzcantaTheSunkenRuin copy() { + return new AzcantaTheSunkenRuin(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BloodsoakedChampion.java b/Mage.Sets/src/mage/cards/b/BloodsoakedChampion.java index 0f43b9dc6c4..3127c144a57 100644 --- a/Mage.Sets/src/mage/cards/b/BloodsoakedChampion.java +++ b/Mage.Sets/src/mage/cards/b/BloodsoakedChampion.java @@ -49,7 +49,7 @@ import mage.watchers.common.PlayerAttackedWatcher; public class BloodsoakedChampion extends CardImpl { public BloodsoakedChampion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.HUMAN, SubType.WARRIOR); this.power = new MageInt(2); @@ -57,14 +57,14 @@ public class BloodsoakedChampion extends CardImpl { // Bloodstained Brave can't block. this.addAbility(new CantBlockAbility()); - + // Raid - {1}{B}: Return Bloodstained Brave from your graveyard to the battlefield. Activate this ability only if you attacked with a creature this turn. Ability ability = new ConditionalActivatedAbility( - Zone.GRAVEYARD, - new ReturnSourceFromGraveyardToBattlefieldEffect(), - new ManaCostsImpl<>("{1}{B}"), + Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToBattlefieldEffect(), + new ManaCostsImpl<>("{1}{B}"), RaidCondition.instance, - "Raid - {1}{B}: Return {this} from your graveyard to the battlefield. Activate this ability only if you attacked with a creature this turn"); + "Raid — {1}{B}: Return {this} from your graveyard to the battlefield. Activate this ability only if you attacked with a creature this turn"); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java index 7743db82ce4..a7e467d37c9 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java @@ -58,7 +58,7 @@ public class MaraudingLooter extends CardImpl { Ability ability = new ConditionalTriggeredAbility( new BeginningOfEndStepTriggeredAbility(new DrawDiscardControllerEffect(1, 1), TargetController.YOU, false), RaidCondition.instance, - "Raid - At the beginning of your end step, " + "Raid — At the beginning of your end step, " + "if you attacked with a creature this turn, " + "you may draw a card. If you do, discard a card"); this.addAbility(ability, new PlayerAttackedWatcher()); diff --git a/Mage.Sets/src/mage/cards/m/MarduHordechief.java b/Mage.Sets/src/mage/cards/m/MarduHordechief.java index 77c0120fa28..a2c4103a8d9 100644 --- a/Mage.Sets/src/mage/cards/m/MarduHordechief.java +++ b/Mage.Sets/src/mage/cards/m/MarduHordechief.java @@ -46,7 +46,7 @@ import mage.watchers.common.PlayerAttackedWatcher; public class MarduHordechief extends CardImpl { public MarduHordechief(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add("Human"); this.subtype.add("Warrior"); @@ -55,7 +55,7 @@ public class MarduHordechief extends CardImpl { // Raid - When Mardu Hordechief enters the battlefield, if you attacked with a creature this turn, create a 1/1 white Warrior creature token this.addAbility(new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WarriorToken())), RaidCondition.instance, - "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, create a 1/1 white Warrior creature token."), + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, create a 1/1 white Warrior creature token."), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/m/MarduWarshrieker.java b/Mage.Sets/src/mage/cards/m/MarduWarshrieker.java index 7076d36e265..3f02e7b1cc6 100644 --- a/Mage.Sets/src/mage/cards/m/MarduWarshrieker.java +++ b/Mage.Sets/src/mage/cards/m/MarduWarshrieker.java @@ -46,7 +46,7 @@ import mage.watchers.common.PlayerAttackedWatcher; public class MarduWarshrieker extends CardImpl { public MarduWarshrieker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add("Orc"); this.subtype.add("Shaman"); @@ -55,7 +55,7 @@ public class MarduWarshrieker extends CardImpl { // Raid - When Mardu Warshrieker enters the battlefield, if you attacked with a creature this turn, add {R}{W}{B} to your mana pool. this.addAbility(new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new AddManaToManaPoolSourceControllerEffect(new Mana(1, 0, 0, 1, 1, 0, 0, 0))), RaidCondition.instance, - "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, add {R}{W}{B} to your mana pool."), + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, add {R}{W}{B} to your mana pool."), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/p/PerfectedForm.java b/Mage.Sets/src/mage/cards/p/PerfectedForm.java index 9836d18d248..48235b78699 100644 --- a/Mage.Sets/src/mage/cards/p/PerfectedForm.java +++ b/Mage.Sets/src/mage/cards/p/PerfectedForm.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,9 +42,9 @@ import mage.constants.CardType; public class PerfectedForm extends CardImpl { public PerfectedForm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add("Insect"); - this.subtype.add("Horror"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + this.subtype.add(SubType.INSECT); + this.subtype.add(SubType.HORROR); this.power = new MageInt(5); this.toughness = new MageInt(4); this.color.setBlue(true); diff --git a/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java b/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java new file mode 100644 index 00000000000..17663bc7fa6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java @@ -0,0 +1,132 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class RampagingFerocidon extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("another creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public RampagingFerocidon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + + // Players can't gain life. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RampagingFerocidonEffect())); + + // Whenever another creature enters the battlefield, Rampaging Ferocidon deals 1 damage to that creature's controller. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that creature's controller"), filter, false, SetTargetPointer.PLAYER, "")); + } + + public RampagingFerocidon(final RampagingFerocidon card) { + super(card); + } + + @Override + public RampagingFerocidon copy() { + return new RampagingFerocidon(this); + } +} + +class RampagingFerocidonEffect extends ContinuousRuleModifyingEffectImpl { + + public RampagingFerocidonEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true); + staticText = "Players can't gain life"; + } + + public RampagingFerocidonEffect(final RampagingFerocidonEffect effect) { + super(effect); + } + + @Override + public RampagingFerocidonEffect copy() { + return new RampagingFerocidonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + Player player = game.getPlayer(event.getPlayerId()); + if (mageObject != null && player != null) { + return player.getLogName() + " can't get " + event.getAmount() + " life (" + mageObject.getIdName() + ")."; + } + return null; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.GAIN_LIFE) { + return game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/r/Rile.java b/Mage.Sets/src/mage/cards/r/Rile.java new file mode 100644 index 00000000000..e88eba205dc --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Rile.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Rile extends CardImpl { + + public Rile(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); + + // Rile deals 1 damage to target creature you control. That creature gains trample until end of turn. + this.getSpellAbility().addEffect(new DamageTargetEffect(1)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) + .setText("That creature gains trample until end of turn")); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); + } + + public Rile(final Rile card) { + super(card); + } + + @Override + public Rile copy() { + return new Rile(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java new file mode 100644 index 00000000000..70389391b7c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.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.cards.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.cards.a.AzcantaTheSunkenRuin; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class SearchForAzcanta extends CardImpl { + + public SearchForAzcanta(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + this.transformable = true; + this.secondSideCardClazz = AzcantaTheSunkenRuin.class; + + this.addSuperType(SuperType.LEGENDARY); + + // At the beginning of your upkeep, look at the top card of your library. You may put it into your graveyard. Then if you have seven or more cards in your graveyard, you may transform Search for Azcanta. + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, false); + ability.addEffect(new ConditionalOneShotEffect(new TransformSourceEffect(true), new CardsInControllerGraveCondition(7), + "Then if you have seven or more cards in your graveyard, you may transform {this}")); + this.addAbility(ability); + this.addAbility(new TransformAbility()); + } + + public SearchForAzcanta(final SearchForAzcanta card) { + super(card); + } + + @Override + public SearchForAzcanta copy() { + return new SearchForAzcanta(this); + } +} + +class SearchForAzcantaLookLibraryEffect extends OneShotEffect { + + public SearchForAzcantaLookLibraryEffect() { + super(Outcome.DrawCard); + this.staticText = "look at the top card of your library. You may put that card into your graveyard"; + } + + public SearchForAzcantaLookLibraryEffect(final SearchForAzcantaLookLibraryEffect effect) { + super(effect); + } + + @Override + public SearchForAzcantaLookLibraryEffect copy() { + return new SearchForAzcantaLookLibraryEffect(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) { + if (controller.getLibrary().hasCards()) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + CardsImpl cards = new CardsImpl(); + cards.add(card); + controller.lookAtCards(sourceObject.getIdName(), cards, game); + if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", source, game)) { + return controller.moveCards(card, Zone.GRAVEYARD, source, game); + } + + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SkitteringHeartstopper.java b/Mage.Sets/src/mage/cards/s/SkitteringHeartstopper.java new file mode 100644 index 00000000000..aeb338db171 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkitteringHeartstopper.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class SkitteringHeartstopper extends CardImpl { + + public SkitteringHeartstopper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.INSECT); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {B}: Skittering Heartstopper gains deathtouch until end of turn. (Any amount of damage it deals to a creature is enough to destroy it.) + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B))); + } + + public SkitteringHeartstopper(final SkitteringHeartstopper card) { + super(card); + } + + @Override + public SkitteringHeartstopper copy() { + return new SkitteringHeartstopper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java index 82c7377a011..6988f647e3d 100644 --- a/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java +++ b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java @@ -37,6 +37,7 @@ import mage.abilities.effects.common.SacrificeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.FilterPermanent; import mage.target.common.TargetOpponent; import mage.watchers.common.PlayerAttackedWatcher; @@ -50,8 +51,8 @@ public class StormFleetArsonist extends CardImpl { public StormFleetArsonist(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); - this.subtype.add("Orc"); - this.subtype.add("Pirate"); + this.subtype.add(SubType.ORC); + this.subtype.add(SubType.PIRATE); this.power = new MageInt(4); this.toughness = new MageInt(4); @@ -59,7 +60,7 @@ public class StormFleetArsonist extends CardImpl { Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new SacrificeEffect(new FilterPermanent(), 1, "Target opponent")), RaidCondition.instance, - "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent."); + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent."); ability.addTarget(new TargetOpponent()); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/StormFleetSpy.java b/Mage.Sets/src/mage/cards/s/StormFleetSpy.java new file mode 100644 index 00000000000..a925ad7d9e3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetSpy.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author LevelX2 + */ +public class StormFleetSpy extends CardImpl { + + public StormFleetSpy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Raid — When Storm Fleet Spy enters the battlefield, if you attacked with a creature this turn, draw a card. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)), + RaidCondition.instance, + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, draw a card."); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public StormFleetSpy(final StormFleetSpy card) { + super(card); + } + + @Override + public StormFleetSpy copy() { + return new StormFleetSpy(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TimelyHordemate.java b/Mage.Sets/src/mage/cards/t/TimelyHordemate.java index 49521684301..36de1352c1d 100644 --- a/Mage.Sets/src/mage/cards/t/TimelyHordemate.java +++ b/Mage.Sets/src/mage/cards/t/TimelyHordemate.java @@ -56,7 +56,7 @@ public class TimelyHordemate extends CardImpl { } public TimelyHordemate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add("Human"); this.subtype.add("Warrior"); @@ -65,7 +65,7 @@ public class TimelyHordemate extends CardImpl { // Raid - When Timely Hordemate enters the battlefield, if you attacked this turn, return target creature card with converted mana cost 2 or less from your graveyard to the battlefield. Ability ability = new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()), RaidCondition.instance, - "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, return target creature card with converted mana cost 2 or less from your graveyard to the battlefield."); + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, return target creature card with converted mana cost 2 or less from your graveyard to the battlefield."); ability.addTarget(new TargetCardInYourGraveyard(filter)); this.addAbility(ability, new PlayerAttackedWatcher()); diff --git a/Mage.Sets/src/mage/cards/w/WarNameAspirant.java b/Mage.Sets/src/mage/cards/w/WarNameAspirant.java index f52bd5c5a84..a0cf1278e22 100644 --- a/Mage.Sets/src/mage/cards/w/WarNameAspirant.java +++ b/Mage.Sets/src/mage/cards/w/WarNameAspirant.java @@ -57,7 +57,7 @@ public class WarNameAspirant extends CardImpl { } public WarNameAspirant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add("Human"); this.subtype.add("Warrior"); @@ -67,7 +67,7 @@ public class WarNameAspirant extends CardImpl { // Raid - War-Name Aspirant enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.instance, - "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "Raid — {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); diff --git a/Mage.Sets/src/mage/cards/w/WingmateRoc.java b/Mage.Sets/src/mage/cards/w/WingmateRoc.java index 51fc6ab2bb0..567019306f8 100644 --- a/Mage.Sets/src/mage/cards/w/WingmateRoc.java +++ b/Mage.Sets/src/mage/cards/w/WingmateRoc.java @@ -62,7 +62,7 @@ public class WingmateRoc extends CardImpl { // Raid - When Wingmate Roc enters the battlefield, if you attacked with a creature this turn, create a 3/4 white Bird creature token with flying. this.addAbility(new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WingmateRocToken())), RaidCondition.instance, - "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, create a 3/4 white Bird creature token with flying."), + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, create a 3/4 white Bird creature token with flying."), new PlayerAttackedWatcher()); // Whenever Wingmate Roc attacks, you gain 1 life for each attacking creature. diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 5ec8f519e20..473c04f0a6f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -35,6 +35,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); + cards.add(new SetCardInfo("Azcanta, The Sunken Ruin", 74, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); @@ -100,11 +101,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); + cards.add(new SetCardInfo("Rampaging Ferocidon", 154, Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); cards.add(new SetCardInfo("Raptor Hatchling", 149, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); + cards.add(new SetCardInfo("Rile", 158, Rarity.COMMON, mage.cards.r.Rile.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); @@ -113,11 +116,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); + cards.add(new SetCardInfo("Search for Azcanta", 74, Rarity.RARE, mage.cards.s.SearchForAzcanta.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); + cards.add(new SetCardInfo("Skittering Heartstopper", 122, Rarity.COMMON, mage.cards.s.SkitteringHeartstopper.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); @@ -127,6 +132,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 63, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); + cards.add(new SetCardInfo("Storm Fleet Spy", 84, Rarity.UNCOMMON, mage.cards.s.StormFleetSpy.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); From 4be1e6b743dfd40c0547841ceeb7fc5b751f1d9e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 18:12:10 -0400 Subject: [PATCH 15/25] Implemented Growing Rites of Itlimoc and Itlimoc, Cradle of the Sun, also small changes --- .../src/mage/cards/c/CommuneWithNature.java | 23 ++--- Mage.Sets/src/mage/cards/g/GaeasCradle.java | 14 ++-- .../mage/cards/g/GrowingRitesOfItlimoc.java | 84 +++++++++++++++++++ .../mage/cards/i/ItlimocCradleOfTheSun.java | 72 ++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 5 files changed, 172 insertions(+), 23 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java create mode 100644 Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithNature.java b/Mage.Sets/src/mage/cards/c/CommuneWithNature.java index 017c3b118a5..b5dc2824bf0 100644 --- a/Mage.Sets/src/mage/cards/c/CommuneWithNature.java +++ b/Mage.Sets/src/mage/cards/c/CommuneWithNature.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.c; import java.util.UUID; @@ -34,8 +33,7 @@ import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.common.FilterCreatureCard; /** * @@ -43,21 +41,18 @@ import mage.filter.predicate.mageobject.CardTypePredicate; */ public class CommuneWithNature extends CardImpl { - private static final FilterCard filter = new FilterCard("a creature card"); - static { - filter.add(new CardTypePredicate(CardType.CREATURE)); - } - - - public CommuneWithNature (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}"); - + public CommuneWithNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}"); // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order. - this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(new StaticValue(5), false, new StaticValue(1), filter, false)); + this.getSpellAbility().addEffect( + new LookLibraryAndPickControllerEffect( + new StaticValue(5), false, new StaticValue(1), new FilterCreatureCard("a creature card"), false + ) + ); } - public CommuneWithNature (final CommuneWithNature card) { + public CommuneWithNature(final CommuneWithNature card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/g/GaeasCradle.java b/Mage.Sets/src/mage/cards/g/GaeasCradle.java index ec8e6eb47f5..8c3ee57f190 100644 --- a/Mage.Sets/src/mage/cards/g/GaeasCradle.java +++ b/Mage.Sets/src/mage/cards/g/GaeasCradle.java @@ -35,8 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.common.FilterControlledCreaturePermanent; /** * @@ -44,18 +43,15 @@ import mage.filter.predicate.mageobject.CardTypePredicate; */ public class GaeasCradle extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("creature you control"); - - static { - filter.add(new CardTypePredicate(CardType.CREATURE)); - } - public GaeasCradle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); addSuperType(SuperType.LEGENDARY); // {T}: Add {G} to your mana pool for each creature you control. - DynamicManaAbility ability = new DynamicManaAbility(Mana.GreenMana(1), new PermanentsOnBattlefieldCount(filter)); + DynamicManaAbility ability = new DynamicManaAbility( + Mana.GreenMana(1), + new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent("creature you control")) + ); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java new file mode 100644 index 00000000000..a80f059010b --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.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.cards.g; + +import java.util.UUID; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.i.ItlimocCradleOfTheSun; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; + +/** + * + * @author TheElk801 + */ +public class GrowingRitesOfItlimoc extends CardImpl { + + public GrowingRitesOfItlimoc(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.transformable = true; + this.secondSideCardClazz = ItlimocCradleOfTheSun.class; + + // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new LookLibraryAndPickControllerEffect( + new StaticValue(4), false, new StaticValue(1), new FilterCreatureCard("a creature card"), false + ))); + + // At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc. + this.addAbility(new TransformAbility()); + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false), + new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CONTROLLED_A_CREATURE, ComparisonType.MORE_THAN, 3), + "At the beginning of your end step, if you control four or more creatures, transform {this}")); + } + + public GrowingRitesOfItlimoc(final GrowingRitesOfItlimoc card) { + super(card); + } + + @Override + public GrowingRitesOfItlimoc copy() { + return new GrowingRitesOfItlimoc(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java new file mode 100644 index 00000000000..ab4b1e858c8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.mana.DynamicManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ItlimocCradleOfTheSun extends CardImpl { + + public ItlimocCradleOfTheSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.nightCard = true; + + // {T}: Add {G} to your mana pool. + this.addAbility(new GreenManaAbility()); + + // {T}: Add {G} to your mana pool for each creature you control. + DynamicManaAbility ability = new DynamicManaAbility( + Mana.GreenMana(1), + new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent("creature you control")) + ); + this.addAbility(ability); + } + + public ItlimocCradleOfTheSun(final ItlimocCradleOfTheSun card) { + super(card); + } + + @Override + public ItlimocCradleOfTheSun copy() { + return new ItlimocCradleOfTheSun(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0cef9e893df..d9610b1d35e 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -73,6 +73,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Grazing Whiptail", 190, Rarity.COMMON, mage.cards.g.GrazingWhiptail.class)); + cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); @@ -80,6 +81,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); From f77907c442e6d04c17018f38c33b1d00d9f3e492 Mon Sep 17 00:00:00 2001 From: Justin Herlehy Date: Fri, 8 Sep 2017 15:36:13 -0700 Subject: [PATCH 16/25] [XLN] Add Growing Rites of Itlimoc//Itlimoc, Cradle of the Sun --- .../mage/cards/g/GrowingRitesOfItlimoc.java | 92 +++++++++++++++++++ .../mage/cards/i/ItlimocCradleOfTheSun.java | 78 ++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 3 files changed, 172 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java create mode 100644 Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java diff --git a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java new file mode 100644 index 00000000000..bd78168fff7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; + +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.i.ItlimocCradleOfTheSun; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author JRHerlehy + */ +public class GrowingRitesOfItlimoc extends CardImpl { + + private static final FilterCard filter = new FilterCard("a creature card"); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + } + + public GrowingRitesOfItlimoc(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + + this.transformable = true; + this.secondSideCardClazz = ItlimocCradleOfTheSun.class; + + // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. + // You may reveal a creature card from among them and put it into your hand. + // Put the rest on the bottom of your library in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(4, 1, filter, true, true, Zone.HAND, false))); + + // At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc. + this.addAbility(new TransformAbility()); + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false), + new PermanentsOnTheBattlefieldCondition(new FilterControlledCreaturePermanent(), ComparisonType.MORE_THAN, 3), + "At the beginning of your end step, if you control four or more creatures, transform {this}")); + } + + public GrowingRitesOfItlimoc(final GrowingRitesOfItlimoc card) { + super(card); + } + + @Override + public GrowingRitesOfItlimoc copy() { + return new GrowingRitesOfItlimoc(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java new file mode 100644 index 00000000000..2253f437653 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.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.cards.i; + +import java.util.UUID; + +import mage.Mana; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.mana.DynamicManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author JRHerlehy + */ +public class ItlimocCradleOfTheSun extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("creature you control"); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + } + + public ItlimocCradleOfTheSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + + // (Transforms from Growing Rites of Itlimoc.)/ + this.nightCard = true; + + // {T}: Add {G} to your mana pool. + this.addAbility(new GreenManaAbility()); + + // {T}: Add {G} to your mana pool for each creature you control. + this.addAbility(new DynamicManaAbility(Mana.GreenMana(1), new PermanentsOnBattlefieldCount(filter))); + } + + public ItlimocCradleOfTheSun(final ItlimocCradleOfTheSun card) { + super(card); + } + + @Override + public ItlimocCradleOfTheSun copy() { + return new ItlimocCradleOfTheSun(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 473c04f0a6f..9e1526bc2c4 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -72,6 +72,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); + cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); @@ -79,6 +80,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); From dc8c9b8dbe4faf3a395ef0d4b020728b30dca74c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 18:43:23 -0400 Subject: [PATCH 17/25] Implemented Fell Flagship --- Mage.Sets/src/mage/cards/f/FellFlagship.java | 81 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FellFlagship.java diff --git a/Mage.Sets/src/mage/cards/f/FellFlagship.java b/Mage.Sets/src/mage/cards/f/FellFlagship.java new file mode 100644 index 00000000000..1726fc2bdcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FellFlagship.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.CrewAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class FellFlagship extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Pirates"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + } + + public FellFlagship(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.subtype.add(SubType.VEHICLE); + + // Pirates you control get +1/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter))); + + // Whenever Fell Flagship deals combat damage to a player, that player discards a card. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1, false), false, true)); + + // Crew 3 + this.addAbility(new CrewAbility(3)); + + } + + public FellFlagship(final FellFlagship card) { + super(card); + } + + @Override + public FellFlagship copy() { + return new FellFlagship(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index d9610b1d35e..3de4febfaec 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -68,6 +68,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); + cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); From b10ae22bc3607033e060b032ac386a58761f8aaf Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 18:48:08 -0400 Subject: [PATCH 18/25] resolve conflicts --- .../mage/cards/g/GrowingRitesOfItlimoc.java | 84 ------------------- .../mage/cards/i/ItlimocCradleOfTheSun.java | 72 ---------------- 2 files changed, 156 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java delete mode 100644 Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java diff --git a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java deleted file mode 100644 index a80f059010b..00000000000 --- a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.cards.g; - -import java.util.UUID; -import mage.abilities.common.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalTriggeredAbility; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.i.ItlimocCradleOfTheSun; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.TargetController; -import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureCard; - -/** - * - * @author TheElk801 - */ -public class GrowingRitesOfItlimoc extends CardImpl { - - public GrowingRitesOfItlimoc(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); - - this.addSuperType(SuperType.LEGENDARY); - this.transformable = true; - this.secondSideCardClazz = ItlimocCradleOfTheSun.class; - - // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order. - this.addAbility(new EntersBattlefieldTriggeredAbility( - new LookLibraryAndPickControllerEffect( - new StaticValue(4), false, new StaticValue(1), new FilterCreatureCard("a creature card"), false - ))); - - // At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc. - this.addAbility(new TransformAbility()); - this.addAbility(new ConditionalTriggeredAbility( - new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false), - new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CONTROLLED_A_CREATURE, ComparisonType.MORE_THAN, 3), - "At the beginning of your end step, if you control four or more creatures, transform {this}")); - } - - public GrowingRitesOfItlimoc(final GrowingRitesOfItlimoc card) { - super(card); - } - - @Override - public GrowingRitesOfItlimoc copy() { - return new GrowingRitesOfItlimoc(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java deleted file mode 100644 index ab4b1e858c8..00000000000 --- a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.cards.i; - -import java.util.UUID; -import mage.Mana; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.mana.DynamicManaAbility; -import mage.abilities.mana.GreenManaAbility; -import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.common.FilterControlledCreaturePermanent; - -/** - * - * @author TheElk801 - */ -public class ItlimocCradleOfTheSun extends CardImpl { - - public ItlimocCradleOfTheSun(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.addSuperType(SuperType.LEGENDARY); - this.nightCard = true; - - // {T}: Add {G} to your mana pool. - this.addAbility(new GreenManaAbility()); - - // {T}: Add {G} to your mana pool for each creature you control. - DynamicManaAbility ability = new DynamicManaAbility( - Mana.GreenMana(1), - new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent("creature you control")) - ); - this.addAbility(ability); - } - - public ItlimocCradleOfTheSun(final ItlimocCradleOfTheSun card) { - super(card); - } - - @Override - public ItlimocCradleOfTheSun copy() { - return new ItlimocCradleOfTheSun(this); - } -} From ee872241d67ddad7ec3adf6b41ca013efb03fd40 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 21:15:39 -0400 Subject: [PATCH 19/25] Implemented Dinosaur Stampede --- .../src/mage/cards/d/DinosaurStampede.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DinosaurStampede.java diff --git a/Mage.Sets/src/mage/cards/d/DinosaurStampede.java b/Mage.Sets/src/mage/cards/d/DinosaurStampede.java new file mode 100644 index 00000000000..33ccd1f3181 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DinosaurStampede.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.cards.d; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class DinosaurStampede extends CardImpl { + + private static final FilterAttackingCreature filter = new FilterAttackingCreature("Attacking creatures"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Dinosaurs you control"); + + static { + filter2.add(new SubtypePredicate(SubType.DINOSAUR)); + filter2.add(new ControllerPredicate(TargetController.YOU)); + } + + public DinosaurStampede(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); + + // Attacking creatures get +2/+0 until end of turn. Dinosaurs you control gain trample until end of turn. + this.getSpellAbility().addEffect(new BoostAllEffect(2, 0, Duration.EndOfTurn, filter, false)); + Effect effect = new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter2); + effect.setText("Dinosaurs you control gain trample until end of turn."); + this.getSpellAbility().addEffect(effect); + } + + public DinosaurStampede(final DinosaurStampede card) { + super(card); + } + + @Override + public DinosaurStampede copy() { + return new DinosaurStampede(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9d71c8b62c2..45e958317cf 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -57,6 +57,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); + cards.add(new SetCardInfo("Dinosaur Stampede", 140, Rarity.UNCOMMON, mage.cards.d.DinosaurStampede.class)); cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); From 6a30aeb1e11f134f0eff15bfca38bd20e1d6711f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 21:37:44 -0400 Subject: [PATCH 20/25] Implemented Bishop of the Bloodstained --- .../mage/cards/b/BishopOfTheBloodstained.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java diff --git a/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java b/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java new file mode 100644 index 00000000000..e0164886e0c --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class BishopOfTheBloodstained extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public BishopOfTheBloodstained(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Bishop of the Bloodstained enters the battlefield, target player loses 1 life for each vampire you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(new PermanentsOnBattlefieldCount(filter))); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public BishopOfTheBloodstained(final BishopOfTheBloodstained card) { + super(card); + } + + @Override + public BishopOfTheBloodstained copy() { + return new BishopOfTheBloodstained(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 45e958317cf..fa23108eb79 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -39,6 +39,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); + cards.add(new SetCardInfo("Bishop of the Bloodstained", 91, Rarity.UNCOMMON, mage.cards.b.BishopOfTheBloodstained.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); From 008767cd23afdb2ec595db6a3ede3eb386493401 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 22:00:13 -0400 Subject: [PATCH 21/25] Implemented Chart a Course --- Mage.Sets/src/mage/cards/c/ChartACourse.java | 93 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 94 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChartACourse.java diff --git a/Mage.Sets/src/mage/cards/c/ChartACourse.java b/Mage.Sets/src/mage/cards/c/ChartACourse.java new file mode 100644 index 00000000000..5e205b28b71 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChartACourse.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.cards.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class ChartACourse extends CardImpl { + + public ChartACourse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); + + // Draw two cards. Then discard a card unless you attacked with a creature this turn. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + this.getSpellAbility().addEffect(new ChartACourseEffect()); + this.getSpellAbility().addWatcher(new PlayerAttackedWatcher()); + } + + public ChartACourse(final ChartACourse card) { + super(card); + } + + @Override + public ChartACourse copy() { + return new ChartACourse(this); + } +} + +class ChartACourseEffect extends OneShotEffect { + + ChartACourseEffect() { + super(Outcome.Neutral); + this.staticText = "Then discard a card unless you attacked with a creature this turn."; + } + + ChartACourseEffect(final ChartACourseEffect effect) { + super(effect); + } + + @Override + public ChartACourseEffect copy() { + return new ChartACourseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null && !RaidCondition.instance.apply(game, source)) { + player.discard(1, false, source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index fa23108eb79..a55723f2ca5 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -47,6 +47,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); + cards.add(new SetCardInfo("Chart a Course", 48, Rarity.UNCOMMON, mage.cards.c.ChartACourse.class)); cards.add(new SetCardInfo("Commune with Dinosaurs", 181, Rarity.COMMON, mage.cards.c.CommuneWithDinosaurs.class)); cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); From 44a10a1f5cad3fc5de0875991acbf49fec082d8a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 8 Sep 2017 23:47:32 -0400 Subject: [PATCH 22/25] Implemented Arcane Adaptation --- .../src/mage/cards/a/ArcaneAdaptation.java | 189 ++++++++++++++++++ Mage.Sets/src/mage/cards/c/Conspiracy.java | 15 +- Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java diff --git a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java new file mode 100644 index 00000000000..30c2064f2f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.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.cards.a; + +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class ArcaneAdaptation extends CardImpl { + + public ArcaneAdaptation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // As Arcane Adaptation enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Neutral))); + // Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConspyEffect())); + } + + public ArcaneAdaptation(final ArcaneAdaptation card) { + super(card); + } + + @Override + public ArcaneAdaptation copy() { + return new ArcaneAdaptation(this); + } +} + +class ConspyEffect extends ContinuousEffectImpl { + + public ConspyEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield"; + } + + public ConspyEffect(final ConspyEffect effect) { + super(effect); + } + + @Override + public ConspyEffect copy() { + return new ConspyEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + SubType choice = (SubType) game.getState().getValue(source.getSourceId().toString() + "_type"); + if (controller != null && choice != null) { + // Creature cards you own that aren't on the battlefield + // in graveyard + for (UUID cardId : controller.getGraveyard()) { + Card card = game.getCard(cardId); + if (card.isCreature() && !card.getSubtype(game).contains(choice)) { + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + // on Hand + for (UUID cardId : controller.getHand()) { + Card card = game.getCard(cardId); + if (card.isCreature() && !card.getSubtype(game).contains(choice)) { + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + // in Exile + for (Card card : game.getState().getExile().getAllCards(game)) { + if (card.isCreature() && !card.getSubtype(game).contains(choice)) { + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + // in Library (e.g. for Mystical Teachings) + for (Card card : controller.getLibrary().getCards(game)) { + if (card.getOwnerId().equals(controller.getId()) && card.isCreature() && !card.getSubtype(game).contains(choice)) { + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + // commander in command zone + for (UUID commanderId : controller.getCommandersIds()) { + if (game.getState().getZone(commanderId) == Zone.COMMAND) { + Card card = game.getCard(commanderId); + if (card.isCreature() && !card.getSubtype(game).contains(choice)) { + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + } + // creature spells you control + for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { + StackObject stackObject = iterator.next(); + if (stackObject instanceof Spell + && stackObject.getControllerId().equals(source.getControllerId()) + && stackObject.isCreature() + && !stackObject.getSubtype(game).contains(choice)) { + Card card = ((Spell) stackObject).getCard(); + for (SubType s : card.getSubtype(game)) { + game.getState().getCreateCardAttribute(card).getSubtype().add(s); + } + game.getState().getCreateCardAttribute(card).getSubtype().add(choice); + } + } + // creatures you control + List creatures = game.getBattlefield().getAllActivePermanents( + new FilterControlledCreaturePermanent(), source.getControllerId(), game); + for (Permanent creature : creatures) { + if (creature != null && !creature.getSubtype(game).contains(choice)) { + creature.getSubtype(game).add(choice); + } + } + return true; + } + + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.TypeChangingEffects_4; + } +} diff --git a/Mage.Sets/src/mage/cards/c/Conspiracy.java b/Mage.Sets/src/mage/cards/c/Conspiracy.java index 7b24ba3cb4c..03ec545cc83 100644 --- a/Mage.Sets/src/mage/cards/c/Conspiracy.java +++ b/Mage.Sets/src/mage/cards/c/Conspiracy.java @@ -29,7 +29,6 @@ package mage.cards.c; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.ChooseCreatureTypeEffect; @@ -44,10 +43,10 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.players.Player; import mage.util.SubTypeList; - import java.util.Iterator; import java.util.List; import java.util.UUID; +import mage.abilities.common.AsEntersBattlefieldAbility; /** * @@ -56,10 +55,10 @@ import java.util.UUID; public class Conspiracy extends CardImpl { public Conspiracy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); // As Conspiracy enters the battlefield, choose a creature type. - this.addAbility(new EntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Neutral))); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Neutral))); // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConspiracyEffect())); } @@ -134,9 +133,9 @@ class ConspiracyEffect extends ContinuousEffectImpl { // creature spells you control for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { StackObject stackObject = iterator.next(); - if (stackObject instanceof Spell && - stackObject.getControllerId().equals(source.getControllerId()) && - stackObject.isCreature()) { + if (stackObject instanceof Spell + && stackObject.getControllerId().equals(source.getControllerId()) + && stackObject.isCreature()) { Card card = ((Spell) stackObject).getCard(); setCreatureSubtype(card, choice, game); } @@ -166,7 +165,7 @@ class ConspiracyEffect extends ContinuousEffectImpl { } private void setChosenSubtype(SubTypeList subtype, SubType choice) { - if (subtype.size() != 1 || !subtype.contains(choice)) { + if (subtype.size() != 1 || !subtype.contains(choice)) { subtype.removeAll(SubType.getCreatureTypes(false)); subtype.add(choice); } diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index a55723f2ca5..6e9c34e8580 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -33,6 +33,7 @@ public class Ixalan extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Arcane Adaptation", 46, Rarity.RARE, mage.cards.a.ArcaneAdaptation.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Azcanta, The Sunken Ruin", 74, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); From 2e2dc88c11dc4e32ff18cfbad939da57cce9d98e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 9 Sep 2017 10:07:20 +0200 Subject: [PATCH 23/25] Fixed a problem that cost reduction of some cards did not work for Zoetic Cavern (e.g. Animar, Soul of Elements). --- .../mage/cards/a/AnimarSoulOfElements.java | 13 +++- .../src/mage/cards/c/CentaurOmenreader.java | 8 ++- .../src/mage/cards/r/RakdosLordOfRiots.java | 21 ++++--- .../modification/CostModificationTest.java | 59 +++++++++++++++---- 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java index 7377f176bcd..f34ddeec7b2 100644 --- a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java +++ b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java @@ -46,6 +46,7 @@ import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.game.stack.Spell; import mage.util.CardUtil; /** @@ -111,9 +112,15 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) { - Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.isCreature())) { - return true; + if (abilityToModify.getControllerId().equals(source.getControllerId())) { + Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); + if (spell != null) { + return spell.isCreature(); + } else { + // used at least for flashback ability because Flashback ability doesn't use stack or for getPlayables where spell is not cast yet + Card sourceCard = game.getCard(abilityToModify.getSourceId()); + return sourceCard != null && sourceCard.isCreature(); + } } } return false; diff --git a/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java b/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java index 627ebf68497..40dea7f8bf7 100644 --- a/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java +++ b/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java @@ -35,6 +35,7 @@ import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; @@ -49,15 +50,16 @@ import mage.game.permanent.Permanent; public class CentaurOmenreader extends CardImpl { private static final FilterCard filter = new FilterCard("creature spells"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } public CentaurOmenreader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); addSuperType(SuperType.SNOW); - this.subtype.add("Centaur"); - this.subtype.add("Shaman"); + this.subtype.add(SubType.CENTAUR); + this.subtype.add(SubType.SHAMAN); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java index 52720812984..147de4902ad 100644 --- a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java +++ b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java @@ -45,6 +45,7 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.stack.Spell; import mage.util.CardUtil; /** @@ -54,9 +55,9 @@ import mage.util.CardUtil; public class RakdosLordOfRiots extends CardImpl { public RakdosLordOfRiots(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{R}{R}"); addSuperType(SuperType.LEGENDARY); - this.subtype.add("Demon"); + this.subtype.add(SubType.DEMON); this.power = new MageInt(6); this.toughness = new MageInt(6); @@ -102,12 +103,12 @@ class RakdosLordOfRiotsCantCastEffect extends ContinuousRuleModifyingEffectImpl public RakdosLordOfRiotsCantCastEffect copy() { return new RakdosLordOfRiotsCantCastEffect(this); } - + @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 (event.getSourceId().equals(source.getSourceId())) { @@ -147,9 +148,15 @@ class RakdosLordOfRiotsCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) { - Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.isCreature())) { - return true; + if (abilityToModify.getControllerId().equals(source.getControllerId())) { + Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); + if (spell != null) { + return spell.isCreature(); + } else { + // used at least for flashback ability because Flashback ability doesn't use stack or for getPlayables where spell is not cast yet + Card sourceCard = game.getCard(abilityToModify.getSourceId()); + return sourceCard != null && sourceCard.isCreature(); + } } } return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java index 0cb57e84577..73ee7046d9b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java @@ -2,6 +2,7 @@ package org.mage.test.cards.cost.modification; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -140,44 +141,80 @@ public class CostModificationTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Fated Conflagration", 1); assertGraveyardCount(playerB, "Carnivorous Moss-Beast", 1); } - + /* * Reported bug: Grand Arbiter Augustin IV makes moth spells you cast and your opponent cast {1} more. Should only affect opponent's spells costs. - */ + */ @Test public void testArbiterIncreasingCostBothPlayers() { - + String gArbiter = "Grand Arbiter Augustin IV"; String divination = "Divination"; String doomBlade = "Doom Blade"; - + /* - Grand Arbiter Augustin IV {2}{W}{U} + Grand Arbiter Augustin IV {2}{W}{U} 2/3 Legendary Creature - Human Advisor White spells you cast cost 1 less to cast. Blue spells you cast cost 1 less to cast. Spells your opponents cast cost 1 more to cast. - */ + */ addCard(Zone.BATTLEFIELD, playerA, gArbiter); addCard(Zone.HAND, playerA, divination); // {2}{U} Sorcery: draw two cards addCard(Zone.BATTLEFIELD, playerA, "Island", 2); - + addCard(Zone.HAND, playerB, doomBlade); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); // {1}{B} Instant: destroy target non-black creature - + // Divination should only cost {1}{U} now with the cost reduction in place for your blue spells. castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, divination); - + // Doom Blade cast by the opponent should cost {2}{B} now with the cost increase in effect for opponent spells. castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, doomBlade, gArbiter); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - + assertGraveyardCount(playerA, divination, 1); assertHandCount(playerA, 2); assertTappedCount("Island", true, 2); assertPermanentCount(playerA, gArbiter, 1); assertHandCount(playerB, doomBlade, 1); } + + /** + * Zoetic Cavern's cast as creature cost is not modified as Animar, Soul of + * Elements gains counters. + */ + @Test + public void ReduceCostToCastZoeticCavern() { + + // Protection from white and from black + // Whenever you cast a creature spell, put a +1/+1 counter on Animar, Soul of Elements. + // Creature spells you cast cost {1} less to cast for each +1/+1 counter on Animar. + addCard(Zone.BATTLEFIELD, playerA, "Animar, Soul of Elements"); + + addCard(Zone.HAND, playerA, "Silvercoat Lion", 2); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + + addCard(Zone.HAND, playerA, "Zoetic Cavern"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + + playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Zoetic Cavern"); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Silvercoat Lion", 2); + assertCounterCount(playerA, "Animar, Soul of Elements", CounterType.P1P1, 3); + + assertHandCount(playerA, "Zoetic Cavern", 0); + assertPermanentCount(playerA, "Zoetic Cavern", 0); + + assertTappedCount("Plains", false, 2); // 2 for 1st Lion 1 for 2nd lion and only 1 mana needed to cast face down Zoetic + + } } From f43950c4b870ad6fa9ec41713da18e6c756c8322 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 9 Sep 2017 10:16:26 -0400 Subject: [PATCH 24/25] Fixed various rule texts --- Mage.Sets/src/mage/cards/b/BlackcleaveCliffs.java | 4 ++-- Mage.Sets/src/mage/cards/b/BloomingMarsh.java | 4 ++-- Mage.Sets/src/mage/cards/b/BotanicalSanctum.java | 4 ++-- Mage.Sets/src/mage/cards/c/CircleOfAffliction.java | 4 ++-- Mage.Sets/src/mage/cards/c/ClifftopRetreat.java | 2 +- Mage.Sets/src/mage/cards/c/ConcealedCourtyard.java | 4 ++-- Mage.Sets/src/mage/cards/c/CopperlineGorge.java | 5 +++-- Mage.Sets/src/mage/cards/d/DarkslickShores.java | 13 ++++++------- Mage.Sets/src/mage/cards/d/DragonskullSummit.java | 7 +++---- Mage.Sets/src/mage/cards/d/DrownedCatacomb.java | 5 ++--- Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java | 12 ++++++------ Mage.Sets/src/mage/cards/g/GlacialFortress.java | 5 ++--- Mage.Sets/src/mage/cards/g/GreenwheelLiberator.java | 3 +-- Mage.Sets/src/mage/cards/h/HinterlandHarbor.java | 7 +++---- Mage.Sets/src/mage/cards/i/InspiringVantage.java | 2 +- Mage.Sets/src/mage/cards/i/IsolatedChapel.java | 2 +- Mage.Sets/src/mage/cards/l/LivingLore.java | 6 +++--- Mage.Sets/src/mage/cards/r/RazorvergeThicket.java | 4 ++-- Mage.Sets/src/mage/cards/r/RootboundCrag.java | 7 +++---- Mage.Sets/src/mage/cards/s/SeachromeCoast.java | 5 +++-- Mage.Sets/src/mage/cards/s/SpirebluffCanal.java | 4 ++-- Mage.Sets/src/mage/cards/s/SulfurFalls.java | 2 +- Mage.Sets/src/mage/cards/s/SunpetalGrove.java | 7 +++---- Mage.Sets/src/mage/cards/w/WoodlandCemetery.java | 7 +++---- .../abilities/common/EntersBattlefieldAbility.java | 3 ++- 25 files changed, 61 insertions(+), 67 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BlackcleaveCliffs.java b/Mage.Sets/src/mage/cards/b/BlackcleaveCliffs.java index 1881b61caf5..eff8060564e 100644 --- a/Mage.Sets/src/mage/cards/b/BlackcleaveCliffs.java +++ b/Mage.Sets/src/mage/cards/b/BlackcleaveCliffs.java @@ -51,10 +51,10 @@ public class BlackcleaveCliffs extends CardImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); public BlackcleaveCliffs(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlackManaAbility()); this.addAbility(new RedManaAbility()); diff --git a/Mage.Sets/src/mage/cards/b/BloomingMarsh.java b/Mage.Sets/src/mage/cards/b/BloomingMarsh.java index 10b43eaf253..a029235ef66 100644 --- a/Mage.Sets/src/mage/cards/b/BloomingMarsh.java +++ b/Mage.Sets/src/mage/cards/b/BloomingMarsh.java @@ -49,11 +49,11 @@ import mage.filter.common.FilterLandPermanent; public class BloomingMarsh extends CardImpl { public BloomingMarsh(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // Blooming Marsh enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(new FilterLandPermanent(), ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {B} or {G} to your mana pool. diff --git a/Mage.Sets/src/mage/cards/b/BotanicalSanctum.java b/Mage.Sets/src/mage/cards/b/BotanicalSanctum.java index 8c80d10605b..9ad9cb57e60 100644 --- a/Mage.Sets/src/mage/cards/b/BotanicalSanctum.java +++ b/Mage.Sets/src/mage/cards/b/BotanicalSanctum.java @@ -49,11 +49,11 @@ import mage.filter.common.FilterLandPermanent; public class BotanicalSanctum extends CardImpl { public BotanicalSanctum(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // Botanical Sanctum enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(new FilterLandPermanent(), ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {G} or {U} to your mana pool. diff --git a/Mage.Sets/src/mage/cards/c/CircleOfAffliction.java b/Mage.Sets/src/mage/cards/c/CircleOfAffliction.java index 4b8f61203d7..bdc90f9b6bb 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfAffliction.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfAffliction.java @@ -32,7 +32,7 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.ChooseColorEffect; import mage.abilities.effects.common.DoIfCostPaid; @@ -58,7 +58,7 @@ public class CircleOfAffliction extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}"); // As Circle of Affliction enters the battlefield, choose a color. - this.addAbility(new EntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // Whenever a source of the chosen color deals damage to you, you may pay {1}. If you do, target player loses 1 life and you gain 1 life. Ability ability = new CircleOfAfflictionTriggeredAbility(); diff --git a/Mage.Sets/src/mage/cards/c/ClifftopRetreat.java b/Mage.Sets/src/mage/cards/c/ClifftopRetreat.java index 40e3a4be5ef..b2359fba934 100644 --- a/Mage.Sets/src/mage/cards/c/ClifftopRetreat.java +++ b/Mage.Sets/src/mage/cards/c/ClifftopRetreat.java @@ -61,7 +61,7 @@ public class ClifftopRetreat extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Mountain or a Plains"; + String abilityText = " tapped unless you control a Mountain or a Plains"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new RedManaAbility()); this.addAbility(new WhiteManaAbility()); diff --git a/Mage.Sets/src/mage/cards/c/ConcealedCourtyard.java b/Mage.Sets/src/mage/cards/c/ConcealedCourtyard.java index 6882d4c64c2..b81bf82a81b 100644 --- a/Mage.Sets/src/mage/cards/c/ConcealedCourtyard.java +++ b/Mage.Sets/src/mage/cards/c/ConcealedCourtyard.java @@ -49,11 +49,11 @@ import mage.filter.StaticFilters; public class ConcealedCourtyard extends CardImpl { public ConcealedCourtyard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // Concealed Courtyard enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {W} or {B} to your mana pool.this.addAbility(new BlackManaAbility()); diff --git a/Mage.Sets/src/mage/cards/c/CopperlineGorge.java b/Mage.Sets/src/mage/cards/c/CopperlineGorge.java index 068a6189565..7dbdfafeb6f 100644 --- a/Mage.Sets/src/mage/cards/c/CopperlineGorge.java +++ b/Mage.Sets/src/mage/cards/c/CopperlineGorge.java @@ -47,12 +47,13 @@ import mage.filter.StaticFilters; * @author maurer.it_at_gmail.com */ public class CopperlineGorge extends CardImpl { + public CopperlineGorge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); // Copperline Gorge enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control two or fewer other lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new RedManaAbility()); this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/d/DarkslickShores.java b/Mage.Sets/src/mage/cards/d/DarkslickShores.java index 0bf6590b607..42bf7dd27f3 100644 --- a/Mage.Sets/src/mage/cards/d/DarkslickShores.java +++ b/Mage.Sets/src/mage/cards/d/DarkslickShores.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.d; import java.util.UUID; @@ -51,24 +50,24 @@ import mage.filter.predicate.permanent.AnotherPredicate; public class DarkslickShores extends CardImpl { private final static FilterLandPermanent filter = new FilterLandPermanent(); - + static { filter.add(new AnotherPredicate()); } - public DarkslickShores (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + public DarkslickShores(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); // Darkslick Shores enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control two or fewer other lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); - + this.addAbility(new BlueManaAbility()); this.addAbility(new BlackManaAbility()); } - public DarkslickShores (final DarkslickShores card) { + public DarkslickShores(final DarkslickShores card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/d/DragonskullSummit.java b/Mage.Sets/src/mage/cards/d/DragonskullSummit.java index 0f15208f99d..4238fa73604 100644 --- a/Mage.Sets/src/mage/cards/d/DragonskullSummit.java +++ b/Mage.Sets/src/mage/cards/d/DragonskullSummit.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.cards.d; import mage.abilities.common.EntersBattlefieldAbility; @@ -59,10 +58,10 @@ public class DragonskullSummit extends CardImpl { } public DragonskullSummit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tapped unless you control a Swamp or a Mountain"; + String abilityText = " tapped unless you control a Swamp or a Mountain"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlackManaAbility()); this.addAbility(new RedManaAbility()); diff --git a/Mage.Sets/src/mage/cards/d/DrownedCatacomb.java b/Mage.Sets/src/mage/cards/d/DrownedCatacomb.java index 353f91b5b37..4565940df15 100644 --- a/Mage.Sets/src/mage/cards/d/DrownedCatacomb.java +++ b/Mage.Sets/src/mage/cards/d/DrownedCatacomb.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.d; import mage.abilities.common.EntersBattlefieldAbility; @@ -59,10 +58,10 @@ public class DrownedCatacomb extends CardImpl { } public DrownedCatacomb(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Island or a Swamp"; + String abilityText = " tapped unless you control a Island or a Swamp"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlackManaAbility()); this.addAbility(new BlueManaAbility()); diff --git a/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java b/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java index b7aea530942..b3a599b5098 100644 --- a/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java +++ b/Mage.Sets/src/mage/cards/e/EtchedMonstrosity.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.e; import java.util.UUID; @@ -40,6 +39,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.target.TargetPlayer; @@ -50,19 +50,19 @@ import mage.target.TargetPlayer; */ public class EtchedMonstrosity extends CardImpl { - public EtchedMonstrosity (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); - this.subtype.add("Golem"); + public EtchedMonstrosity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + this.subtype.add(SubType.GOLEM); this.power = new MageInt(10); this.toughness = new MageInt(10); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(5)), "{this} gets five -1/-1 counters")); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(5)), " with five -1/-1 counters on it")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardTargetEffect(3), new ManaCostsImpl("{W}{U}{B}{R}{G}")); ability.addCost(new RemoveCountersSourceCost(CounterType.M1M1.createInstance(5))); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } - public EtchedMonstrosity (final EtchedMonstrosity card) { + public EtchedMonstrosity(final EtchedMonstrosity card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/g/GlacialFortress.java b/Mage.Sets/src/mage/cards/g/GlacialFortress.java index 10cd5ec9de7..0090555fb2c 100644 --- a/Mage.Sets/src/mage/cards/g/GlacialFortress.java +++ b/Mage.Sets/src/mage/cards/g/GlacialFortress.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.g; import mage.abilities.common.EntersBattlefieldAbility; @@ -59,10 +58,10 @@ public class GlacialFortress extends CardImpl { } public GlacialFortress(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Plains or an Island"; + String abilityText = " tapped unless you control a Plains or an Island"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlueManaAbility()); this.addAbility(new WhiteManaAbility()); diff --git a/Mage.Sets/src/mage/cards/g/GreenwheelLiberator.java b/Mage.Sets/src/mage/cards/g/GreenwheelLiberator.java index 7660b787a28..03eb733f0d0 100644 --- a/Mage.Sets/src/mage/cards/g/GreenwheelLiberator.java +++ b/Mage.Sets/src/mage/cards/g/GreenwheelLiberator.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.g; import java.util.UUID; @@ -57,7 +56,7 @@ public class GreenwheelLiberator extends CardImpl { // permanent you controlled left the battlefield this turn. Ability ability = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), false, RevoltCondition.instance, - "Revolt — enters the battlefield with two +1/+1 counters on it if a permanent you controlled left the battlefield this turn", null); + "Revolt — {this} enters the battlefield with two +1/+1 counters on it if a permanent you controlled left the battlefield this turn", null); ability.addWatcher(new RevoltWatcher()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HinterlandHarbor.java b/Mage.Sets/src/mage/cards/h/HinterlandHarbor.java index ab412ebbadc..62aaa793824 100644 --- a/Mage.Sets/src/mage/cards/h/HinterlandHarbor.java +++ b/Mage.Sets/src/mage/cards/h/HinterlandHarbor.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.cards.h; import mage.abilities.common.EntersBattlefieldAbility; @@ -58,10 +57,10 @@ public class HinterlandHarbor extends CardImpl { } public HinterlandHarbor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tapped unless you control a Forest or an Island"; + String abilityText = " tapped unless you control a Forest or an Island"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new GreenManaAbility()); this.addAbility(new BlueManaAbility()); diff --git a/Mage.Sets/src/mage/cards/i/InspiringVantage.java b/Mage.Sets/src/mage/cards/i/InspiringVantage.java index 1f715cb8a61..38ca08c1630 100644 --- a/Mage.Sets/src/mage/cards/i/InspiringVantage.java +++ b/Mage.Sets/src/mage/cards/i/InspiringVantage.java @@ -52,7 +52,7 @@ public class InspiringVantage extends CardImpl { // Inspiring Vantage enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {R} or {W} to your mana pool. diff --git a/Mage.Sets/src/mage/cards/i/IsolatedChapel.java b/Mage.Sets/src/mage/cards/i/IsolatedChapel.java index 761a102a52a..f002742ff34 100644 --- a/Mage.Sets/src/mage/cards/i/IsolatedChapel.java +++ b/Mage.Sets/src/mage/cards/i/IsolatedChapel.java @@ -61,7 +61,7 @@ public class IsolatedChapel extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Plains or a Swamp"; + String abilityText = " tapped unless you control a Plains or a Swamp"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new WhiteManaAbility()); this.addAbility(new BlackManaAbility()); diff --git a/Mage.Sets/src/mage/cards/l/LivingLore.java b/Mage.Sets/src/mage/cards/l/LivingLore.java index 256d20650ec..e7a0d4b4c37 100644 --- a/Mage.Sets/src/mage/cards/l/LivingLore.java +++ b/Mage.Sets/src/mage/cards/l/LivingLore.java @@ -32,8 +32,8 @@ import mage.MageInt; import mage.MageObject; import mage.MageObjectReference; import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.DealsCombatDamageTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; @@ -61,13 +61,13 @@ import mage.util.CardUtil; public class LivingLore extends CardImpl { public LivingLore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add("Avatar"); this.power = new MageInt(0); this.toughness = new MageInt(0); // As Living Lore enters the battlefield, exile an instant or sorcery card from your graveyard. - this.addAbility(new EntersBattlefieldAbility(new LivingLoreExileEffect(), "exile an instant or sorcery card from your graveyard")); + this.addAbility(new AsEntersBattlefieldAbility(new LivingLoreExileEffect(), "exile an instant or sorcery card from your graveyard")); // Living Lore's power and toughness are each equal to the exiled card's converted mana cost. this.addAbility(new SimpleStaticAbility(Zone.ALL, new LivingLoreSetPowerToughnessSourceEffect())); diff --git a/Mage.Sets/src/mage/cards/r/RazorvergeThicket.java b/Mage.Sets/src/mage/cards/r/RazorvergeThicket.java index d741d697bab..f1eab11e0cd 100644 --- a/Mage.Sets/src/mage/cards/r/RazorvergeThicket.java +++ b/Mage.Sets/src/mage/cards/r/RazorvergeThicket.java @@ -49,10 +49,10 @@ import mage.filter.StaticFilters; public class RazorvergeThicket extends CardImpl { public RazorvergeThicket(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tap it unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/r/RootboundCrag.java b/Mage.Sets/src/mage/cards/r/RootboundCrag.java index 11ce87713ed..faaecb50fb2 100644 --- a/Mage.Sets/src/mage/cards/r/RootboundCrag.java +++ b/Mage.Sets/src/mage/cards/r/RootboundCrag.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.cards.r; import mage.abilities.common.EntersBattlefieldAbility; @@ -59,10 +58,10 @@ public class RootboundCrag extends CardImpl { } public RootboundCrag(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Mountain or a Forest"; + String abilityText = " tapped unless you control a Mountain or a Forest"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new RedManaAbility()); this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/s/SeachromeCoast.java b/Mage.Sets/src/mage/cards/s/SeachromeCoast.java index f3f797839c4..f6533ab5b07 100644 --- a/Mage.Sets/src/mage/cards/s/SeachromeCoast.java +++ b/Mage.Sets/src/mage/cards/s/SeachromeCoast.java @@ -47,12 +47,13 @@ import mage.filter.StaticFilters; * @author maurer.it_at_gmail.com */ public class SeachromeCoast extends CardImpl { + public SeachromeCoast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); // Seachrome Coast enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tap it unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {W} or {U} to your mana pool. diff --git a/Mage.Sets/src/mage/cards/s/SpirebluffCanal.java b/Mage.Sets/src/mage/cards/s/SpirebluffCanal.java index 747942c5e95..696b3275625 100644 --- a/Mage.Sets/src/mage/cards/s/SpirebluffCanal.java +++ b/Mage.Sets/src/mage/cards/s/SpirebluffCanal.java @@ -49,11 +49,11 @@ import mage.filter.StaticFilters; public class SpirebluffCanal extends CardImpl { public SpirebluffCanal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // Spirebluff Canal enters the battlefield tapped unless you control two or fewer other lands. Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_LANDS, ComparisonType.FEWER_THAN, 3)); - String abilityText = "tapped unless you control fewer than 3 lands"; + String abilityText = " tapped unless you control two or fewer other lands"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); // {T}: Add {U} or {R} to your mana pool. diff --git a/Mage.Sets/src/mage/cards/s/SulfurFalls.java b/Mage.Sets/src/mage/cards/s/SulfurFalls.java index fbe5ff94f7f..ce4b437297f 100644 --- a/Mage.Sets/src/mage/cards/s/SulfurFalls.java +++ b/Mage.Sets/src/mage/cards/s/SulfurFalls.java @@ -61,7 +61,7 @@ public class SulfurFalls extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Island or a Mountain"; + String abilityText = " tapped unless you control a Island or a Mountain"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlueManaAbility()); this.addAbility(new RedManaAbility()); diff --git a/Mage.Sets/src/mage/cards/s/SunpetalGrove.java b/Mage.Sets/src/mage/cards/s/SunpetalGrove.java index 6a7e81aed73..a6083962253 100644 --- a/Mage.Sets/src/mage/cards/s/SunpetalGrove.java +++ b/Mage.Sets/src/mage/cards/s/SunpetalGrove.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.cards.s; import mage.abilities.common.EntersBattlefieldAbility; @@ -59,10 +58,10 @@ public class SunpetalGrove extends CardImpl { } public SunpetalGrove(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Forest or a Plains"; + String abilityText = " tapped unless you control a Forest or a Plains"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new GreenManaAbility()); this.addAbility(new WhiteManaAbility()); diff --git a/Mage.Sets/src/mage/cards/w/WoodlandCemetery.java b/Mage.Sets/src/mage/cards/w/WoodlandCemetery.java index 7df123b93be..9592895cc82 100644 --- a/Mage.Sets/src/mage/cards/w/WoodlandCemetery.java +++ b/Mage.Sets/src/mage/cards/w/WoodlandCemetery.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.cards.w; import mage.abilities.common.EntersBattlefieldAbility; @@ -58,10 +57,10 @@ public class WoodlandCemetery extends CardImpl { } public WoodlandCemetery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); Condition controls = new InvertCondition(new PermanentsOnTheBattlefieldCondition(filter)); - String abilityText = "tap it unless you control a Swamp or a Forest"; + String abilityText = " tapped unless you control a Swamp or a Forest"; this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new TapSourceEffect(), controls, abilityText), abilityText)); this.addAbility(new BlackManaAbility()); this.addAbility(new GreenManaAbility()); diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java index 5dc4dd0e8ec..01c582f52c7 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java @@ -108,6 +108,7 @@ public class EntersBattlefieldAbility extends StaticAbility { if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield" + super.getRule(); + String superRule = super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield" + (superRule.charAt(0) == ' ' ? "" : " ") + superRule; } } From b5667dc4a7773ddc195b5fb916c4d4a9d92be6b0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 9 Sep 2017 10:47:58 -0400 Subject: [PATCH 25/25] Added Arcane Adaptation test, updated Conspiracy test --- .../SubTypeChangingEffectsTest.java | 135 +++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java index 3e6a2548199..0aacdcbc848 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java @@ -82,7 +82,7 @@ public class SubTypeChangingEffectsTest extends CardTestPlayerBase { for (Card card : playerB.getLibrary().getCards(currentGame)) { if (card.isCreature()) { Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); - Assert.assertEquals(card.getName() + " should have CAR type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); } } @@ -171,4 +171,137 @@ public class SubTypeChangingEffectsTest extends CardTestPlayerBase { } } + + @Test + public void testArcaneAdaptationGiveType() { + // As Arcane Adaptation enters the battlefield, choose a creature type. + // Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. + addCard(Zone.HAND, playerA, "Arcane Adaptation", 1); // Enchantment {2}{U} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arcane Adaptation"); + setChoice(playerA, "Orc"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Arcane Adaptation", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + silvercoatLion = getPermanent("Silvercoat Lion", playerB); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerB.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerB.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + + } + for (Card card : playerB.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + } + + /** + * Arcane Adaptation doesn't revert creature types of non-permanent cards + * when it leaves the battlefield + */ + @Test + public void testArcaneAdaptationIsRestCorrectly() { + // As Arcane Adaptation enters the battlefield, choose a creature type. + // Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. + addCard(Zone.HAND, playerA, "Arcane Adaptation", 1); // Enchantment {2}{U} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Disenchant", 1); // Instant + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arcane Adaptation"); + setChoice(playerA, "Orc"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Disenchant", "Arcane Adaptation"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Arcane Adaptation", 1); + assertGraveyardCount(playerB, "Disenchant", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + + } + + } }