From b9bfe2ba48aa304aa1b14289cbce381129f80eb2 Mon Sep 17 00:00:00 2001 From: ssk97 Date: Sun, 17 Mar 2024 16:58:02 -0700 Subject: [PATCH] Megamorph abilities - fixed that face down creatures show megamorph instead morph status (#11957) * Megamorph should appear as if it were Morph * review comment --- .../abilities/keywords/MegamorphTest.java | 2 +- .../mage/test/serverside/TokenImagesTest.java | 4 ++-- .../main/java/mage/abilities/AbilityImpl.java | 1 - .../BecomesFaceDownCreatureEffect.java | 4 +--- .../mage/abilities/keyword/MorphAbility.java | 22 +++++++++---------- .../cards/repository/TokenRepository.java | 9 +------- .../mage/constants/SpellAbilityCastMode.java | 4 +--- 7 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MegamorphTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MegamorphTest.java index a3ac35e375d..1178d9f305d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MegamorphTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MegamorphTest.java @@ -21,7 +21,7 @@ public class MegamorphTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Aerie Bowmasters", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aerie Bowmasters using Megamorph"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aerie Bowmasters using Morph"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{5}{G}: Turn"); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java index 454b53463c2..d78351933ca 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java @@ -853,13 +853,13 @@ public class TokenImagesTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Forest", 6 + 3); // prepare face down permanent - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aerie Bowmasters using Megamorph"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aerie Bowmasters using Morph"); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); runCode("on face down", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> { assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1); assertPermanentCount(playerA, "Aerie Bowmasters", 0); Permanent permanent = getPermanent(EmptyNames.FACE_DOWN_CREATURE.toString(), playerA); - assertFaceDownCharacteristics("permanent", permanent, TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH); + assertFaceDownCharacteristics("permanent", permanent, TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MORPH); }); // face up it and find counter diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index b3ed7a5501c..0616397eb6d 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -428,7 +428,6 @@ public abstract class AbilityImpl implements Ability { case MORE_THAN_MEETS_THE_EYE: case BESTOW: case MORPH: - case MEGAMORPH: case DISGUISE: // from Snapcaster Mage: // If you cast a spell from a graveyard using its flashback ability, you can't pay other alternative costs diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesFaceDownCreatureEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesFaceDownCreatureEffect.java index 2fffbd3c953..472bd01489e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesFaceDownCreatureEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesFaceDownCreatureEffect.java @@ -297,10 +297,8 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl { String tokenName; switch (faceDownType) { case MORPHED: - tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MORPH; - break; case MEGAMORPHED: - tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH; + tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MORPH; break; case DISGUISED: tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE; diff --git a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java index 4abe66d4323..85d0cddde70 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java @@ -69,6 +69,7 @@ public class MorphAbility extends SpellAbility { + "as a 2/2 creature for {3}. Turn it face up any time for its megamorph " + "cost and put a +1/+1 counter on it."; protected Costs morphCosts; + protected boolean isMegamorph; public MorphAbility(Card card, Cost morphCost) { this(card, morphCost, false); @@ -79,7 +80,8 @@ public class MorphAbility extends SpellAbility { this.timing = TimingRule.SORCERY; this.morphCosts = new CostsImpl<>(); this.morphCosts.add(morphCost); - this.setSpellAbilityCastMode(useMegamorph ? SpellAbilityCastMode.MEGAMORPH : SpellAbilityCastMode.MORPH); + this.isMegamorph = useMegamorph; + this.setSpellAbilityCastMode(SpellAbilityCastMode.MORPH); this.setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE); // face down effect (hidden by default, visible in face down objects) @@ -93,6 +95,7 @@ public class MorphAbility extends SpellAbility { protected MorphAbility(final MorphAbility ability) { super(ability); this.morphCosts = ability.morphCosts; // can't be changed TODO: looks buggy, need research + this.isMegamorph = ability.isMegamorph; } @Override @@ -109,17 +112,12 @@ public class MorphAbility extends SpellAbility { boolean isMana = morphCosts.get(0) instanceof ManaCost; String text; String reminder; - switch (this.getSpellAbilityCastMode()) { - case MORPH: - text = ABILITY_KEYWORD; - reminder = REMINDER_TEXT; - break; - case MEGAMORPH: - text = ABILITY_KEYWORD_MEGA; - reminder = REMINDER_TEXT_MEGA; - break; - default: - throw new IllegalArgumentException("Un-supported spell ability cast mode for morph: " + this.getSpellAbilityCastMode()); + if (isMegamorph){ + text = ABILITY_KEYWORD_MEGA; + reminder = REMINDER_TEXT_MEGA; + } else { + text = ABILITY_KEYWORD; + reminder = REMINDER_TEXT; } return text + (isMana ? " " : "—") + morphCosts.getText() + (isMana ? ' ' : ". ") + " (" + reminder + ")"; } diff --git a/Mage/src/main/java/mage/cards/repository/TokenRepository.java b/Mage/src/main/java/mage/cards/repository/TokenRepository.java index 5cde842b570..24d3ac76966 100644 --- a/Mage/src/main/java/mage/cards/repository/TokenRepository.java +++ b/Mage/src/main/java/mage/cards/repository/TokenRepository.java @@ -24,7 +24,6 @@ public enum TokenRepository { public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MANUAL = "Face Down"; public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST = "Manifest"; public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MORPH = "Morph"; - public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH = "Megamorph"; public static final String XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE = "Disguise"; public static final String XMAGE_IMAGE_NAME_FACE_DOWN_FORETELL = "Foretell"; public static final String XMAGE_IMAGE_NAME_COPY = "Copy"; @@ -277,18 +276,12 @@ public enum TokenRepository { res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, 3, "https://api.scryfall.com/cards/tfrf/4/en?format=image")); res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, 4, "https://api.scryfall.com/cards/tncc/3/en?format=image")); - // Morph + // Morph and Megamorph // https://scryfall.com/search?q=Morph+unique%3Aprints+otag%3Aassistant-cards&unique=cards&as=grid&order=name res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MORPH, 1, "https://api.scryfall.com/cards/tktk/11/en?format=image")); res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MORPH, 2, "https://api.scryfall.com/cards/ta25/15/en?format=image")); res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MORPH, 3, "https://api.scryfall.com/cards/tc19/27/en?format=image")); - // Megamorph - // warning, mtg don't have megamorph tokens yet so use morph instead (users will see the diff by card name and face up ability text) - res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH, 1, "https://api.scryfall.com/cards/tktk/11/en?format=image")); - res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH, 2, "https://api.scryfall.com/cards/ta25/15/en?format=image")); - res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH, 3, "https://api.scryfall.com/cards/tc19/27/en?format=image")); - // Disguise // support only 1 image: https://scryfall.com/card/tmkm/21/a-mysterious-creature res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE, 1, "https://api.scryfall.com/cards/tmkm/21/en?format=image")); diff --git a/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java b/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java index d36e91e50a9..2c73fb3c439 100644 --- a/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java +++ b/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java @@ -17,8 +17,7 @@ public enum SpellAbilityCastMode { FLASHBACK("Flashback"), BESTOW("Bestow"), PROTOTYPE("Prototype"), - MORPH("Morph", false, true), - MEGAMORPH("Megamorph", false, true), + MORPH("Morph", false, true), // and megamorph DISGUISE("Disguise", false, true), TRANSFORMED("Transformed", true), DISTURB("Disturb", true), @@ -75,7 +74,6 @@ public enum SpellAbilityCastMode { cardCopy = ((PrototypeAbility) spellAbility).prototypeCardSpell(cardCopy); break; case MORPH: - case MEGAMORPH: case DISGUISE: if (cardCopy instanceof Spell) { //Spell doesn't support setName, so make a copy of the card (we're blowing it away anyway)