From ec34bb53d040c217d3ce3b8441b09976bda55c04 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Wed, 1 May 2024 15:40:41 +0200 Subject: [PATCH] implement [PIP] Young Deathclaws --- .../mage/cards/v/VarolzTheScarStriped.java | 52 ++------------ .../src/mage/cards/y/YoungDeathclaws.java | 46 +++++++++++++ Mage.Sets/src/mage/sets/Fallout.java | 1 + .../other/VarolzTheScarStripedTest.java | 28 +++++--- .../common/GiveScavengeContinuousEffect.java | 67 +++++++++++++++++++ 5 files changed, 140 insertions(+), 54 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/y/YoungDeathclaws.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/GiveScavengeContinuousEffect.java diff --git a/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java b/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java index a790c8740de..3e69d2901b9 100644 --- a/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java +++ b/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java @@ -1,27 +1,20 @@ package mage.cards.v; -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.SacrificeTargetCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.GiveScavengeContinuousEffect; import mage.abilities.effects.common.RegenerateSourceEffect; -import mage.abilities.keyword.ScavengeAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class VarolzTheScarStriped extends CardImpl { @@ -36,7 +29,9 @@ public final class VarolzTheScarStriped extends CardImpl { this.toughness = new MageInt(2); // Each creature card in your graveyard has scavenge. The scavenge cost is equal to its mana cost. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VarolzTheScarStripedEffect())); + this.addAbility(new SimpleStaticAbility( + new GiveScavengeContinuousEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_CARD_CREATURE) + )); // Sacrifice another creature: Regenerate Varolz, the Scar-Striped. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), @@ -52,38 +47,3 @@ public final class VarolzTheScarStriped extends CardImpl { return new VarolzTheScarStriped(this); } } - -class VarolzTheScarStripedEffect extends ContinuousEffectImpl { - - VarolzTheScarStripedEffect() { - super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); - staticText = "Each creature card in your graveyard has scavenge. The scavenge cost is equal to its mana cost"; - } - - private VarolzTheScarStripedEffect(final VarolzTheScarStripedEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID cardId : controller.getGraveyard()) { - Card card = game.getCard(cardId); - if (card != null && card.isCreature(game)) { - ScavengeAbility ability = new ScavengeAbility(new ManaCostsImpl<>(card.getManaCost().getText())); - ability.setSourceId(cardId); - ability.setControllerId(card.getOwnerId()); - game.getState().addOtherAbility(card, ability); - } - } - return true; - } - return false; - } - - @Override - public VarolzTheScarStripedEffect copy() { - return new VarolzTheScarStripedEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/y/YoungDeathclaws.java b/Mage.Sets/src/mage/cards/y/YoungDeathclaws.java new file mode 100644 index 00000000000..7f39677d1dd --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YoungDeathclaws.java @@ -0,0 +1,46 @@ +package mage.cards.y; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.GiveScavengeContinuousEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class YoungDeathclaws extends CardImpl { + + public YoungDeathclaws(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}"); + + this.subtype.add(SubType.LIZARD); + this.subtype.add(SubType.MUTANT); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Menace + this.addAbility(new MenaceAbility(false)); + + // Each creature card in your graveyard has scavenge. The scavenge cost is equal to its mana cost. + this.addAbility(new SimpleStaticAbility( + new GiveScavengeContinuousEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_CARD_CREATURE) + )); + } + + private YoungDeathclaws(final YoungDeathclaws card) { + super(card); + } + + @Override + public YoungDeathclaws copy() { + return new YoungDeathclaws(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Fallout.java b/Mage.Sets/src/mage/sets/Fallout.java index 4ae3c5c69a0..f56fa2e50bd 100644 --- a/Mage.Sets/src/mage/sets/Fallout.java +++ b/Mage.Sets/src/mage/sets/Fallout.java @@ -368,5 +368,6 @@ public final class Fallout extends ExpansionSet { cards.add(new SetCardInfo("Windbrisk Heights", 315, Rarity.RARE, mage.cards.w.WindbriskHeights.class)); cards.add(new SetCardInfo("Winding Constrictor", 223, Rarity.UNCOMMON, mage.cards.w.WindingConstrictor.class)); cards.add(new SetCardInfo("Woodland Cemetery", 316, Rarity.RARE, mage.cards.w.WoodlandCemetery.class)); + cards.add(new SetCardInfo("Young Deathclaws", 125, Rarity.UNCOMMON, mage.cards.y.YoungDeathclaws.class)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/VarolzTheScarStripedTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/VarolzTheScarStripedTest.java index fa2f497bf38..9a6a7a11fd8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/VarolzTheScarStripedTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/VarolzTheScarStripedTest.java @@ -9,31 +9,31 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * * @author BetaSteward */ public class VarolzTheScarStripedTest extends CardTestPlayerBase { - /** + /** * Varolz, the Scar-Striped * Legendary Creature — Troll Warrior 2/2, 1BG (3) - * Each creature card in your graveyard has scavenge. The scavenge cost is - * equal to its mana cost. (Exile a creature card from your graveyard and - * pay its mana cost: Put a number of +1/+1 counters equal to that card's + * Each creature card in your graveyard has scavenge. The scavenge cost is + * equal to its mana cost. (Exile a creature card from your graveyard and + * pay its mana cost: Put a number of +1/+1 counters equal to that card's * power on target creature. Scavenge only as a sorcery.) * Sacrifice another creature: Regenerate Varolz, the Scar-Striped. - * */ @Test public void testUseScavenge() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); addCard(Zone.BATTLEFIELD, playerA, "Varolz, the Scar-Striped"); addCard(Zone.BATTLEFIELD, playerA, "Goblin Roughrider"); addCard(Zone.GRAVEYARD, playerA, "Goblin Roughrider"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scavenge", "Goblin Roughrider"); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -41,7 +41,19 @@ public class VarolzTheScarStripedTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Goblin Roughrider", 0); assertExileCount("Goblin Roughrider", 1); assertCounterCount("Goblin Roughrider", CounterType.P1P1, 3); - } + @Test + public void testNoManaCost() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, "Varolz, the Scar-Striped"); + addCard(Zone.BATTLEFIELD, playerA, "Goblin Roughrider"); + addCard(Zone.GRAVEYARD, playerA, "Asmoranomardicadaistinaculdacar"); // No Mana Cost: no Scavenge. + + checkPlayableAbility("No Scavenge", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scavenge", false); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/GiveScavengeContinuousEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GiveScavengeContinuousEffect.java new file mode 100644 index 00000000000..30d14323bee --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/GiveScavengeContinuousEffect.java @@ -0,0 +1,67 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.keyword.ScavengeAbility; +import mage.cards.Card; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * Give Scavenge to all cards matching the filter in your graveyard. + * The scavenge cost is the card's manacost. + * + * @author Susucr + */ +public class GiveScavengeContinuousEffect extends ContinuousEffectImpl { + + private final FilterCard filter; + + public GiveScavengeContinuousEffect(Duration duration, FilterCard filter) { + super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "Each " + filter.getMessage() + " in your graveyard has scavenge. The scavenge cost is equal to its mana cost"; + this.filter = filter; + } + + private GiveScavengeContinuousEffect(final GiveScavengeContinuousEffect effect) { + super(effect); + this.filter = effect.filter; + } + + + @Override + public GiveScavengeContinuousEffect copy() { + return new GiveScavengeContinuousEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + discard(); + return false; + } + for (UUID cardId : controller.getGraveyard()) { + Card card = game.getCard(cardId); + if (!filter.match(card, source.getControllerId(), source, game)) { + continue; + } + if (card.getManaCost().getText().isEmpty()) { // Checks that the card has a mana cost. + continue; + } + ScavengeAbility ability = new ScavengeAbility(new ManaCostsImpl<>(card.getManaCost().getText())); + ability.setSourceId(cardId); + ability.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, ability); + } + return true; + } +}