From b573d7288351cf9b2dc62b940d09ac09d7ccf883 Mon Sep 17 00:00:00 2001 From: igoudt Date: Sun, 2 Jul 2017 13:08:03 +0200 Subject: [PATCH 1/6] added UT, fix small bug on Hour of Revelation --- .../src/mage/cards/h/HourOfRevelation.java | 5 ++- .../single/hou/BontusLastReckoningTest.java | 33 +++++++++++++++ .../cards/single/hou/ChampionOfWitsTest.java | 40 +++++++++++++++++++ .../single/hou/HourOfRevelationTest.java | 26 ++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/hou/BontusLastReckoningTest.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChampionOfWitsTest.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/hou/HourOfRevelationTest.java diff --git a/Mage.Sets/src/mage/cards/h/HourOfRevelation.java b/Mage.Sets/src/mage/cards/h/HourOfRevelation.java index bdbed620df..f2b229f4a8 100644 --- a/Mage.Sets/src/mage/cards/h/HourOfRevelation.java +++ b/Mage.Sets/src/mage/cards/h/HourOfRevelation.java @@ -27,7 +27,6 @@ */ package mage.cards.h; -import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.effects.common.DestroyAllEffect; @@ -39,6 +38,8 @@ import mage.constants.ComparisonType; import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; +import java.util.UUID; + /** * * @author fireshoes @@ -51,7 +52,7 @@ public class HourOfRevelation extends CardImpl { // Hour of Revelation costs {3} less to cast if there are ten or more nonland permanents on the battlefield. SimpleStaticAbility ability = new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(3, new PermanentsOnTheBattlefieldCondition( - new FilterNonlandPermanent("there are ten or more nonland permanents on the battlefield"), ComparisonType.MORE_THAN, 9))); + new FilterNonlandPermanent("there are ten or more nonland permanents on the battlefield"), ComparisonType.MORE_THAN, 9, false))); ability.setRuleAtTheTop(true); this.addAbility(ability); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/BontusLastReckoningTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/BontusLastReckoningTest.java new file mode 100644 index 0000000000..2846c50174 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/BontusLastReckoningTest.java @@ -0,0 +1,33 @@ +package org.mage.test.cards.single.hou; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class BontusLastReckoningTest extends CardTestPlayerBase { + + private String reckoning = "Bontu's Last Reckoning"; + + @Test + public void testDelayedUntap(){ + String pouncer = "Adorned Pouncer"; + String angel = "Angel of Condemnation"; + addCard(Zone.HAND, playerA, reckoning); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + addCard(Zone.BATTLEFIELD, playerA, pouncer); + addCard(Zone.BATTLEFIELD, playerB, angel); + addCard(Zone.BATTLEFIELD, playerB, "Island"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN,playerA, reckoning); + + setStopAt(3, PhaseStep.PRECOMBAT_MAIN); + + execute(); + + assertTappedCount("Swamp", true, 3); + assertTappedCount("Island", false, 1); + assertGraveyardCount(playerA, pouncer, 1); + assertGraveyardCount(playerB, angel, 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChampionOfWitsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChampionOfWitsTest.java new file mode 100644 index 0000000000..4a6ec08e3e --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChampionOfWitsTest.java @@ -0,0 +1,40 @@ +package org.mage.test.cards.single.hou; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class ChampionOfWitsTest extends CardTestPlayerBase { + + + private final String champion = "Champion of Wits"; + + @Test + public void testEternalize(){ + addCard(Zone.GRAVEYARD, playerA, champion); + addCard(Zone.BATTLEFIELD,playerA, "Island", 10); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA,"Eternalize {5}{U}{U}"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + + execute(); + assertHandCount(playerA, 2); + } + + @Test + public void testEternalizeWithAnthem(){ + String anthem = "Glorious Anthem"; + addCard(Zone.GRAVEYARD, playerA, champion); + addCard(Zone.BATTLEFIELD,playerA, "Island", 10); + addCard(Zone.BATTLEFIELD, playerA, anthem); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA,"Eternalize {5}{U}{U}"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + + execute(); + assertHandCount(playerA, 3); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/HourOfRevelationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/HourOfRevelationTest.java new file mode 100644 index 0000000000..2d1f5998d8 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/HourOfRevelationTest.java @@ -0,0 +1,26 @@ +package org.mage.test.cards.single.hou; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class HourOfRevelationTest extends CardTestPlayerBase { + + private final String hour = "Hour of Revelation"; + + @Test + public void testCountAllPlayers() { + addCard(Zone.HAND, playerA, hour, 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 5); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears", 5); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hour); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertTappedCount("Plains", true, 3); + } +} From e302e5f3024525ab88e8f8744cbdafdaceb95724 Mon Sep 17 00:00:00 2001 From: igoudt Date: Sun, 2 Jul 2017 13:54:10 +0200 Subject: [PATCH 2/6] added dutiful servants, rampagin hippo, scrounger of souls --- .../src/mage/cards/d/DutifulServants.java | 26 ++++++++++++++ .../src/mage/cards/r/RampagingHippo.java | 35 +++++++++++++++++++ .../src/mage/cards/s/ScroungerOfSouls.java | 31 ++++++++++++++++ .../src/mage/sets/HourOfDevastation.java | 8 +++-- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DutifulServants.java create mode 100644 Mage.Sets/src/mage/cards/r/RampagingHippo.java create mode 100644 Mage.Sets/src/mage/cards/s/ScroungerOfSouls.java diff --git a/Mage.Sets/src/mage/cards/d/DutifulServants.java b/Mage.Sets/src/mage/cards/d/DutifulServants.java new file mode 100644 index 0000000000..d09dfcf50f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DutifulServants.java @@ -0,0 +1,26 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +public class DutifulServants extends CardImpl { + + public DutifulServants(UUID ownerId, CardSetInfo cardSetInfo){ + super(ownerId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + subtype.add("Zombie"); + power = new MageInt(2); + toughness = new MageInt(5); + } + + public DutifulServants(final DutifulServants dutifulServants){ + super(dutifulServants); + } + + public DutifulServants copy(){ + return new DutifulServants(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RampagingHippo.java b/Mage.Sets/src/mage/cards/r/RampagingHippo.java new file mode 100644 index 0000000000..ff5286a99d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RampagingHippo.java @@ -0,0 +1,35 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +public class RampagingHippo extends CardImpl { + + public RampagingHippo(UUID cardID, CardSetInfo cardSetInfo){ + super(cardID, cardSetInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + subtype.add("Hippo"); + power = new MageInt(5); + toughness = new MageInt(6); + + // Trample + addAbility(TrampleAbility.getInstance()); + + // Cycling {2} + addAbility(new CyclingAbility(new ManaCostsImpl("2"))); + } + + public RampagingHippo(final RampagingHippo rampagingHippo){ + super(rampagingHippo); + } + + public RampagingHippo copy(){ + return new RampagingHippo(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScroungerOfSouls.java b/Mage.Sets/src/mage/cards/s/ScroungerOfSouls.java new file mode 100644 index 0000000000..c684ab11cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScroungerOfSouls.java @@ -0,0 +1,31 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +public class ScroungerOfSouls extends CardImpl { + + public ScroungerOfSouls(UUID cardID, CardSetInfo cardSetInfo){ + super(cardID, cardSetInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + subtype.add("Horror"); + + power = new MageInt(3); + toughness = new MageInt(4); + + // Lifelink + addAbility(LifelinkAbility.getInstance()); + + } + + public ScroungerOfSouls(final ScroungerOfSouls scroungerOfSouls){ + super(scroungerOfSouls); + } + public ScroungerOfSouls copy(){ + return new ScroungerOfSouls(this); + } +} diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index d44af937ff..bc16f25bcb 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -27,8 +27,6 @@ */ package mage.sets; -import java.util.ArrayList; -import java.util.List; import mage.cards.CardGraphicInfo; import mage.cards.ExpansionSet; import mage.cards.FrameStyle; @@ -38,6 +36,9 @@ import mage.cards.repository.CardRepository; import mage.constants.Rarity; import mage.constants.SetType; +import java.util.ArrayList; +import java.util.List; + /** * @author fireshoes */ @@ -88,6 +89,7 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Djeru, With Eyes Open", 10, Rarity.RARE, mage.cards.d.DjeruWithEyesOpen.class)); cards.add(new SetCardInfo("Doomfall", 62, Rarity.UNCOMMON, mage.cards.d.Doomfall.class)); cards.add(new SetCardInfo("Dreamstealer", 63, Rarity.RARE, mage.cards.d.Dreamstealer.class)); + cards.add(new SetCardInfo("Dutiful Servants", 12, Rarity.COMMON, mage.cards.d.DutifulServants.class)); cards.add(new SetCardInfo("Earthshaker Khenra", 90, Rarity.RARE, mage.cards.e.EarthshakerKhenra.class)); cards.add(new SetCardInfo("Fervent Paincaster", 91, Rarity.UNCOMMON, mage.cards.f.FerventPaincaster.class)); cards.add(new SetCardInfo("Forest", 189, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true))); @@ -116,6 +118,7 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Plains", 185, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Pride Sovereign", 126, Rarity.RARE, mage.cards.p.PrideSovereign.class)); cards.add(new SetCardInfo("Proven Combatant", 42, Rarity.COMMON, mage.cards.p.ProvenCombatant.class)); + cards.add(new SetCardInfo("Rampaging Hippo", 128, Rarity.COMMON, mage.cards.r.RampagingHippo.class)); cards.add(new SetCardInfo("Ramunap Excavator", 129, Rarity.RARE, mage.cards.r.RamunapExcavator.class)); cards.add(new SetCardInfo("Ramunap Hydra", 130, Rarity.RARE, mage.cards.r.RamunapHydra.class)); cards.add(new SetCardInfo("Razaketh, the Foulblooded", 73, Rarity.MYTHIC, mage.cards.r.RazakethTheFoulblooded.class)); @@ -124,6 +127,7 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Samut, the Tested", 144, Rarity.MYTHIC, mage.cards.s.SamutTheTested.class)); cards.add(new SetCardInfo("Sand Strangler", 107, Rarity.UNCOMMON, mage.cards.s.SandStrangler.class)); cards.add(new SetCardInfo("Sandblast", 20, Rarity.COMMON, mage.cards.s.Sandblast.class)); + cards.add(new SetCardInfo("Scrounger of Souls", 76, Rarity.COMMON, mage.cards.s.ScroungerOfSouls.class)); cards.add(new SetCardInfo("Sidewinder Naga", 134, Rarity.COMMON, mage.cards.s.SidewinderNaga.class)); cards.add(new SetCardInfo("Sinuous Striker", 45, Rarity.UNCOMMON, mage.cards.s.SinuousStriker.class)); cards.add(new SetCardInfo("Solemnity", 22, Rarity.RARE, mage.cards.s.Solemnity.class)); From e0464635c47bda4274bc70314a0bd41b51b1dcf8 Mon Sep 17 00:00:00 2001 From: spjspj Date: Sun, 2 Jul 2017 22:48:00 +1000 Subject: [PATCH 3/6] Implement 2 cards (HOU) --- .../src/mage/cards/t/TenaciousHunter.java | 91 +++++++++++++++++++ Mage.Sets/src/mage/cards/t/ThornedMoloch.java | 77 ++++++++++++++++ Mage.Sets/src/mage/cards/t/TragicLesson.java | 3 +- .../src/mage/sets/HourOfDevastation.java | 2 + 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/t/TenaciousHunter.java create mode 100644 Mage.Sets/src/mage/cards/t/ThornedMoloch.java diff --git a/Mage.Sets/src/mage/cards/t/TenaciousHunter.java b/Mage.Sets/src/mage/cards/t/TenaciousHunter.java new file mode 100644 index 0000000000..82d6d6eb50 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TenaciousHunter.java @@ -0,0 +1,91 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; + +/** + * + * @author spjspj + */ +public class TenaciousHunter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature has a -1/-1 counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.M1M1)); + } + + public TenaciousHunter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + + this.subtype.add("Crocodile"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // As long as a creature has a -1/-1 counter on it, Tenacious Hunter has vigilance and deathtouch. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(VigilanceAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter), + "{this} has Vigilance as long as a creature has a -1/-1 counter on it" + ) + ); + + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(DeathtouchAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter), + "{this} has Deathtouch as long as a creature has a -1/-1 counter on it" + ) + ); + + this.addAbility(ability); + } + + public TenaciousHunter(final TenaciousHunter card) { + super(card); + } + + @Override + public TenaciousHunter copy() { + return new TenaciousHunter(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/ThornedMoloch.java b/Mage.Sets/src/mage/cards/t/ThornedMoloch.java new file mode 100644 index 0000000000..54275a0f47 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThornedMoloch.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.SourceAttackingCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author spjspj + */ +public class ThornedMoloch extends CardImpl { + + public ThornedMoloch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add("Lizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Prowess + this.addAbility(new ProwessAbility()); + + // Thorned Moloch has first strike as long as it's attacking. + this.addAbility( + new SimpleStaticAbility( + Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), SourceAttackingCondition.instance, "{this} has first strike as long as it's attacking") + ) + ); + + } + + public ThornedMoloch(final ThornedMoloch card) { + super(card); + } + + @Override + public ThornedMoloch copy() { + return new ThornedMoloch(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TragicLesson.java b/Mage.Sets/src/mage/cards/t/TragicLesson.java index f728e0ff65..7ce12df4e3 100644 --- a/Mage.Sets/src/mage/cards/t/TragicLesson.java +++ b/Mage.Sets/src/mage/cards/t/TragicLesson.java @@ -33,6 +33,7 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -98,7 +99,7 @@ class TragicLessonEffect extends OneShotEffect { Cost cost = new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)); if (cost.canPay(source, source.getSourceId(), controller.getId(), game)) { if (cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) { - return true; + return true; } } } diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index d44af937ff..e1895efa3c 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -134,9 +134,11 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Supreme Will", 49, Rarity.UNCOMMON, mage.cards.s.SupremeWill.class)); cards.add(new SetCardInfo("Swamp", 187, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Swarm Intelligence", 50, Rarity.RARE, mage.cards.s.SwarmIntelligence.class)); + cards.add(new SetCardInfo("Tenacious Hunter", 136, Rarity.UNCOMMON, mage.cards.t.TenaciousHunter.class)); cards.add(new SetCardInfo("The Locust God", 139, Rarity.MYTHIC, mage.cards.t.TheLocustGod.class)); cards.add(new SetCardInfo("The Scarab God", 145, Rarity.MYTHIC, mage.cards.t.TheScarabGod.class)); cards.add(new SetCardInfo("The Scorpion God", 146, Rarity.MYTHIC, mage.cards.t.TheScorpionGod.class)); + cards.add(new SetCardInfo("Thorned Moloch", 108, Rarity.COMMON, mage.cards.t.ThornedMoloch.class)); cards.add(new SetCardInfo("Torment of Hailfire", 77, Rarity.RARE, mage.cards.t.TormentOfHailfire.class)); cards.add(new SetCardInfo("Torment of Scarabs", 78, Rarity.UNCOMMON, mage.cards.t.TormentOfScarabs.class)); cards.add(new SetCardInfo("Torment of Venom", 79, Rarity.COMMON, mage.cards.t.TormentOfVenom.class)); From 7028f8ee3d75fce0d2534508e44b87cd705e1f65 Mon Sep 17 00:00:00 2001 From: igoudt Date: Sun, 2 Jul 2017 15:36:18 +0200 Subject: [PATCH 4/6] implement Chaos Maw --- Mage.Sets/src/mage/cards/c/ChaosMaw.java | 36 +++++++++++++++++++ .../src/mage/sets/HourOfDevastation.java | 1 + .../test/cards/single/hou/ChaosMawTest.java | 28 +++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChaosMaw.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChaosMawTest.java diff --git a/Mage.Sets/src/mage/cards/c/ChaosMaw.java b/Mage.Sets/src/mage/cards/c/ChaosMaw.java new file mode 100644 index 0000000000..32cb6aaf00 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosMaw.java @@ -0,0 +1,36 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +import java.util.UUID; + +public class ChaosMaw extends CardImpl { + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature"); + static { + filter.add(new AnotherPredicate()); + } + public ChaosMaw(UUID ownerId, CardSetInfo cardSetInfo){ + super(ownerId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); + subtype.add("Hellion"); + power = new MageInt(6); + toughness = new MageInt(6); + + // When Chaos Maw enters the battlefield, it deals 3 damage to each other creature + addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(3, filter))); + } + + public ChaosMaw(final ChaosMaw chaosMaw){ + super(chaosMaw); + } + + public ChaosMaw copy(){ + return new ChaosMaw(this); + } +} diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index bc16f25bcb..705461134c 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -76,6 +76,7 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Carrion Screecher", 61, Rarity.COMMON, mage.cards.c.CarrionScreecher.class)); cards.add(new SetCardInfo("Champion of Wits", 31, Rarity.RARE, mage.cards.c.ChampionOfWits.class)); cards.add(new SetCardInfo("Chandra's Defeat", 86, Rarity.UNCOMMON, mage.cards.c.ChandrasDefeat.class)); + cards.add(new SetCardInfo("Chaos Maw", 87, Rarity.RARE, mage.cards.c.ChaosMaw.class)); cards.add(new SetCardInfo("Cinder Barrens", 209, Rarity.COMMON, mage.cards.c.CinderBarrens.class)); cards.add(new SetCardInfo("Claim // Fame", 150, Rarity.UNCOMMON, mage.cards.c.ClaimFame.class)); cards.add(new SetCardInfo("Crook of Condemnation", 159, Rarity.UNCOMMON, mage.cards.c.CrookOfCondemnation.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChaosMawTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChaosMawTest.java new file mode 100644 index 0000000000..33084c5154 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/ChaosMawTest.java @@ -0,0 +1,28 @@ +package org.mage.test.cards.single.hou; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class ChaosMawTest extends CardTestPlayerBase { + + private String chaosMaw = "Chaos Maw"; + + @Test + public void testChaosMaw(){ + addCard(Zone.HAND, playerA, chaosMaw, 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1); + addCard(Zone.BATTLEFIELD, playerB, "Savannah Lions", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, chaosMaw ); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + + execute(); + + assertGraveyardCount(playerA, "Grizzly Bears", 1); + assertGraveyardCount(playerB, "Savannah Lions", 1); + } +} From c3c09eab2c26dca07bd1ae8269fc4389cf4a0bcb Mon Sep 17 00:00:00 2001 From: spjspj Date: Mon, 3 Jul 2017 00:23:05 +1000 Subject: [PATCH 5/6] Implement 2 cards (HOU) --- .../src/mage/cards/s/SunscourgeChampion.java | 109 ++++++++++++++++++ .../src/mage/cards/s/SurvivorsEncampment.java | 78 +++++++++++++ .../src/mage/sets/HourOfDevastation.java | 2 + 3 files changed, 189 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SunscourgeChampion.java create mode 100644 Mage.Sets/src/mage/cards/s/SurvivorsEncampment.java diff --git a/Mage.Sets/src/mage/cards/s/SunscourgeChampion.java b/Mage.Sets/src/mage/cards/s/SunscourgeChampion.java new file mode 100644 index 0000000000..1b8287d127 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunscourgeChampion.java @@ -0,0 +1,109 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EternalizeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author spjspj + */ +public class SunscourgeChampion extends CardImpl { + + private static String rule = "Eternalize - {2}{W}{W}, Discard a card ({2}{W}{W}, Discard a card, Exile this card from your graveyard: Create a token that's a copy of it, except it's a 4/4 black Zombie"; + + public SunscourgeChampion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Sunscourge Champion enters the battlefield, you gain life equal to its power. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SunscourgeChampionEffect(), false)); + + // Eternalize - {2}{W}{W}, Discard a card. + EternalizeAbility ability = new EternalizeAbility(new ManaCostsImpl("{2}{W}{W}"), this, rule); + ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + } + + public SunscourgeChampion(final SunscourgeChampion card) { + super(card); + } + + @Override + public SunscourgeChampion copy() { + return new SunscourgeChampion(this); + } +} + +class SunscourgeChampionEffect extends OneShotEffect { + + public SunscourgeChampionEffect() { + super(Outcome.Benefit); + staticText = "you gain life equal to its power."; + } + + public SunscourgeChampionEffect(final SunscourgeChampionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && permanent != null && sourceObject != null) { + controller.gainLife(permanent.getPower().getValue(), game); + return true; + } + return false; + } + + @Override + public SunscourgeChampionEffect copy() { + return new SunscourgeChampionEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SurvivorsEncampment.java b/Mage.Sets/src/mage/cards/s/SurvivorsEncampment.java new file mode 100644 index 0000000000..004a584646 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SurvivorsEncampment.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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.mana.AnyColorManaAbility; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import static mage.cards.s.SpellstutterSprite.filter; +import mage.constants.CardType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author spjspj + */ +public class SurvivorsEncampment extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an untapped creature you control"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + } + + public SurvivorsEncampment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Desert"); + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {T}, Tap an untapped creature you control: Add one mana of any color to your mana pool. + Ability ability = new AnyColorManaAbility(); + ability.addCost(new TapTargetCost(new TargetControlledPermanent(filter))); + this.addAbility(ability); + } + + public SurvivorsEncampment(final SurvivorsEncampment card) { + super(card); + } + + @Override + public SurvivorsEncampment copy() { + return new SurvivorsEncampment(this); + } +} diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index e1895efa3c..4644a6b653 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -130,8 +130,10 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Steadfast Sentinel", 24, Rarity.COMMON, mage.cards.s.SteadfastSentinel.class)); cards.add(new SetCardInfo("Strategic Planning", 47, Rarity.COMMON, mage.cards.s.StrategicPlanning.class)); cards.add(new SetCardInfo("Struggle // Survive", 151, Rarity.UNCOMMON, mage.cards.s.StruggleSurvive.class)); + cards.add(new SetCardInfo("Sunscourge Champion", 26, Rarity.UNCOMMON, mage.cards.s.SunscourgeChampion.class)); cards.add(new SetCardInfo("Sunset Pyramid", 166, Rarity.UNCOMMON, mage.cards.s.SunsetPyramid.class)); cards.add(new SetCardInfo("Supreme Will", 49, Rarity.UNCOMMON, mage.cards.s.SupremeWill.class)); + cards.add(new SetCardInfo("Survivors' Encampment", 184, Rarity.COMMON, mage.cards.s.SurvivorsEncampment.class)); cards.add(new SetCardInfo("Swamp", 187, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Swarm Intelligence", 50, Rarity.RARE, mage.cards.s.SwarmIntelligence.class)); cards.add(new SetCardInfo("Tenacious Hunter", 136, Rarity.UNCOMMON, mage.cards.t.TenaciousHunter.class)); From 8e4f47894692baf311e403e86201c2d273416f04 Mon Sep 17 00:00:00 2001 From: spjspj Date: Mon, 3 Jul 2017 09:08:24 +1000 Subject: [PATCH 6/6] Implement 2 cards (HOU) --- .../main/java/mage/abilities/keyword/EternalizeAbility.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java index 28d9aec01c..0fa338038b 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java @@ -58,6 +58,11 @@ public class EternalizeAbility extends ActivatedAbilityImpl { this.timing = TimingRule.SORCERY; setRule(cost, card); } + + public EternalizeAbility(Cost cost, Card card, String rule) { + this(cost, card); + this.rule = rule; + } public EternalizeAbility(final EternalizeAbility ability) { super(ability);