From a970dc46c7124bf5586867c1bbcc8cbac13f7a5e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 14 Dec 2024 09:04:01 +0400 Subject: [PATCH] Havengul Laboratory // Havengul Mystery - fixed that it doesn't transform back on creature leaves --- .../src/mage/cards/h/HavengulLaboratory.java | 2 +- .../src/mage/cards/h/HavengulMystery.java | 12 +++- Mage.Sets/src/mage/sets/UniversesWithin.java | 1 - .../single/slx/HavengulLaboratoryTest.java | 63 +++++++++++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/slx/HavengulLaboratoryTest.java diff --git a/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java b/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java index 76ccb05d0c5..766da704cd2 100644 --- a/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java +++ b/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java @@ -42,7 +42,7 @@ public final class HavengulLaboratory extends CardImpl { ability.addCost(new TapSourceCost()); this.addAbility(ability); - // At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Hawkins National Laboratory. + // At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Havengul Laboratory. this.addAbility(new TransformAbility()); this.addAbility(new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new TransformSourceEffect(), diff --git a/Mage.Sets/src/mage/cards/h/HavengulMystery.java b/Mage.Sets/src/mage/cards/h/HavengulMystery.java index 505472cd0e5..bb1dbe2aa08 100644 --- a/Mage.Sets/src/mage/cards/h/HavengulMystery.java +++ b/Mage.Sets/src/mage/cards/h/HavengulMystery.java @@ -22,6 +22,7 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; import java.util.HashSet; import java.util.Set; @@ -35,7 +36,6 @@ public final class HavengulMystery extends CardImpl { public HavengulMystery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; // When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield. @@ -63,7 +63,7 @@ public final class HavengulMystery extends CardImpl { } static String makeKey(Ability source, Game game) { - return "HavengulMystery_" + source.getSourceId() + '_' + source.getSourceObjectZoneChangeCounter(); + return "HavengulMystery_" + source.getSourceId() + '_' + CardUtil.getActualSourceObjectZoneChangeCounter(game, source); } } @@ -112,6 +112,7 @@ class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl { HavengulMysteryLeavesAbility() { super(Zone.BATTLEFIELD, new TransformSourceEffect()); + setLeavesTheBattlefieldTrigger(true); } private HavengulMysteryLeavesAbility(final HavengulMysteryLeavesAbility ability) { @@ -131,7 +132,12 @@ class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - Set morSet = (Set) game.getState().getValue(HavengulMystery.makeKey(this, game)); + if (zEvent.getFromZone() != Zone.BATTLEFIELD) { + return false; + } + + String key = HavengulMystery.makeKey(this, game); + Set morSet = (Set) game.getState().getValue(key); return morSet != null && !morSet.isEmpty() && morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game)); diff --git a/Mage.Sets/src/mage/sets/UniversesWithin.java b/Mage.Sets/src/mage/sets/UniversesWithin.java index 895ee348ca3..1e748c59444 100644 --- a/Mage.Sets/src/mage/sets/UniversesWithin.java +++ b/Mage.Sets/src/mage/sets/UniversesWithin.java @@ -16,7 +16,6 @@ public final class UniversesWithin extends ExpansionSet { } private UniversesWithin() { - // The set name is a placeholder and will likely change super("Universes Within", "SLX", ExpansionSet.buildDate(2022, 3, 3), SetType.SUPPLEMENTAL); this.hasBasicLands = false; this.hasBoosters = false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/HavengulLaboratoryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/HavengulLaboratoryTest.java new file mode 100644 index 00000000000..748a0894374 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/HavengulLaboratoryTest.java @@ -0,0 +1,63 @@ +package org.mage.test.cards.single.slx; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class HavengulLaboratoryTest extends CardTestPlayerBase { + + @Test + public void test_LeavesAndTransform() { + addCustomEffect_TargetDestroy(playerA); + + // Havengul Laboratory + // At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Havengul Laboratory. + // Havengul Mystery + // When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield. + // When the creature put onto the battlefield with Havengul Mystery leaves the battlefield, transform Havengul Mystery. + addCard(Zone.BATTLEFIELD, playerA, "Havengul Laboratory"); + addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears"); + // + // Draw a card. Investigate. + addCard(Zone.HAND, playerA, "Deduce", 3); // instant {1}{U} + addCard(Zone.BATTLEFIELD, playerA, "Island", 3 * 2); + // + // Clue Token + // {2}, Sacrifice this artifact: Draw a card. + addCard(Zone.BATTLEFIELD, playerA, "Island", 3 * 2); + + // prepare x3 clues + checkPermanentCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Havengul Laboratory", 1); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deduce"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deduce"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deduce"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + checkPermanentCount("on prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clue Token", 3); + + // use all clues and transform + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Sacrifice"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Sacrifice"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Sacrifice"); + addTarget(playerA, "Grizzly Bears"); // return to battlefield on transform + waitStackResolved(1, PhaseStep.END_TURN); + checkPermanentCount("on transform", 1, PhaseStep.END_TURN, playerA, "Havengul Laboratory", 0); + checkPermanentCount("on transform", 1, PhaseStep.END_TURN, playerA, "Havengul Mystery", 1); + checkPermanentCount("on transform", 1, PhaseStep.END_TURN, playerA, "Grizzly Bears", 1); + + // destroy and transform back to Havengul Laboratory + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Grizzly Bears"); + waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN); + checkPermanentCount("on leaves", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Havengul Laboratory", 1); + checkPermanentCount("on leaves", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Havengul Mystery", 0); + checkPermanentCount("on leaves", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 0); + checkGraveyardCount("on leaves", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 1); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.END_TURN); + execute(); + } +}