diff --git a/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java b/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java index bdca251a3ff..1c8ded5216a 100644 --- a/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java +++ b/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java @@ -2,12 +2,10 @@ package mage.cards.a; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; @@ -19,7 +17,10 @@ import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetAnyTarget; +import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -70,24 +71,19 @@ class ApocalypseHydraEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentEntering(source.getSourceId()); - if (permanent == null) { - return false; - } - SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); - if (spellAbility == null - || !spellAbility.getSourceId().equals(source.getSourceId()) - || permanent.getZoneChangeCounter(game) != spellAbility.getSourceObjectZoneChangeCounter()) { - return false; - } - int amount = spellAbility.getManaCostsToPay().getX(); - if (amount > 0) { - if (amount < 5) { - permanent.addCounters(CounterType.P1P1.createInstance(amount), source.getControllerId(), source, game); - } else { - permanent.addCounters(CounterType.P1P1.createInstance(amount * 2), source.getControllerId(), source, game); + if (permanent != null) { + int amount = CardUtil.getSourceCostsTag(game, source, "X", 0); + if (amount > 0) { + List appliedEffects = (ArrayList) this.getValue("appliedEffects"); + if (amount < 5) { + permanent.addCounters(CounterType.P1P1.createInstance(amount), source.getControllerId(), source, game, appliedEffects); + } else { + permanent.addCounters(CounterType.P1P1.createInstance(amount * 2), source.getControllerId(), source, game, appliedEffects); + } } + return true; } - return true; + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/h/Hydradoodle.java b/Mage.Sets/src/mage/cards/h/Hydradoodle.java index 3e14e87bfaa..5be6abe70be 100644 --- a/Mage.Sets/src/mage/cards/h/Hydradoodle.java +++ b/Mage.Sets/src/mage/cards/h/Hydradoodle.java @@ -3,9 +3,7 @@ package mage.cards.h; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.ReachAbility; import mage.abilities.keyword.TrampleAbility; @@ -20,7 +18,10 @@ import mage.filter.predicate.permanent.CounterAnyPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -85,15 +86,11 @@ class HydradoodleEffect extends OneShotEffect { Permanent permanent = game.getPermanentEntering(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); if (permanent != null && controller != null) { - SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); - if (spellAbility != null - && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { - int amount = spellAbility.getManaCostsToPay().getX(); - if (amount > 0) { - int total = controller.rollDice(outcome, source, game, 6, amount, 0).stream().mapToInt(x -> x).sum(); - permanent.addCounters(CounterType.P1P1.createInstance(total), source.getControllerId(), source, game); - } + int amount = CardUtil.getSourceCostsTag(game, source, "X", 0); + if (amount > 0) { + int total = controller.rollDice(outcome, source, game, 6, amount, 0).stream().mapToInt(x -> x).sum(); + List appliedEffects = (ArrayList) this.getValue("appliedEffects"); + permanent.addCounters(CounterType.P1P1.createInstance(total), source.getControllerId(), source, game, appliedEffects); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NeverwinterHydra.java b/Mage.Sets/src/mage/cards/n/NeverwinterHydra.java index 3cbbd56d58b..b7056ab0108 100644 --- a/Mage.Sets/src/mage/cards/n/NeverwinterHydra.java +++ b/Mage.Sets/src/mage/cards/n/NeverwinterHydra.java @@ -2,10 +2,8 @@ package mage.cards.n; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.WardAbility; @@ -18,6 +16,7 @@ import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.util.CardUtil; import java.util.ArrayList; import java.util.List; @@ -75,25 +74,15 @@ class NeverwinterHydraEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentEntering(source.getSourceId()); Player player = game.getPlayer(source.getControllerId()); - if (permanent == null || player == null) { + if (permanent != null && player != null) { + int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); + if (xValue > 0) { + int amount = player.rollDice(outcome, source, game, 6, xValue, 0).stream().mapToInt(x -> x).sum(); + List appliedEffects = (ArrayList) this.getValue("appliedEffects"); + permanent.addCounters(CounterType.P1P1.createInstance(amount), source.getControllerId(), source, game, appliedEffects); + } return true; } - SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); - if (spellAbility == null - || !spellAbility.getSourceId().equals(source.getSourceId()) - || permanent.getZoneChangeCounter(game) != spellAbility.getSourceObjectZoneChangeCounter()) { - return true; - } - if (!spellAbility.getSourceId().equals(source.getSourceId())) { - return true; - } // put into play by normal cast - int xValue = spellAbility.getManaCostsToPay().getX(); - if (xValue < 1) { - return false; - } - int amount = player.rollDice(outcome, source, game, 6, xValue, 0).stream().mapToInt(x -> x).sum(); - List appliedEffects = (ArrayList) this.getValue("appliedEffects"); - permanent.addCounters(CounterType.P1P1.createInstance(amount), source.getControllerId(), source, game, appliedEffects); - return true; + return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java index b332c8f80bd..1dfa057c598 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java @@ -14,7 +14,6 @@ import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentToken; import mage.util.CardUtil; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import org.mage.test.player.TestPlayer; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -193,7 +192,7 @@ public class CopySpellTest extends CardTestPlayerBase { * Reported bug: "Silverfur Partisan and fellow wolves did not trigger off * of copies of Strength of Arms made by Zada, Hedron Grinder. Not sure * about other spells, but I imagine similar results." - + // Perhaps someone knows the correct implementation for this test. // Just target the Silverfur Partisan and hit done // This test works fine in game. The @Ignore would not work for me either. @@ -778,6 +777,101 @@ public class CopySpellTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Expedition Map", 0); } + /** + * Reported bug: https://github.com/magefree/mage/issues/11581 + * Neverwinter Hydra is copied by Magus Lucea Kane's ability, but the copied version does not enter with +1/+1 counters. + */ + @Test + public void test_CopyNeverwinterHydra() { + addCard(Zone.BATTLEFIELD, playerA, "Tropical Island", 4 + 2); + // Psychic Stimulus — {T}: Add {C}{C}. When you next cast a spell with {X} in its mana cost + // or activate an ability with {X} in its activation cost this turn, copy that spell or ability. + // You may choose new targets for the copy. + addCard(Zone.BATTLEFIELD, playerA, "Magus Lucea Kane"); + addCard(Zone.HAND, playerA, "Neverwinter Hydra"); + // Copy target creature spell you control, except it isn’t legendary if the spell is legendary. + addCard(Zone.HAND, playerA, "Double Major"); + + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Neverwinter Hydra"); + setChoice(playerA, "X=2"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Double Major", "Neverwinter Hydra"); + + // Although the value of X should be the same, the actual dice rolls can be different + setDieRollResult(playerA, 3); + setDieRollResult(playerA, 4); + + setDieRollResult(playerA, 6); + setDieRollResult(playerA, 6); + + setDieRollResult(playerA, 1); + setDieRollResult(playerA, 1); + + setStrictChooseMode(true); + // Target for Lucea Kane's Spiritual Leader ability + addTarget(playerA, "Magus Lucea Kane"); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Neverwinter Hydra", 3); + } + + /** + * Reported bug: https://github.com/magefree/mage/issues/11581 + * Neverwinter Hydra is copied by Magus Lucea Kane's ability, but the copied version does not enter with +1/+1 counters. + */ + @Test + public void test_CopyHydradoodle() { + String hydradoodle = "Hydradoodle"; + + addCard(Zone.BATTLEFIELD, playerA, "Tropical Island", 4 + 2); + addCard(Zone.HAND, playerA, hydradoodle); + // Copy target creature spell you control, except it isn’t legendary if the spell is legendary. + addCard(Zone.HAND, playerA, "Double Major"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hydradoodle); + setChoice(playerA, "X=1"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Double Major", hydradoodle); + + setDieRollResult(playerA, 5); + + setDieRollResult(playerA, 1); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, hydradoodle, 2); + } + + /** + * Reported bug: https://github.com/magefree/mage/issues/11581 + * Neverwinter Hydra is copied by Magus Lucea Kane's ability, but the copied version does not enter with +1/+1 counters. + */ + @Test + public void test_CopyApocalypseHydra() { + String apocalypseHydra = "Apocalypse Hydra"; + + addCard(Zone.BATTLEFIELD, playerA, "Taiga", 10); + addCard(Zone.BATTLEFIELD, playerA, "Magus Lucea Kane"); + + addCard(Zone.HAND, playerA, apocalypseHydra); + + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, apocalypseHydra); + setChoice(playerA, "X=5"); + + setStrictChooseMode(true); + // Target for Lucea Kane's Spiritual Leader ability + addTarget(playerA, "Magus Lucea Kane"); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, apocalypseHydra, 2); + } + private void abilitySourceMustBeSame(Card card, String infoPrefix) { Set partIds = CardUtil.getObjectParts(card);