Megamorph abilities - fixed that face down creatures show megamorph instead morph status (#11957)

* Megamorph should appear as if it were Morph

* review comment
This commit is contained in:
ssk97 2024-03-17 16:58:02 -07:00 committed by GitHub
parent 67286aa1a0
commit b9bfe2ba48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 16 additions and 30 deletions

View file

@ -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");

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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<Cost> 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 ? " " : "&mdash;") + morphCosts.getText() + (isMana ? ' ' : ". ") + " <i>(" + reminder + ")</i>";
}

View file

@ -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"));

View file

@ -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)