diff --git a/Mage.Sets/src/mage/cards/p/Pyrogoyf.java b/Mage.Sets/src/mage/cards/p/Pyrogoyf.java new file mode 100644 index 00000000000..aa9dded8db9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Pyrogoyf.java @@ -0,0 +1,94 @@ + +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class Pyrogoyf extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.LHURGOYF, "{this} or another Lhurgoyf creature"); + + private static final DynamicValue powerValue = CardTypesInGraveyardCount.ALL; + + public Pyrogoyf(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.subtype.add(SubType.LHURGOYF); + + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Pyrogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); + + // Whenever Pyrogoyf or another Lhurgoyf creature enters the battlefield under your control, that creature deals damage equal to its power to any target. + Ability ability = new EntersBattlefieldThisOrAnotherTriggeredAbility( + new PyrogoyfEffect(), filter, false, true + ); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private Pyrogoyf(final Pyrogoyf card) { + super(card); + } + + @Override + public Pyrogoyf copy() { + return new Pyrogoyf(this); + } +} + +class PyrogoyfEffect extends OneShotEffect { + + PyrogoyfEffect() { + super(Outcome.Damage); + staticText = "that creature deals damage equal to its power to any target"; + } + + private PyrogoyfEffect(final PyrogoyfEffect effect) { + super(effect); + } + + @Override + public PyrogoyfEffect copy() { + return new PyrogoyfEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent damagingPermanent = (Permanent) getValue("permanentEnteringBattlefield"); + if (damagingPermanent == null) { + return false; + } + int damageValue = damagingPermanent.getPower().getValue(); + Permanent anotherPermanent = game.getPermanent(source.getFirstTarget()); + Player anotherPlayer = game.getPlayer(source.getFirstTarget()); + if (anotherPermanent != null) { + anotherPermanent.damage(damageValue, damagingPermanent.getId(), source, game); + return true; + } else if (anotherPlayer != null) { + anotherPlayer.damage(damageValue, damagingPermanent.getId(), source, game); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java b/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java index 65e3dea08f8..bd9b838d678 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java @@ -75,6 +75,7 @@ public final class ModernHorizons3Commander extends ExpansionSet { cards.add(new SetCardInfo("Port Town", 364, Rarity.RARE, mage.cards.p.PortTown.class)); cards.add(new SetCardInfo("Prairie Stream", 365, Rarity.RARE, mage.cards.p.PrairieStream.class)); cards.add(new SetCardInfo("Professional Face-Breaker", 216, Rarity.RARE, mage.cards.p.ProfessionalFaceBreaker.class)); + cards.add(new SetCardInfo("Pyrogoyf", 59, Rarity.RARE, mage.cards.p.Pyrogoyf.class)); cards.add(new SetCardInfo("Salvation Colossus", 43, Rarity.RARE, mage.cards.s.SalvationColossus.class)); cards.add(new SetCardInfo("Shivan Reef", 375, Rarity.RARE, mage.cards.s.ShivanReef.class)); cards.add(new SetCardInfo("Siege-Gang Lieutenant", 61, Rarity.RARE, mage.cards.s.SiegeGangLieutenant.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PyrogoyfTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PyrogoyfTest.java new file mode 100644 index 00000000000..bd70674d80f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PyrogoyfTest.java @@ -0,0 +1,117 @@ +package org.mage.test.cards.single.m3c; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class PyrogoyfTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.p.Pyrogoyf} {3}{R} + * Creature — Lhurgoyf + * Pyrogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. + * Whenever Pyrogoyf or another Lhurgoyf creature enters the battlefield under your control, that creature deals damage equal to its power to any target. + * * / 1+* + */ + private static final String pyrogoyf = "Pyrogoyf"; + + @Test + public void test_Trigger_Simple() { + setStrictChooseMode(true); + + addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment + addCard(Zone.GRAVEYARD, playerA, "Swamp"); // Land + + addCard(Zone.HAND, playerA, pyrogoyf, 1); + addCard(Zone.HAND, playerA, "Tarmogoyf", 1); + addCard(Zone.HAND, playerA, "Memnite", 1); + addCard(Zone.BATTLEFIELD, playerA, "Taiga", 6); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyrogoyf, true); + addTarget(playerA, playerB); // trigger target, will deal 3 + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tarmogoyf", true); + addTarget(playerA, pyrogoyf); // trigger target, will deal 3 + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Memnite"); + // Not a lhurgoyf, no trigger + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertDamageReceived(playerA, pyrogoyf, 3); + assertLife(playerB, 20 - 3); + } + + @Test + public void test_Trigger_FetchInResponse() { + setStrictChooseMode(true); + + addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment + + addCard(Zone.HAND, playerA, pyrogoyf, 1); + addCard(Zone.BATTLEFIELD, playerA, "Taiga", 4); + addCard(Zone.BATTLEFIELD, playerA, "Evolving Wilds"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyrogoyf); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA, true); + addTarget(playerA, playerB); // trigger target, will deal 3 + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice"); + addTarget(playerA, "Mountain"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, "Evolving Wilds", 1); + assertLife(playerB, 20 - 3); + } + + @Test + public void test_Trigger_Doomblade() { + setStrictChooseMode(true); + + addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment + addCard(Zone.GRAVEYARD, playerA, "Swamp"); // Land + + addCard(Zone.HAND, playerA, pyrogoyf, 1); + addCard(Zone.HAND, playerA, "Doom Blade", 1); + addCard(Zone.BATTLEFIELD, playerA, "Badlands", 6); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyrogoyf); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA, true); + addTarget(playerA, playerB); // trigger target, will deal 3 + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", pyrogoyf); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, pyrogoyf, 1); + assertLife(playerB, 20 - 3); // LKI has 3 power for Pyrogoyf. + } + + @Test + public void test_Trigger_Cloudshift() { + setStrictChooseMode(true); + + addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment + addCard(Zone.GRAVEYARD, playerA, "Swamp"); // Land + + addCard(Zone.HAND, playerA, pyrogoyf, 1); + addCard(Zone.HAND, playerA, "Cloudshift"); // Instant {W} Exile target creature you control, then return that card to the battlefield under your control. + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 5); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyrogoyf); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA, true); + addTarget(playerA, playerB); // trigger target, will deal 3 + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cloudshift", pyrogoyf); + addTarget(playerA, playerB); // trigger target, will deal 4 + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, pyrogoyf, 1); + assertLife(playerB, 20 - 3 - 4); // LKI has 3 power for first trigger. + } +}