From 57a94d7c64c8acab418707adbe8b06396bd1d7d5 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sat, 6 Dec 2025 09:59:34 -0600 Subject: [PATCH 1/7] cleanup some missed back face classes --- .../mage/cards/d/DennickPiousApparition.java | 56 ------------------- .../src/mage/cards/f/ForsakenThresher.java | 37 ------------ .../src/mage/cards/h/HomicidalBrute.java | 55 ------------------ .../src/mage/cards/v/VoraciousReader.java | 49 ---------------- Mage.Sets/src/mage/sets/EldritchMoon.java | 1 - .../src/mage/sets/InnistradCrimsonVow.java | 1 - .../src/mage/sets/InnistradDoubleFeature.java | 1 - .../sets/ShadowsOverInnistradRemastered.java | 1 - 8 files changed, 201 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/d/DennickPiousApparition.java delete mode 100644 Mage.Sets/src/mage/cards/f/ForsakenThresher.java delete mode 100644 Mage.Sets/src/mage/cards/h/HomicidalBrute.java delete mode 100644 Mage.Sets/src/mage/cards/v/VoraciousReader.java diff --git a/Mage.Sets/src/mage/cards/d/DennickPiousApparition.java b/Mage.Sets/src/mage/cards/d/DennickPiousApparition.java deleted file mode 100644 index ce39618f468..00000000000 --- a/Mage.Sets/src/mage/cards/d/DennickPiousApparition.java +++ /dev/null @@ -1,56 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; -import mage.abilities.effects.keyword.InvestigateEffect; -import mage.abilities.keyword.DisturbAbility; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author LePwnerer - */ -public final class DennickPiousApparition extends CardImpl { - - public DennickPiousApparition(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever one or more creature cards are put into graveyards from anywhere, investigate. This ability triggers only once each turn. - this.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility( - new InvestigateEffect(1), false, - StaticFilters.FILTER_CARD_CREATURE, TargetController.ANY - ).setTriggersLimitEachTurn(1).setTriggerPhrase("Whenever one or more creature cards are put into graveyards from anywhere, ")); - - // If Dennick, Pious Apparition would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private DennickPiousApparition(final DennickPiousApparition card) { - super(card); - } - - @Override - public DennickPiousApparition copy() { - return new DennickPiousApparition(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/ForsakenThresher.java b/Mage.Sets/src/mage/cards/f/ForsakenThresher.java deleted file mode 100644 index ff71b95d151..00000000000 --- a/Mage.Sets/src/mage/cards/f/ForsakenThresher.java +++ /dev/null @@ -1,37 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.abilities.effects.mana.AddManaOfAnyColorEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -public class ForsakenThresher extends CardImpl { - - public ForsakenThresher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - - // Back half of Foreboding Statue - this.nightCard = true; - - // At the beginning of your precombat main phase, add one mana of any color. - this.addAbility(new BeginningOfFirstMainTriggeredAbility(new AddManaOfAnyColorEffect())); - } - - private ForsakenThresher(final ForsakenThresher card) { - super(card); - } - - @Override - public ForsakenThresher copy() { - return new ForsakenThresher(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HomicidalBrute.java b/Mage.Sets/src/mage/cards/h/HomicidalBrute.java deleted file mode 100644 index e9a45b2582c..00000000000 --- a/Mage.Sets/src/mage/cards/h/HomicidalBrute.java +++ /dev/null @@ -1,55 +0,0 @@ - -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.TriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.InvertCondition; -import mage.abilities.condition.common.AttackedThisTurnSourceCondition; -import mage.abilities.effects.common.TapSourceEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class HomicidalBrute extends CardImpl { - - private static final Condition condition = new InvertCondition( - AttackedThisTurnSourceCondition.instance, "{this} didn't attack this turn" - ); - - public HomicidalBrute(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.MUTANT); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.color.setRed(true); - this.power = new MageInt(5); - this.toughness = new MageInt(1); - - // At the beginning of your end step, if Homicidal Brute didn't attack this turn, tap Homicidal Brute, then transform it. - TriggeredAbility ability = new BeginningOfEndStepTriggeredAbility(new TapSourceEffect()); - ability.addEffect(new TransformSourceEffect().setText(", then transform it")); - this.addAbility(ability.withInterveningIf(condition)); - } - - private HomicidalBrute(final HomicidalBrute card) { - super(card); - } - - @Override - public HomicidalBrute copy() { - return new HomicidalBrute(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/v/VoraciousReader.java b/Mage.Sets/src/mage/cards/v/VoraciousReader.java deleted file mode 100644 index 9956bc0cc68..00000000000 --- a/Mage.Sets/src/mage/cards/v/VoraciousReader.java +++ /dev/null @@ -1,49 +0,0 @@ - -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; -import mage.abilities.keyword.ProwessAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.common.FilterInstantOrSorceryCard; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class VoraciousReader extends CardImpl { - - private static final FilterCard filter = new FilterInstantOrSorceryCard("Instant and sorcery spells"); - - public VoraciousReader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.HOMUNCULUS); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Prowess - this.addAbility(new ProwessAbility()); - - // Instant and sorcery spells you cast cost {1} less to cast. - this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1))); - } - - private VoraciousReader(final VoraciousReader card) { - super(card); - } - - @Override - public VoraciousReader copy() { - return new VoraciousReader(this); - } -} diff --git a/Mage.Sets/src/mage/sets/EldritchMoon.java b/Mage.Sets/src/mage/sets/EldritchMoon.java index 76aa983a42f..94888733668 100644 --- a/Mage.Sets/src/mage/sets/EldritchMoon.java +++ b/Mage.Sets/src/mage/sets/EldritchMoon.java @@ -239,7 +239,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Vexing Scuttler", 11, Rarity.UNCOMMON, mage.cards.v.VexingScuttler.class)); cards.add(new SetCardInfo("Vildin-Pack Outcast", 148, Rarity.COMMON, mage.cards.v.VildinPackOutcast.class)); cards.add(new SetCardInfo("Voldaren Pariah", 111, Rarity.RARE, mage.cards.v.VoldarenPariah.class)); - cards.add(new SetCardInfo("Voracious Reader", 54, Rarity.UNCOMMON, mage.cards.v.VoraciousReader.class)); cards.add(new SetCardInfo("Wailing Ghoul", 112, Rarity.COMMON, mage.cards.w.WailingGhoul.class)); cards.add(new SetCardInfo("Waxing Moon", 177, Rarity.COMMON, mage.cards.w.WaxingMoon.class)); cards.add(new SetCardInfo("Weaver of Lightning", 149, Rarity.UNCOMMON, mage.cards.w.WeaverOfLightning.class)); diff --git a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java index 4cf85b4fdca..dc533ed678d 100644 --- a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java +++ b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java @@ -187,7 +187,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Forest", 402, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 412, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Forsaken Thresher", 256, Rarity.UNCOMMON, mage.cards.f.ForsakenThresher.class)); cards.add(new SetCardInfo("Frenzied Devils", 159, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class)); cards.add(new SetCardInfo("Geistlight Snare", 405, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Geistlight Snare", 60, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java b/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java index 3a0aa70042d..0f747ef794c 100644 --- a/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java +++ b/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java @@ -227,7 +227,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Florian, Voldaren Scion", 223, Rarity.RARE, mage.cards.f.FlorianVoldarenScion.class)); cards.add(new SetCardInfo("Flourishing Hunter", 466, Rarity.COMMON, mage.cards.f.FlourishingHunter.class)); cards.add(new SetCardInfo("Foreboding Statue", 523, Rarity.UNCOMMON, mage.cards.f.ForebodingStatue.class)); - cards.add(new SetCardInfo("Forsaken Thresher", 523, Rarity.UNCOMMON, mage.cards.f.ForsakenThresher.class)); cards.add(new SetCardInfo("Foul Play", 101, Rarity.UNCOMMON, mage.cards.f.FoulPlay.class)); cards.add(new SetCardInfo("Frenzied Devils", 426, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class)); cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java index beae6f1be95..51854dc17a9 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java +++ b/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java @@ -311,7 +311,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Veteran Cathar", 225, Rarity.UNCOMMON, mage.cards.v.VeteranCathar.class)); cards.add(new SetCardInfo("Village Messenger", 184, Rarity.UNCOMMON, mage.cards.v.VillageMessenger.class)); cards.add(new SetCardInfo("Voldaren Pariah", 138, Rarity.RARE, mage.cards.v.VoldarenPariah.class)); - cards.add(new SetCardInfo("Voracious Reader", 58, Rarity.UNCOMMON, mage.cards.v.VoraciousReader.class)); cards.add(new SetCardInfo("Weirded Vampire", 139, Rarity.COMMON, mage.cards.w.WeirdedVampire.class)); cards.add(new SetCardInfo("Weirding Wood", 226, Rarity.COMMON, mage.cards.w.WeirdingWood.class)); cards.add(new SetCardInfo("Westvale Abbey", 275, Rarity.RARE, mage.cards.w.WestvaleAbbey.class)); From 2bcbb3095495a328ca3865ae74329d9b37e2a9ff Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sat, 6 Dec 2025 14:54:07 -0600 Subject: [PATCH 2/7] remove secondSideCardClazz --- Mage/src/main/java/mage/cards/CardImpl.java | 32 ++----------------- Mage/src/main/java/mage/game/GameImpl.java | 6 ---- .../mage/game/permanent/PermanentCard.java | 19 ++--------- 3 files changed, 4 insertions(+), 53 deletions(-) diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index 966363ae338..fe7e0b658b0 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -41,7 +41,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { protected UUID ownerId; protected Rarity rarity; - protected Class secondSideCardClazz; protected Class meldsWithClazz; protected Class meldsToClazz; protected MeldCard meldsToCard; @@ -121,19 +120,8 @@ public abstract class CardImpl extends MageObjectImpl implements Card { ownerId = card.ownerId; rarity = card.rarity; - // TODO: wtf, do not copy card sides cause it must be re-created each time (see details in getSecondCardFace) - // must be reworked to normal copy and workable transform without such magic - nightCard = card.nightCard; - secondSideCardClazz = card.secondSideCardClazz; - secondSideCard = null; // will be set on first getSecondCardFace call if card has one - // TODO: temporary until cards tdfc cards are converted - // can do normal copy after - if (card.secondSideCard instanceof DoubleFacedCardHalf) { - secondSideCard = card.secondSideCard.copy(); - } - if (card.secondSideCard instanceof MockableCard) { - // workaround to support gui's mock cards + if (card.secondSideCard != null) { secondSideCard = card.secondSideCard.copy(); } @@ -667,27 +655,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card { // If a spell or ability instructs a player to transform a permanent that // isn’t represented by a transforming token or a transforming double-faced // card, nothing happens. - return this.secondSideCardClazz != null || this.nightCard || this.secondSideCard != null; + return this.secondSideCard != null; } @Override public final Card getSecondCardFace() { - // init card side on first call - if (secondSideCardClazz == null && secondSideCard == null) { - return null; - } - - if (secondSideCard == null) { - secondSideCard = initSecondSideCard(secondSideCardClazz); - if (secondSideCard != null && secondSideCard.getSpellAbility() != null) { - // TODO: wtf, why it set cast mode here?! Transform tests fails without it - // must be reworked without that magic, also see CardImpl'constructor for copy code - secondSideCard.getSpellAbility().setSourceId(this.getId()); - secondSideCard.getSpellAbility().setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE); - secondSideCard.getSpellAbility().setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED); - } - } - return secondSideCard; } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index ff45386549a..71b2a324e93 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -56,7 +56,6 @@ import mage.game.mulligan.Mulligan; import mage.game.permanent.Battlefield; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentCard; -import mage.game.permanent.PermanentToken; import mage.game.stack.Spell; import mage.game.stack.SpellStack; import mage.game.stack.StackAbility; @@ -2117,11 +2116,6 @@ public abstract class GameImpl implements Game { BecomesFaceDownCreatureEffect.makeFaceDownObject(this, null, newBluePrint, faceDownType, null); } newBluePrint.assignNewId(); - // TODO: should be able to remove after tdfc rework - if (copyFromPermanent.isTransformed() && (copyFromPermanent instanceof PermanentToken || ((copyFromPermanent instanceof PermanentCard) && - !(((PermanentCard) copyFromPermanent).getCard() instanceof DoubleFacedCardHalf)))) { - TransformAbility.transformPermanent(newBluePrint, this, source); - } if (copyFromPermanent.isPrototyped()) { Abilities abilities = copyFromPermanent.getAbilities(); for (Ability ability : abilities) { diff --git a/Mage/src/main/java/mage/game/permanent/PermanentCard.java b/Mage/src/main/java/mage/game/permanent/PermanentCard.java index 9139caea669..476b9587882 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentCard.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentCard.java @@ -7,8 +7,6 @@ import mage.abilities.Ability; import mage.abilities.common.RoomAbility; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; -import mage.abilities.keyword.NightboundAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.*; import mage.constants.SpellAbilityType; import mage.game.Game; @@ -103,16 +101,6 @@ public class PermanentCard extends PermanentImpl { if (card instanceof LevelerCard) { maxLevelCounters = ((LevelerCard) card).getMaxLevelCounters(); } - - // if transformed on ETB - // TODO: remove after tdfc rework - if (card.isTransformable() && !(card instanceof DoubleFacedCardHalf)) { - if (game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()) != null - || NightboundAbility.checkCard(this, game)) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), null); - TransformAbility.transformPermanent(this, game, null); - } - } } protected PermanentCard(final PermanentCard permanent) { @@ -163,7 +151,7 @@ public class PermanentCard extends PermanentImpl { } else if (card.getId() != this.getId()) { // if different id, abilities need to be added to game state for continuous/triggers for (Ability ability : card.getAbilities()) { - this.addAbility(ability, card.getId(), game, true); + this.addAbility(ability, card.getId(), game, true); } } else { // copy only own abilities; all dynamic added abilities must be added in the parent call @@ -202,9 +190,6 @@ public class PermanentCard extends PermanentImpl { this.setImageFileName(card.getImageFileName()); this.setImageNumber(card.getImageNumber()); - if (card.getSecondCardFace() != null && !(card instanceof DoubleFacedCardHalf)) { - this.secondSideCardClazz = card.getSecondCardFace().getClass(); - } if (card.getMeldsToCard() != null) { this.meldsToClazz = card.getMeldsToCard().getClass(); } @@ -249,7 +234,7 @@ public class PermanentCard extends PermanentImpl { @Override public boolean turnFaceUp(Ability source, Game game, UUID playerId) { - if (!this.getBasicMageObject().isPermanent()){ + if (!this.getBasicMageObject().isPermanent()) { // 701.34g. If a manifested permanent that's represented by an instant or sorcery card would turn face up, // its controller reveals it and leaves it face down. Abilities that trigger whenever a permanent // is turned face up won't trigger. From 2a75aa3acc6bb34b7cf3a1dd341fbf1fde9e15ee Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sat, 6 Dec 2025 14:57:54 -0600 Subject: [PATCH 3/7] remove TransformAbility --- .../client/dialog/TestCardRenderDialog.java | 23 +-- Mage.Sets/src/mage/cards/a/AccursedWitch.java | 4 +- .../mage/cards/a/AclazotzDeepestBetrayal.java | 3 +- Mage.Sets/src/mage/cards/b/BiolumeEgg.java | 3 +- .../src/mage/cards/c/ContainmentPriest.java | 4 +- .../src/mage/cards/e/EdgarCharmedGroom.java | 3 +- Mage.Sets/src/mage/cards/e/EsperOrigins.java | 3 +- .../mage/cards/g/GarlandKnightOfCornelia.java | 3 +- .../src/mage/cards/g/GoldenGuardian.java | 3 +- .../mage/cards/g/GrimlockDinobotLeader.java | 13 +- Mage.Sets/src/mage/cards/h/HarvestHand.java | 3 +- .../src/mage/cards/j/JourneyToEternity.java | 4 +- Mage.Sets/src/mage/cards/l/LoyalCathar.java | 3 +- Mage.Sets/src/mage/cards/m/Mistcaller.java | 4 +- .../mage/cards/o/OjerAxonilDeepestMight.java | 3 +- .../mage/cards/o/OjerKaslemDeepestGrowth.java | 3 +- .../cards/o/OjerPakpatiqDeepestEpoch.java | 3 +- .../cards/o/OjerTaqDeepestFoundation.java | 3 +- .../src/mage/cards/o/OptimusPrimeHero.java | 13 +- Mage.Sets/src/mage/cards/r/RadiantGrace.java | 3 +- Mage.Sets/src/mage/cards/s/SkinInvasion.java | 3 +- Mage.Sets/src/mage/cards/s/StartledAwake.java | 3 +- .../src/mage/cards/v/VengefulStrangler.java | 3 +- .../abilities/keywords/TransformTest.java | 30 ++- .../java/mage/verify/VerifyCardDataTest.java | 21 +-- .../mage/abilities/common/SiegeAbility.java | 5 +- .../common/SpellTransformedAbility.java | 52 +---- .../effects/AuraReplacementEffect.java | 10 +- .../mage/abilities/keyword/CraftAbility.java | 4 +- .../abilities/keyword/DayboundAbility.java | 1 - .../abilities/keyword/TransformAbility.java | 177 ------------------ .../cards/TransformingDoubleFacedCard.java | 3 + .../main/java/mage/constants/PutCards.java | 10 +- .../permanent/TransformablePredicate.java | 19 ++ .../src/main/java/mage/game/ZonesHandler.java | 18 +- .../game/permanent/token/IncubatorToken.java | 2 - Mage/src/main/java/mage/game/stack/Spell.java | 6 - .../main/java/mage/players/PlayerImpl.java | 12 +- 38 files changed, 118 insertions(+), 365 deletions(-) delete mode 100644 Mage/src/main/java/mage/abilities/keyword/TransformAbility.java create mode 100644 Mage/src/main/java/mage/filter/predicate/permanent/TransformablePredicate.java diff --git a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java index cdc5d658831..a1a1af64010 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java @@ -4,7 +4,6 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect; import mage.abilities.icon.*; -import mage.abilities.keyword.TransformAbility; import mage.cards.*; import mage.cards.decks.Deck; import mage.cards.repository.CardInfo; @@ -13,34 +12,26 @@ import mage.cards.repository.ExpansionInfo; import mage.cards.repository.ExpansionRepository; import mage.client.MageFrame; import mage.client.cards.BigCard; -import mage.client.game.PlayAreaPanel; import mage.client.game.PlayerPanelExt; import mage.client.themes.ThemeType; import mage.client.util.*; import mage.client.util.Event; -import mage.client.util.GUISizeHelper; -import mage.client.util.Listener; -import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; import mage.constants.Zone; import mage.counters.Counter; import mage.counters.CounterType; import mage.designations.CitysBlessing; -import mage.designations.Monarch; -import mage.game.*; +import mage.game.FakeGame; +import mage.game.FakeMatch; +import mage.game.Game; import mage.game.command.Dungeon; import mage.game.command.Emblem; import mage.game.command.Plane; -import mage.game.match.*; -import mage.game.mulligan.Mulligan; -import mage.game.mulligan.MulliganType; +import mage.game.match.Match; import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentMeld; import mage.game.permanent.PermanentToken; -import mage.game.permanent.token.IncubatorToken; -import mage.game.permanent.token.Phyrexian00Token; import mage.game.permanent.token.Token; -import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.players.StubPlayer; import mage.util.CardUtil; @@ -52,8 +43,8 @@ import org.mage.card.arcane.CardPanel; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; -import java.util.List; import java.util.*; +import java.util.List; /** * App GUI: debug only, testing card renders and manipulations @@ -150,8 +141,8 @@ public class TestCardRenderDialog extends MageDialog { } if (transform) { - // need direct transform call to keep other side info (original) - TransformAbility.transformPermanent(permanent, game, null); + permanent.setTransformed(true); + permanent.reset(game); } if (damage > 0) permanent.damage(damage, controllerId, null, game); diff --git a/Mage.Sets/src/mage/cards/a/AccursedWitch.java b/Mage.Sets/src/mage/cards/a/AccursedWitch.java index b2f2f329017..70804f3b35b 100644 --- a/Mage.Sets/src/mage/cards/a/AccursedWitch.java +++ b/Mage.Sets/src/mage/cards/a/AccursedWitch.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect; import mage.abilities.keyword.EnchantAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; import mage.cards.DoubleFacedCardHalf; @@ -112,7 +111,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); game.getState().setValue("attachTo:" + card.getOtherSide().getId(), attachTo.getId()); if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { attachTo.addAttachment(card.getOtherSide().getId(), source, game); @@ -120,6 +119,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect { return true; } } + class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl { InfectiousCurseCostReductionEffect() { diff --git a/Mage.Sets/src/mage/cards/a/AclazotzDeepestBetrayal.java b/Mage.Sets/src/mage/cards/a/AclazotzDeepestBetrayal.java index 3ffb59c98fc..69bd73ca58e 100644 --- a/Mage.Sets/src/mage/cards/a/AclazotzDeepestBetrayal.java +++ b/Mage.Sets/src/mage/cards/a/AclazotzDeepestBetrayal.java @@ -16,7 +16,6 @@ import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.BlackManaAbility; import mage.cards.*; import mage.constants.*; @@ -191,7 +190,7 @@ class AclazotzDeepestBetrayalTransformEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/cards/b/BiolumeEgg.java b/Mage.Sets/src/mage/cards/b/BiolumeEgg.java index 83ed25e5abc..13d7ff4c92a 100644 --- a/Mage.Sets/src/mage/cards/b/BiolumeEgg.java +++ b/Mage.Sets/src/mage/cards/b/BiolumeEgg.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -94,7 +93,7 @@ class BiolumeEggEffect extends OneShotEffect { } Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); } return true; diff --git a/Mage.Sets/src/mage/cards/c/ContainmentPriest.java b/Mage.Sets/src/mage/cards/c/ContainmentPriest.java index d7fd6171afb..8227abcb9fd 100644 --- a/Mage.Sets/src/mage/cards/c/ContainmentPriest.java +++ b/Mage.Sets/src/mage/cards/c/ContainmentPriest.java @@ -5,10 +5,10 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.FlashAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; @@ -86,7 +86,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { - Object entersTransformed = game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId()); + Object entersTransformed = game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId()); Card card = game.getCard(event.getTargetId()); if (card != null && entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) { card = card.getSecondCardFace(); diff --git a/Mage.Sets/src/mage/cards/e/EdgarCharmedGroom.java b/Mage.Sets/src/mage/cards/e/EdgarCharmedGroom.java index 704a9315a79..af64f1a3039 100644 --- a/Mage.Sets/src/mage/cards/e/EdgarCharmedGroom.java +++ b/Mage.Sets/src/mage/cards/e/EdgarCharmedGroom.java @@ -12,7 +12,6 @@ import mage.abilities.effects.common.RemoveAllCountersSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -97,7 +96,7 @@ class EdgarCharmedGroomEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/cards/e/EsperOrigins.java b/Mage.Sets/src/mage/cards/e/EsperOrigins.java index e8c10f40d11..744118bf85e 100644 --- a/Mage.Sets/src/mage/cards/e/EsperOrigins.java +++ b/Mage.Sets/src/mage/cards/e/EsperOrigins.java @@ -13,7 +13,6 @@ import mage.abilities.effects.keyword.SurveilEffect; import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.keyword.FlashbackAbility; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; @@ -115,7 +114,7 @@ class EsperOriginsEffect extends OneShotEffect { Card card = spell.getMainCard(); player.moveCards(card, Zone.EXILED, source, game); game.setEnterWithCounters(card.getId(), new Counters(CounterType.FINALITY.createInstance())); - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); player.moveCards( card, Zone.BATTLEFIELD, source, game, false, false, true, null diff --git a/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java b/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java index b6d5a06f9a1..5f627d983d8 100644 --- a/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java +++ b/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java @@ -9,7 +9,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.PutOnLibrarySourceEffect; import mage.abilities.effects.keyword.SurveilEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -95,7 +94,7 @@ class GarlandKnightOfCorneliaEffect extends OneShotEffect { if (player == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); return player.moveCards(card, Zone.BATTLEFIELD, source, game); } } diff --git a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java index c04f609ad9e..3d4249a0c9a 100644 --- a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java +++ b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.FightTargetSourceEffect; import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.SimpleManaAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -120,7 +119,7 @@ class GoldenGuardianReturnTransformedEffect extends OneShotEffect { if (controller == null || game.getState().getZone(source.getSourceId()) != Zone.GRAVEYARD) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); Card card = game.getCard(source.getSourceId()); return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game); } diff --git a/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java b/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java index 4e5d938eae5..37f87804f3f 100644 --- a/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java +++ b/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java @@ -7,7 +7,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; @@ -16,8 +15,7 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.filter.predicate.permanent.TransformedPredicate; +import mage.filter.predicate.permanent.TransformablePredicate; import java.util.UUID; @@ -27,18 +25,13 @@ import java.util.UUID; public final class GrimlockDinobotLeader extends TransformingDoubleFacedCard { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs and Vehicles you control"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Transformers creatures"); static { filter.add(Predicates.or( SubType.DINOSAUR.getPredicate(), SubType.VEHICLE.getPredicate()) ); - } - - private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Transformers creatures"); - static { - filter2.add(Predicates.not(SubType.DINOSAUR.getPredicate())); - filter2.add(Predicates.not(SubType.VEHICLE.getPredicate())); - filter2.add(Predicates.or(new AbilityPredicate(TransformAbility.class), TransformedPredicate.instance)); + filter2.add(TransformablePredicate.instance); } public GrimlockDinobotLeader(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/h/HarvestHand.java b/Mage.Sets/src/mage/cards/h/HarvestHand.java index ad517955f58..57ab999fdb5 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestHand.java +++ b/Mage.Sets/src/mage/cards/h/HarvestHand.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.MenaceAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -89,7 +88,7 @@ class HarvestHandReturnTransformedEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java index 132be3c70e8..7b7df49aaf0 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java @@ -1,4 +1,3 @@ - package mage.cards.j; import mage.abilities.Ability; @@ -11,7 +10,6 @@ import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlAttachedEffect; import mage.abilities.keyword.EnchantAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -95,7 +93,7 @@ class JourneyToEternityReturnTransformedSourceEffect extends OneShotEffect { if (zone == Zone.BATTLEFIELD || !zone.isPublicZone()) { return true; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null); } return true; diff --git a/Mage.Sets/src/mage/cards/l/LoyalCathar.java b/Mage.Sets/src/mage/cards/l/LoyalCathar.java index 41bb3659fc3..345cb758831 100644 --- a/Mage.Sets/src/mage/cards/l/LoyalCathar.java +++ b/Mage.Sets/src/mage/cards/l/LoyalCathar.java @@ -6,7 +6,6 @@ import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -111,7 +110,7 @@ class ReturnLoyalCatharEffect extends OneShotEffect { } Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game); } return true; diff --git a/Mage.Sets/src/mage/cards/m/Mistcaller.java b/Mage.Sets/src/mage/cards/m/Mistcaller.java index 337820d3721..4eb0a32148c 100644 --- a/Mage.Sets/src/mage/cards/m/Mistcaller.java +++ b/Mage.Sets/src/mage/cards/m/Mistcaller.java @@ -5,10 +5,10 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; @@ -88,7 +88,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { Card card = game.getCard(event.getTargetId()); if (card != null) { - Object entersTransformed = game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId()); + Object entersTransformed = game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId()); if (entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) { card = card.getSecondCardFace(); } diff --git a/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java index 8c7bbe6e8bd..7f645f14db6 100644 --- a/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java +++ b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java @@ -14,7 +14,6 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.RedManaAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -105,7 +104,7 @@ class OjerAxonilDeepestMightTransformEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java index 6538489b745..a98acd9d79e 100644 --- a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java +++ b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java @@ -12,7 +12,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.common.PermanentsYouControlHint; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.GreenManaAbility; import mage.cards.*; import mage.cards.g.GishathSunsAvatar; @@ -96,7 +95,7 @@ class OjerKaslemDeepestGrowthTransformEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java index 73a4be11c49..ae30d8f89c1 100644 --- a/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java +++ b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java @@ -14,7 +14,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReboundAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.BlueManaAbility; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -167,7 +166,7 @@ class OjerPakpatiqDeepestEpochTrigger extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); game.setEnterWithCounters(card.getId(), new Counters().addCounter(CounterType.TIME.createInstance(3))); controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); return true; diff --git a/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java b/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java index 1241a2425e7..d35724d0538 100644 --- a/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java +++ b/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java @@ -10,7 +10,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; import mage.abilities.mana.WhiteManaAbility; import mage.cards.Card; @@ -94,7 +93,7 @@ class OjerTaqDeepestFoundationTransformEffect extends OneShotEffect { if (controller == null || card == null) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/cards/o/OptimusPrimeHero.java b/Mage.Sets/src/mage/cards/o/OptimusPrimeHero.java index 11a4d5db80c..abc7f569e46 100644 --- a/Mage.Sets/src/mage/cards/o/OptimusPrimeHero.java +++ b/Mage.Sets/src/mage/cards/o/OptimusPrimeHero.java @@ -4,16 +4,15 @@ import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.LivingMetalAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.keyword.BolsterEffect; +import mage.abilities.keyword.LivingMetalAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -106,7 +105,7 @@ class OptimusPrimeHeroEffect extends OneShotEffect { if (backSide == null) { return true; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true); controller.moveCards(backSide, Zone.BATTLEFIELD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/r/RadiantGrace.java b/Mage.Sets/src/mage/cards/r/RadiantGrace.java index ae2c6055941..df55c1baf93 100644 --- a/Mage.Sets/src/mage/cards/r/RadiantGrace.java +++ b/Mage.Sets/src/mage/cards/r/RadiantGrace.java @@ -9,7 +9,6 @@ import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; import mage.cards.DoubleFacedCardHalf; @@ -116,7 +115,7 @@ class RadiantGraceEffect extends OneShotEffect { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); game.getState().setValue("attachTo:" + card.getOtherSide().getId(), player.getId()); if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { player.addAttachment(card.getId(), source, game); diff --git a/Mage.Sets/src/mage/cards/s/SkinInvasion.java b/Mage.Sets/src/mage/cards/s/SkinInvasion.java index dda91e54c88..e8ab1cf590e 100644 --- a/Mage.Sets/src/mage/cards/s/SkinInvasion.java +++ b/Mage.Sets/src/mage/cards/s/SkinInvasion.java @@ -7,7 +7,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect; import mage.abilities.keyword.EnchantAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -82,7 +81,7 @@ class SkinInvasionEffect extends OneShotEffect { Card card = game.getCard(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); if (card != null && controller != null) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); controller.moveCards(card, Zone.BATTLEFIELD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/s/StartledAwake.java b/Mage.Sets/src/mage/cards/s/StartledAwake.java index d46bc468036..e39f241493f 100644 --- a/Mage.Sets/src/mage/cards/s/StartledAwake.java +++ b/Mage.Sets/src/mage/cards/s/StartledAwake.java @@ -8,7 +8,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MillCardsTargetEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.keyword.SkulkAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -96,7 +95,7 @@ class StartledAwakeReturnTransformedEffect extends OneShotEffect { if (backSide == null) { return true; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true); controller.moveCards(backSide, Zone.BATTLEFIELD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/v/VengefulStrangler.java b/Mage.Sets/src/mage/cards/v/VengefulStrangler.java index 5d0fd76b8f2..62bfa42cb25 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulStrangler.java +++ b/Mage.Sets/src/mage/cards/v/VengefulStrangler.java @@ -6,7 +6,6 @@ import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; import mage.cards.DoubleFacedCardHalf; @@ -107,7 +106,7 @@ class VengefulStranglerEffect extends OneShotEffect { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); game.getState().setValue("attachTo:" + card.getOtherSide().getId(), permanent); if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { permanent.addAttachment(card.getOtherSide().getId(), source, game); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java index c8ccc2e413d..b8e3627d5a2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java @@ -859,7 +859,7 @@ public class TransformTest extends CardTestPlayerBase { assertLife(playerB, 20); assertGraveyardCount(playerA, dressDown, 1); assertPermanentCount(playerA, huntmasterOfTheFells, 1); - assertPermanentCount(playerA, 6+1+1); + assertPermanentCount(playerA, 6 + 1 + 1); } @Test @@ -924,4 +924,32 @@ public class TransformTest extends CardTestPlayerBase { assertPermanentCount(playerA, baithookAngler, 1); assertTrue(getPermanent(baithookAngler, playerA).isTapped()); } + + /** + * Test that copying a TDFC will not leave and return transformed + */ + @Test + public void testCloneCantReturnTransformed() { + addCard(Zone.BATTLEFIELD, playerA, azusasManyJourneys); + addCard(Zone.HAND, playerA, "Clever Impersonator@impersonator"); + addCard(Zone.BATTLEFIELD, playerA, "Island", 5); + + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clever Impersonator"); + setChoice(playerA, true); // Choose to copy + setChoice(playerA, azusasManyJourneys); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, "@impersonator", CounterType.LORE, 2); + setChoice(playerA, "II"); // order triggers + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, azusasManyJourneys, 1); + assertPermanentCount(playerA, likenessOfTheSeeker, 0); + assertPermanentCount(playerA, "Clever Impersonator", 0); + assertExileCount(playerA, "Clever Impersonator", 1); + } } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 8db8b3fd823..0d392a4309c 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -2297,31 +2297,14 @@ public class VerifyCardDataTest { fail(card, "abilities", "transforming double-faced card should not have abilities on the main card"); } - // TODO: remove after transform ability removed - // special check: new DFC implementation should not have transform ability - if (card instanceof DoubleFacedCardHalf && card.getAbilities().containsClass(TransformAbility.class) - && !card.getAbilities().containsClass(DayboundAbility.class) - && !card.getAbilities().containsClass(CraftAbility.class) - && !card.getAbilities().containsClass(SiegeAbility.class)) { - fail(card, "abilities", "new transforming double-faced card should not have transform ability"); - } - // special check: Werewolves front ability should only be on front and vice versa - if (card.getAbilities().containsClass(WerewolfFrontTriggeredAbility.class) && (card.isNightCard() || (card instanceof DoubleFacedCardHalf && ((DoubleFacedCardHalf) card).isBackSide()))) { + if (card.getAbilities().containsClass(WerewolfFrontTriggeredAbility.class) && (card instanceof DoubleFacedCardHalf && ((DoubleFacedCardHalf) card).isBackSide())) { fail(card, "abilities", "card is a back face werewolf with a front face ability"); } - if (card.getAbilities().containsClass(WerewolfBackTriggeredAbility.class) && (!card.isNightCard() && (card instanceof DoubleFacedCardHalf && !((DoubleFacedCardHalf) card).isBackSide()))) { + if (card.getAbilities().containsClass(WerewolfBackTriggeredAbility.class) && (card instanceof DoubleFacedCardHalf && !((DoubleFacedCardHalf) card).isBackSide())) { fail(card, "abilities", "card is a front face werewolf with a back face ability"); } - // special check: transform ability in TDFC should only be on front and vice versa - if (card.getSecondCardFace() != null && !card.isNightCard() && !card.getAbilities().containsClass(TransformAbility.class)) { - fail(card, "abilities", "double-faced cards should have transform ability on the front"); - } - if (card.getSecondCardFace() != null && card.isNightCard() && card.getAbilities().containsClass(TransformAbility.class)) { - fail(card, "abilities", "double-faced cards should not have transform ability on the back"); - } - // special check: back side in TDFC must be only night card if (card.getSecondCardFace() != null && !card.getSecondCardFace().isNightCard()) { fail(card, "abilities", "the back face of a double-faced card should be nightCard = true"); diff --git a/Mage/src/main/java/mage/abilities/common/SiegeAbility.java b/Mage/src/main/java/mage/abilities/common/SiegeAbility.java index 6e6e57df8a3..295a693cd3f 100644 --- a/Mage/src/main/java/mage/abilities/common/SiegeAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SiegeAbility.java @@ -5,9 +5,9 @@ import mage.abilities.Ability; import mage.abilities.StaticAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; -import mage.constants.*; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; @@ -21,7 +21,6 @@ public class SiegeAbility extends StaticAbility { public SiegeAbility() { super(Zone.ALL, null); - this.addSubAbility(new TransformAbility()); this.addSubAbility(new SiegeDefeatedTriggeredAbility()); } diff --git a/Mage/src/main/java/mage/abilities/common/SpellTransformedAbility.java b/Mage/src/main/java/mage/abilities/common/SpellTransformedAbility.java index 8b3dfd4eeff..e8c329a65a5 100644 --- a/Mage/src/main/java/mage/abilities/common/SpellTransformedAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SpellTransformedAbility.java @@ -1,16 +1,13 @@ package mage.abilities.common; import mage.MageIdentifier; -import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.TransformingDoubleFacedCard; -import mage.constants.*; +import mage.constants.SpellAbilityCastMode; +import mage.constants.SpellAbilityType; import mage.game.Game; -import mage.game.stack.Spell; import java.util.Set; import java.util.UUID; @@ -21,7 +18,6 @@ import java.util.UUID; public class SpellTransformedAbility extends SpellAbility { protected final String manaCost; //This variable is only used for rules text - private boolean ignoreTransformEffect; // TODO: temporary while converting tdfc public SpellTransformedAbility(Card card, String manaCost) { super(card.getSecondFaceSpellAbility()); @@ -37,11 +33,6 @@ public class SpellTransformedAbility extends SpellAbility { this.clearManaCosts(); this.clearManaCostsToPay(); this.addCost(new ManaCostsImpl<>(manaCost)); - if (!(card instanceof TransformingDoubleFacedCard)) { - this.addSubAbility(new TransformAbility()); - } else { - ignoreTransformEffect = true; - } } public SpellTransformedAbility(final SpellAbility ability) { @@ -54,13 +45,11 @@ public class SpellTransformedAbility extends SpellAbility { this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; this.setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED); - //when casting this way, the card must have the TransformAbility from elsewhere } protected SpellTransformedAbility(final SpellTransformedAbility ability) { super(ability); this.manaCost = ability.manaCost; - this.ignoreTransformEffect = ability.ignoreTransformEffect; } @Override @@ -71,14 +60,7 @@ public class SpellTransformedAbility extends SpellAbility { @Override public boolean activate(Game game, Set allowedIdentifiers, boolean noMana) { if (super.activate(game, allowedIdentifiers, noMana)) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + getSourceId(), Boolean.TRUE); - if (ignoreTransformEffect) { - return true; - } - // TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides) - TransformedEffect effect = new TransformedEffect(); - game.addEffect(effect, this); - effect.apply(game, this); //Apply the effect immediately + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + getSourceId(), Boolean.TRUE); return true; } return false; @@ -95,31 +77,3 @@ public class SpellTransformedAbility extends SpellAbility { return ActivationStatus.getFalse(); } } - -class TransformedEffect extends ContinuousEffectImpl { - - public TransformedEffect() { - super(Duration.WhileOnStack, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature); - staticText = ""; - } - - private TransformedEffect(final TransformedEffect effect) { - super(effect); - } - - @Override - public TransformedEffect copy() { - return new TransformedEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Spell spell = game.getSpell(source.getSourceId()); - if (spell == null || spell.getCard().getSecondCardFace() == null) { - return false; - } - // simulate another side as new card (another code part in spell constructor) - TransformAbility.transformCardSpellDynamic(spell, spell.getCard().getSecondCardFace(), game); - return true; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java index ee2151f1ad1..59140adef8e 100644 --- a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java @@ -1,13 +1,10 @@ package mage.abilities.effects; -import java.util.Locale; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; @@ -18,6 +15,9 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; +import java.util.Locale; +import java.util.UUID; + /** * Cards with the Aura subtype don't change the zone they are in, if there is no * valid target on the battlefield. Also, when entering the battlefield and it @@ -184,7 +184,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl { return false; } // in case of transformable enchantments - if (Boolean.TRUE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId())) + if (Boolean.TRUE.equals(game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId())) && card.getSecondCardFace() != null) { card = card.getSecondCardFace(); } diff --git a/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java b/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java index ca871fbffed..ee8e0db4f56 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java @@ -9,6 +9,7 @@ import mage.abilities.costs.common.ExileSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterCard; import mage.filter.FilterPermanent; @@ -59,7 +60,6 @@ public class CraftAbility extends ActivatedAbilityImpl { super(Zone.BATTLEFIELD, new CraftEffect(), new ManaCostsImpl<>(manaString)); this.addCost(new ExileSourceCost()); this.addCost(new CraftCost(target)); - this.addSubAbility(new TransformAbility()); this.timing = TimingRule.SORCERY; this.manaString = manaString; this.description = description; @@ -173,7 +173,7 @@ class CraftEffect extends OneShotEffect { if (player == null || card == null || card.getZoneChangeCounter(game) != source.getStackMomentSourceZCC() + 1) { return false; } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); player.moveCards(card, Zone.BATTLEFIELD, source, game); return true; } diff --git a/Mage/src/main/java/mage/abilities/keyword/DayboundAbility.java b/Mage/src/main/java/mage/abilities/keyword/DayboundAbility.java index c6dcfc78542..ec4f0f201cb 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DayboundAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DayboundAbility.java @@ -15,7 +15,6 @@ public class DayboundAbility extends StaticAbility { public DayboundAbility() { super(Zone.BATTLEFIELD, new DayboundEffect()); this.addHint(DayNightHint.instance); - this.addSubAbility(new TransformAbility()); } private DayboundAbility(final DayboundAbility ability) { diff --git a/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java b/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java deleted file mode 100644 index 6606464266b..00000000000 --- a/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java +++ /dev/null @@ -1,177 +0,0 @@ -package mage.abilities.keyword; - -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.cards.Card; -import mage.constants.*; -import mage.game.Game; -import mage.game.MageObjectAttribute; -import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentToken; -import mage.game.stack.Spell; -import mage.util.CardUtil; - -/** - * @author nantuko - */ -public class TransformAbility extends SimpleStaticAbility { - - // this state value controls if a permanent enters the battlefield already transformed - public static final String VALUE_KEY_ENTER_TRANSFORMED = "EnterTransformed"; - - public TransformAbility() { - super(Zone.BATTLEFIELD, new TransformEffect()); - } - - private TransformAbility(final TransformAbility ability) { - super(ability); - } - - @Override - public TransformAbility copy() { - return new TransformAbility(this); - } - - @Override - public String getRule() { - return ""; - } - - /** - * Apply transform effect to permanent (copy characteristic and other things) - */ - public static boolean transformPermanent(Permanent permanent, Game game, Ability source) { - MageObject sourceCard = findSourceObjectForTransform(permanent); - if (sourceCard == null) { - return false; - } - - permanent.setTransformed(true); - permanent.setName(sourceCard.getName()); - permanent.getColor(game).setColor(sourceCard.getColor(game)); - permanent.getManaCost().clear(); - permanent.getManaCost().add(sourceCard.getManaCost().copy()); - permanent.removeAllCardTypes(game); - for (CardType type : sourceCard.getCardType(game)) { - permanent.addCardType(game, type); - } - permanent.removeAllSubTypes(game); - permanent.copySubTypesFrom(game, sourceCard); - permanent.removeAllSuperTypes(game); - for (SuperType type : sourceCard.getSuperType(game)) { - permanent.addSuperType(game, type); - } - - CardUtil.copySetAndCardNumber(permanent, sourceCard); - - permanent.getAbilities().clear(); - for (Ability ability : sourceCard.getAbilities()) { - // source == null -- call from init card (e.g. own abilities) - // source != null -- from apply effect - permanent.addAbility(ability, source == null ? permanent.getId() : source.getSourceId(), game, true); - } - permanent.getPower().setModifiedBaseValue(sourceCard.getPower().getValue()); - permanent.getToughness().setModifiedBaseValue(sourceCard.getToughness().getValue()); - permanent.setStartingLoyalty(sourceCard.getStartingLoyalty()); - permanent.setStartingDefense(sourceCard.getStartingDefense()); - - return true; - } - - private static MageObject findSourceObjectForTransform(Permanent permanent) { - if (permanent == null) { - return null; - } - - // copies can't transform - if (permanent.isCopy()) { - return null; - } - - if (permanent instanceof PermanentToken) { - return ((PermanentToken) permanent).getToken().getBackFace(); - } else { - return permanent.getSecondCardFace(); - } - } - - public static Card transformCardSpellStatic(Card mainSide, Card otherSide, Game game) { - // workaround to simulate transformed card on the stack (example: disturb ability) - // prepare static attributes - // TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides) - Card newCard = mainSide.copy(); - newCard.setName(otherSide.getName()); - - // mana value must be from main side only - newCard.getManaCost().clear(); - newCard.getManaCost().add(mainSide.getManaCost().copy()); - - game.getState().getCardState(newCard.getId()).clearAbilities(); - for (Ability ability : otherSide.getAbilities()) { - game.getState().addOtherAbility(newCard, ability); - } - newCard.getPower().setModifiedBaseValue(otherSide.getPower().getValue()); - newCard.getToughness().setModifiedBaseValue(otherSide.getToughness().getValue()); - - return newCard; - } - - public static void transformCardSpellDynamic(Spell spell, Card otherSide, Game game) { - // workaround to simulate transformed card on the stack (example: disturb ability) - // prepare dynamic attributes - // TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides) - MageObjectAttribute moa = game.getState().getCreateMageObjectAttribute(spell.getCard(), game); - moa.getColor().setColor(otherSide.getColor(game)); - moa.getCardType().clear(); - moa.getCardType().addAll(otherSide.getCardType(game)); - moa.getSuperType().clear(); - moa.getSuperType().addAll(otherSide.getSuperType(game)); - moa.getSubtype().clear(); - moa.getSubtype().addAll(otherSide.getSubtype(game)); - - game.getState().getCardState(spell.getCard().getId()).clearAbilities(); - for (Ability ability : otherSide.getAbilities()) { - game.getState().addOtherAbility(spell.getCard(), ability); - } - } -} - -class TransformEffect extends ContinuousEffectImpl { - - TransformEffect() { - super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature); - staticText = ""; - } - - private TransformEffect(final TransformEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - return false; - } - - // only for transformed permanents - if (!permanent.isTransformed()) { - return false; - } - - return TransformAbility.transformPermanent(permanent, game, source); - } - - @Override - public TransformEffect copy() { - return new TransformEffect(this); - } - - @Override - public String getText(Mode mode) { - return ""; - } -} diff --git a/Mage/src/main/java/mage/cards/TransformingDoubleFacedCard.java b/Mage/src/main/java/mage/cards/TransformingDoubleFacedCard.java index aa56e519844..01d2f2b7710 100644 --- a/Mage/src/main/java/mage/cards/TransformingDoubleFacedCard.java +++ b/Mage/src/main/java/mage/cards/TransformingDoubleFacedCard.java @@ -8,6 +8,9 @@ import java.util.UUID; public abstract class TransformingDoubleFacedCard extends DoubleFacedCard { + // this state value controls if a permanent enters the battlefield already transformed + public static final String VALUE_KEY_ENTER_TRANSFORMED = "EnterTransformed"; + public TransformingDoubleFacedCard( UUID ownerId, CardSetInfo setInfo, CardType[] typesLeft, SubType[] subTypesLeft, String costsLeft, diff --git a/Mage/src/main/java/mage/constants/PutCards.java b/Mage/src/main/java/mage/constants/PutCards.java index 2d93243ff52..f2881ca500c 100644 --- a/Mage/src/main/java/mage/constants/PutCards.java +++ b/Mage/src/main/java/mage/constants/PutCards.java @@ -1,8 +1,10 @@ package mage.constants; import mage.abilities.Ability; -import mage.abilities.keyword.TransformAbility; -import mage.cards.*; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -93,7 +95,7 @@ public enum PutCards { if (card instanceof TransformingDoubleFacedCard) { card = ((TransformingDoubleFacedCard) card).getRightHalfCard(); } - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); case BATTLEFIELD: case EXILED: case HAND: @@ -131,7 +133,7 @@ public enum PutCards { case SHUFFLE: return player.shuffleCardsToLibrary(cards, game, source); case BATTLEFIELD_TRANSFORMED: - cards.stream().forEach(uuid -> game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + uuid, Boolean.TRUE)); + cards.stream().forEach(uuid -> game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + uuid, Boolean.TRUE)); case BATTLEFIELD: case EXILED: case HAND: diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/TransformablePredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/TransformablePredicate.java new file mode 100644 index 00000000000..da200e11bfc --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/TransformablePredicate.java @@ -0,0 +1,19 @@ +package mage.filter.predicate.permanent; + +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +public enum TransformablePredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.isTransformable(); + } + + @Override + public String toString() { + return "Transformable"; + } +} diff --git a/Mage/src/main/java/mage/game/ZonesHandler.java b/Mage/src/main/java/mage/game/ZonesHandler.java index ad215f21baf..a248937b8bb 100644 --- a/Mage/src/main/java/mage/game/ZonesHandler.java +++ b/Mage/src/main/java/mage/game/ZonesHandler.java @@ -1,7 +1,6 @@ package mage.game; import mage.abilities.Ability; -import mage.abilities.keyword.TransformAbility; import mage.cards.*; import mage.constants.Outcome; import mage.constants.Zone; @@ -91,8 +90,7 @@ public final class ZonesHandler { Card card = game.getCard(info.event.getTargetId()); if (card instanceof DoubleFacedCard || card instanceof DoubleFacedCardHalf) { boolean forceToMainSide = false; - // TODO: move transform key or have some other identifier after tdfc rework - Boolean enterTransformed = (Boolean) game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()); + Boolean enterTransformed = (Boolean) game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId()); if (enterTransformed == null) { enterTransformed = false; } @@ -296,7 +294,7 @@ public final class ZonesHandler { game.getPermanentsEntering().remove(permanent.getId()); break; default: - throw new UnsupportedOperationException("to Zone " + toZone.toString() + " not supported yet"); + throw new UnsupportedOperationException("to Zone " + toZone + " not supported yet"); } } @@ -376,15 +374,13 @@ public final class ZonesHandler { isGoodToMove = true; } else if (event.getToZone().equals(Zone.BATTLEFIELD)) { // non-permanents can't move to battlefield - // TODO: possible bug with Nightbound, search all usage of getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED and insert additional check Ability.checkCard + // TODO: possible bug with Nightbound, search all usage of getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED and insert additional check Ability.checkCard /* - * 712.14a. If a spell or ability puts a transforming double-faced card onto the battlefield "transformed" - * or "converted," it enters the battlefield with its back face up. If a player is instructed to put a card - * that isn't a transforming double-faced card onto the battlefield transformed or converted, that card stays in - * its current zone. + * 712.14a. If a spell or ability puts a double-faced card onto the battlefield "transformed" or "converted," + * it enters the battlefield with its back face up. If a player is instructed to put a card that isn't a double-faced card + * onto the battlefield transformed or converted, that card stays in its current zone. */ - // TODO: remove after tdfc rework - boolean wantToTransform = Boolean.TRUE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId())); + boolean wantToTransform = Boolean.TRUE.equals(game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId())); if (wantToTransform && !(card instanceof DoubleFacedCardHalf)) { isGoodToMove = card.isTransformable() && card.getSecondCardFace().isPermanent(game); } else { diff --git a/Mage/src/main/java/mage/game/permanent/token/IncubatorToken.java b/Mage/src/main/java/mage/game/permanent/token/IncubatorToken.java index fc285f88af1..5c83b870030 100644 --- a/Mage/src/main/java/mage/game/permanent/token/IncubatorToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/IncubatorToken.java @@ -3,7 +3,6 @@ package mage.game.permanent.token; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; import mage.constants.CardType; import mage.constants.SubType; @@ -18,7 +17,6 @@ public final class IncubatorToken extends TokenImpl { subtype.add(SubType.INCUBATOR); this.backFace = new Phyrexian00Token(); - this.addAbility(new TransformAbility()); this.addAbility(new SimpleActivatedAbility( new TransformSourceEffect().setText("transform this artifact"), new GenericManaCost(2) )); diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index e9b54a60375..f79d89a8f66 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -8,7 +8,6 @@ import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.keyword.BestowAbility; import mage.abilities.keyword.PrototypeAbility; -import mage.abilities.keyword.TransformAbility; import mage.cards.*; import mage.constants.*; import mage.counters.Counter; @@ -81,11 +80,6 @@ public class Spell extends StackObjectImpl implements Card { Card affectedCard = card; - // TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides) - if (ability.getSpellAbilityCastMode().isTransformed() && affectedCard.getSecondCardFace() != null) { - // simulate another side as new card (another code part in continues effect from disturb ability) - affectedCard = TransformAbility.transformCardSpellStatic(card, card.getSecondCardFace(), game); - } if (ability instanceof PrototypeAbility) { affectedCard = ((PrototypeAbility) ability).prototypeCardSpell(card); this.prototyped = true; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index e2c6348cbaa..b9f75e83780 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -4110,7 +4110,7 @@ public abstract class PlayerImpl implements Player, Serializable { TransformingDoubleFacedCard mainCard = (TransformingDoubleFacedCard) object; getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output); getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output); - } else if (object instanceof CardWithSpellOption) { + } else if (object instanceof CardWithSpellOption) { // adventure must use different card characteristics for different spells (main or adventure) CardWithSpellOption cardWithSpellOption = (CardWithSpellOption) object; getPlayableFromObjectSingle(game, fromZone, cardWithSpellOption.getSpellCard(), cardWithSpellOption.getSpellCard().getAbilities(game), availableMana, output); @@ -4952,16 +4952,6 @@ public abstract class PlayerImpl implements Player, Serializable { for (Card card : cards) { fromZone = game.getState().getZone(card.getId()); - // 712.14a. If a spell or ability puts a transforming double-faced card onto the battlefield "transformed" - // or "converted," it enters the battlefield with its back face up. If a player is instructed to put a card - // that isn't a transforming double-faced card onto the battlefield transformed or converted, that card stays in - // its current zone. - // TODO: can probably remove/change after tdfc rework, should only be sending transformed side - Boolean enterTransformed = (Boolean) game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()); - if (enterTransformed != null && enterTransformed && !card.isTransformable() && !(card instanceof TransformingDoubleFacedCardHalf)) { - continue; - } - // 303.4g. If an Aura is entering the battlefield and there is no legal object or player for it to enchant, // the Aura remains in its current zone, unless that zone is the stack. In that case, the Aura is put into // its owner's graveyard instead of entering the battlefield. If the Aura is a token, it isn't created. From 8d82e1aa31c8d9fedff28a338a5be48388783f5c Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sun, 7 Dec 2025 11:18:02 -0600 Subject: [PATCH 4/7] Card - update todo for nightCard * still used by meld, will be removed after converting meld cards --- Mage/src/main/java/mage/cards/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/cards/Card.java b/Mage/src/main/java/mage/cards/Card.java index b78ff8d133a..2edff923359 100644 --- a/Mage/src/main/java/mage/cards/Card.java +++ b/Mage/src/main/java/mage/cards/Card.java @@ -73,7 +73,7 @@ public interface Card extends MageObject, Ownerable { SpellAbility getSecondFaceSpellAbility(); - //TODO: remove after tdfc rework + //TODO: remove after meld converted to DFC boolean isNightCard(); default boolean meldsWith(Card card) { From 0b9382f9cd774cbd13a5b08e4334f2eda6891403 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sun, 7 Dec 2025 11:18:58 -0600 Subject: [PATCH 5/7] CardView - remove old transformable setting code --- Mage.Common/src/main/java/mage/view/CardView.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Mage.Common/src/main/java/mage/view/CardView.java b/Mage.Common/src/main/java/mage/view/CardView.java index 4892830edbb..b8cdd8f06e3 100644 --- a/Mage.Common/src/main/java/mage/view/CardView.java +++ b/Mage.Common/src/main/java/mage/view/CardView.java @@ -538,17 +538,7 @@ public class CardView extends SimpleCardView { this.extraDeckCard = card.isExtraDeckCard(); - // TODO: can probably remove this after tdfc rework - // transformable, double faces cards - if (!(sourceCard.getMainCard() instanceof DoubleFacedCard)) { - this.transformable = card.isTransformable(); - - Card secondSideCard = card.getSecondCardFace(); - if (secondSideCard != null) { - this.secondCardFace = new CardView(secondSideCard, game); - this.alternateName = secondCardFace.getName(); - } - } else if (card instanceof PermanentCard && card.isTransformable()) { + if (card instanceof PermanentCard && card.isTransformable()) { this.transformable = card.isTransformable(); Card secondSideCard = (Card) ((PermanentCard) card).getOtherFace(); this.secondCardFace = new CardView(secondSideCard, game); From 6ec96ef154a501dfa927b4ea7ddd960244dd3c13 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sun, 7 Dec 2025 11:19:28 -0600 Subject: [PATCH 6/7] remove old transformable reference code from Mycosynth Lattice and Painter's Servant --- .../src/mage/cards/m/MycosynthLattice.java | 6 ---- .../src/mage/cards/p/PaintersServant.java | 6 ---- .../test/cards/mana/MycosynthLatticeTest.java | 30 +++++++++++++++++++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MycosynthLattice.java b/Mage.Sets/src/mage/cards/m/MycosynthLattice.java index 7f14adf8639..ce5654886de 100644 --- a/Mage.Sets/src/mage/cards/m/MycosynthLattice.java +++ b/Mage.Sets/src/mage/cards/m/MycosynthLattice.java @@ -149,12 +149,6 @@ class EverythingIsColorlessEffect extends ContinuousEffectImpl { game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().setColor(colorless); game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().setColor(colorless); } - - // double faces cards - // TODO: can remove after tdfc rework - if (card.getSecondCardFace() != null) { - game.getState().getCreateMageObjectAttribute(card, game).getColor().setColor(colorless); - } }); return true; } diff --git a/Mage.Sets/src/mage/cards/p/PaintersServant.java b/Mage.Sets/src/mage/cards/p/PaintersServant.java index 4c47d77655f..c1327002cad 100644 --- a/Mage.Sets/src/mage/cards/p/PaintersServant.java +++ b/Mage.Sets/src/mage/cards/p/PaintersServant.java @@ -122,12 +122,6 @@ class PaintersServantEffect extends ContinuousEffectImpl { game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().addColor(color); game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().addColor(color); } - - // double faces cards - // TODO: can remove after tdfc rework - if (card.getSecondCardFace() != null) { - game.getState().getCreateMageObjectAttribute(card.getSecondCardFace(), game).getColor().addColor(color); - } }); return true; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/MycosynthLatticeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/MycosynthLatticeTest.java index 4b86b4a810c..a9ba8ca74cf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/MycosynthLatticeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/MycosynthLatticeTest.java @@ -6,6 +6,8 @@ import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; +import static org.junit.Assert.assertTrue; + public class MycosynthLatticeTest extends CardTestPlayerBase { @Test @@ -57,4 +59,32 @@ public class MycosynthLatticeTest extends CardTestPlayerBase { assertCounterCount(playerA, crawler, CounterType.P1P1, 4); } + + @Test + public void testColorsWithDifferentCardTypes() { + String azusasManyJourneys = "Azusa's Many Journeys"; // TDFC + String alrundGodOfTheCosmos = "Alrund, God of the Cosmos"; // MDFC + String carnivalCarnage = "Carnival // Carnage"; // Split Card + + addCard(Zone.BATTLEFIELD, playerA, "Mycosynth Lattice"); + addCard(Zone.GRAVEYARD, playerA, azusasManyJourneys); + addCard(Zone.HAND, playerA, alrundGodOfTheCosmos); + addCard(Zone.LIBRARY, playerA, carnivalCarnage); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + currentGame.getCards().forEach(card -> { + if (card.getName().equals(azusasManyJourneys) + || card.getName().equals("Likeness of the Seeker") + || card.getName().equals(alrundGodOfTheCosmos) + || card.getName().equals("Alrund's Epiphany") + || card.getName().equals("Carnival") + || card.getName().equals("Carnage")) { + assertTrue("Card " + card.getName() + " should be colorless", card.getColor(currentGame).isColorless()); + } + }); + + } } From d25edbce5b83f3404455d21a6addc3f609bc688e Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Sun, 7 Dec 2025 11:20:42 -0600 Subject: [PATCH 7/7] VerifyCardDataTest - remove old transformable reference from test_checkMissingCardData --- .../src/test/java/mage/verify/VerifyCardDataTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 0d392a4309c..2313c827433 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1228,11 +1228,6 @@ public class VerifyCardDataTest { cardInfo.getCardNumber(), cardInfo.getRarity(), cardInfo.getGraphicInfo())); Assert.assertNotNull(card); - //TODO: do we need this check after tdfc rework? - if (card.getSecondCardFace() != null && !(card instanceof DoubleFacedCard)) { - containsDoubleSideCards = true; - } - // CHECK: all planeswalkers must be legendary if (card.isPlaneswalker() && !card.isLegendary()) { errorsList.add("Error: planeswalker must have legendary type: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber());