diff --git a/Mage.Sets/src/mage/cards/g/GrimGiganotosaurus.java b/Mage.Sets/src/mage/cards/g/GrimGiganotosaurus.java new file mode 100644 index 00000000000..f67309915c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrimGiganotosaurus.java @@ -0,0 +1,83 @@ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; +import mage.abilities.costs.CostAdjuster; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.keyword.MonstrosityAbility; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author jimga150 + */ +public final class GrimGiganotosaurus extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifacts and creatures other than {this}"); + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.or(CardType.ARTIFACT.getPredicate(), CardType.CREATURE.getPredicate())); + } + + public GrimGiganotosaurus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(10); + this.toughness = new MageInt(10); + + // {10}{B}{G}: Monstrosity 10. This ability costs {1} less to activate for each creature with power 4 or greater your opponents control. + this.addAbility(new MonstrosityAbility("{10}{B}{G}", 10, + GrimGiganotosaurusAdjuster.instance, + "This ability costs {1} less to activate for each creature with power 4 or greater your opponents control. ")); + + // When Grim Giganotosaurus becomes monstrous, destroy all artifacts and creatures other than Grim Giganotosaurus. + this.addAbility(new BecomesMonstrousSourceTriggeredAbility(new DestroyAllEffect(filter))); + } + + private GrimGiganotosaurus(final GrimGiganotosaurus card) { + super(card); + } + + @Override + public GrimGiganotosaurus copy() { + return new GrimGiganotosaurus(this); + } +} + +enum GrimGiganotosaurusAdjuster implements CostAdjuster { + instance; + + private static final FilterCreaturePermanent filter = new FilterOpponentsCreaturePermanent("creature with power 4 or greater your opponents control"); + + static { + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); + + @Override + public void adjustCosts(Ability ability, Game game) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + CardUtil.reduceCost(ability, xValue.calculate(game, ability, null)); + } + } +} diff --git a/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java b/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java index 8e761f5ebbe..f56e30fe582 100644 --- a/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java +++ b/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java @@ -6,7 +6,6 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.CostAdjuster; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; @@ -45,12 +44,9 @@ public final class NemesisOfMortals extends CardImpl { this.addAbility(ability); // {7}{G}{G}: Monstrosity 5. This ability costs {1} less to activate for each creature card in your graveyard. - ability = new MonstrosityAbility("{7}{G}{G}", 5); - for (Effect effect : ability.getEffects()) { - effect.setText("Monstrosity 5. This ability costs {1} less to activate for each creature card in your graveyard"); - } - ability.setCostAdjuster(NemesisOfMortalsAdjuster.instance); - this.addAbility(ability); + this.addAbility(new MonstrosityAbility("{7}{G}{G}", 5, + NemesisOfMortalsAdjuster.instance, + "This ability costs {1} less to activate for each creature card in your graveyard")); } private NemesisOfMortals(final NemesisOfMortals card) { diff --git a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java index 3748843259b..6e5cd44389f 100644 --- a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java +++ b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java @@ -30,6 +30,7 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Ellie and Alan, Paleontologists", 10, Rarity.RARE, mage.cards.e.EllieAndAlanPaleontologists.class)); cards.add(new SetCardInfo("Forest", 25, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Forest", "25b", Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Grim Giganotosaurus", 11, Rarity.RARE, mage.cards.g.GrimGiganotosaurus.class)); cards.add(new SetCardInfo("Henry Wu, InGen Geneticist", 12, Rarity.RARE, mage.cards.h.HenryWuInGenGeneticist.class)); cards.add(new SetCardInfo("Hunting Velociraptor", 4, Rarity.RARE, mage.cards.h.HuntingVelociraptor.class)); cards.add(new SetCardInfo("Island", 22, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/NemesisOfMortalsTests.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/NemesisOfMortalsTests.java new file mode 100644 index 00000000000..eb0d6c2c218 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/NemesisOfMortalsTests.java @@ -0,0 +1,42 @@ +package org.mage.test.cards.abilities.activated; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class NemesisOfMortalsTests extends CardTestPlayerBase { + + @Test + public void testNoCostReduction() { + + addCard(Zone.BATTLEFIELD, playerA, "Nemesis of Mortals"); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 9); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{7}{G}{G}"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertTappedCount("Forest", true, 9); + } + + @Test + public void testWithCostReduction() { + + addCard(Zone.BATTLEFIELD, playerA, "Nemesis of Mortals"); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 9); + + addCard(Zone.GRAVEYARD, playerA, "Memnite", 4); + addCard(Zone.GRAVEYARD, playerA, "Forest", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{7}{G}{G}"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertTappedCount("Forest", true, 5); + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/MonstrosityAbility.java b/Mage/src/main/java/mage/abilities/keyword/MonstrosityAbility.java index b0eb18499aa..e1ebfc885c4 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MonstrosityAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MonstrosityAbility.java @@ -2,7 +2,9 @@ package mage.abilities.keyword; import mage.abilities.Ability; import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.hint.common.MonstrousHint; import mage.constants.Outcome; @@ -44,15 +46,21 @@ public class MonstrosityAbility extends ActivatedAbilityImpl { private final int monstrosityValue; + public MonstrosityAbility(String manaString, int monstrosityValue) { + this(manaString, monstrosityValue, null, ""); + } + /** * @param manaString * @param monstrosityValue use Integer.MAX_VALUE for monstrosity X. + * @param costAdjuster + * @param costAdjusterText Clarifies the cost adjusting condition(s). */ - public MonstrosityAbility(String manaString, int monstrosityValue) { - super(Zone.BATTLEFIELD, new BecomeMonstrousSourceEffect(monstrosityValue), new ManaCostsImpl<>(manaString)); + public MonstrosityAbility(String manaString, int monstrosityValue, CostAdjuster costAdjuster, String costAdjusterText) { + super(Zone.BATTLEFIELD, new BecomeMonstrousSourceEffect(monstrosityValue, costAdjusterText), new ManaCostsImpl<>(manaString)); this.monstrosityValue = monstrosityValue; - this.addHint(MonstrousHint.instance); + setCostAdjuster(costAdjuster); } protected MonstrosityAbility(final MonstrosityAbility ability) { @@ -74,8 +82,12 @@ public class MonstrosityAbility extends ActivatedAbilityImpl { class BecomeMonstrousSourceEffect extends OneShotEffect { public BecomeMonstrousSourceEffect(int monstrosityValue) { + this(monstrosityValue, ""); + } + + public BecomeMonstrousSourceEffect(int monstrosityValue, String costAdjusterText) { super(Outcome.BoostCreature); - this.staticText = setText(monstrosityValue); + this.staticText = setText(monstrosityValue, costAdjusterText); } protected BecomeMonstrousSourceEffect(final BecomeMonstrousSourceEffect effect) { @@ -110,9 +122,9 @@ class BecomeMonstrousSourceEffect extends OneShotEffect { return true; } - private String setText(int monstrosityValue) { + private String setText(int monstrosityValue, String costAdjusterText) { return "Monstrosity " + (monstrosityValue == Integer.MAX_VALUE ? "X" : monstrosityValue) + - ". (If this creature isn't monstrous, put " + + ". " + costAdjusterText + "(If this creature isn't monstrous, put " + (monstrosityValue == Integer.MAX_VALUE ? "X" : CardUtil.numberToText(monstrosityValue)) + " +1/+1 counters on it and it becomes monstrous.)"; }