mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
implement [MKM] Cryptic Coat (#12164) and Cloak ability
This commit is contained in:
parent
8172616449
commit
ab280ad2ba
15 changed files with 235 additions and 29 deletions
|
|
@ -33,6 +33,7 @@ public class PermanentView extends CardView {
|
|||
private final boolean morphed;
|
||||
private final boolean disguised;
|
||||
private final boolean manifested;
|
||||
private final boolean cloaked;
|
||||
private final boolean attachedToPermanent;
|
||||
// If this card is attached to a permanent which is controlled by a player other than the one which controls this permanent
|
||||
private final boolean attachedControllerDiffers;
|
||||
|
|
@ -47,6 +48,7 @@ public class PermanentView extends CardView {
|
|||
this.morphed = permanent.isMorphed();
|
||||
this.disguised = permanent.isDisguised();
|
||||
this.manifested = permanent.isManifested();
|
||||
this.cloaked = permanent.isCloaked();
|
||||
this.damage = permanent.getDamage();
|
||||
this.attachments = new ArrayList<>(permanent.getAttachments());
|
||||
this.attachedTo = permanent.getAttachedTo();
|
||||
|
|
@ -143,6 +145,7 @@ public class PermanentView extends CardView {
|
|||
this.morphed = permanentView.morphed;
|
||||
this.disguised = permanentView.disguised;
|
||||
this.manifested = permanentView.manifested;
|
||||
this.cloaked = permanentView.cloaked;
|
||||
this.attachedToPermanent = permanentView.attachedToPermanent;
|
||||
this.attachedControllerDiffers = permanentView.attachedControllerDiffers;
|
||||
}
|
||||
|
|
@ -222,4 +225,8 @@ public class PermanentView extends CardView {
|
|||
public boolean isManifested() {
|
||||
return manifested;
|
||||
}
|
||||
|
||||
public boolean isCloaked() {
|
||||
return cloaked;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
97
Mage.Sets/src/mage/cards/c/CrypticCoat.java
Normal file
97
Mage.Sets/src/mage/cards/c/CrypticCoat.java
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||
import mage.abilities.effects.common.combat.CantBeBlockedAttachedEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
|
||||
import mage.abilities.effects.keyword.ManifestEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AttachmentType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class CrypticCoat extends CardImpl {
|
||||
|
||||
public CrypticCoat(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
|
||||
|
||||
this.subtype.add(SubType.EQUIPMENT);
|
||||
|
||||
// When Cryptic Coat enters the battlefield, cloak the top card of your library, then attach Cryptic Coat to it.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new CrypticCoatEffect()));
|
||||
|
||||
// Equipped creature gets +1/+0 and can't be blocked.
|
||||
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
|
||||
ability.addEffect(new CantBeBlockedAttachedEffect(AttachmentType.EQUIPMENT)
|
||||
.setText("and can't be blocked")
|
||||
);
|
||||
this.addAbility(ability);
|
||||
|
||||
// {1}{U}: Return Cryptic Coat to its owner's hand.
|
||||
this.addAbility(new SimpleActivatedAbility(new ReturnToHandSourceEffect(), new ManaCostsImpl<>("{1}{U}")));
|
||||
}
|
||||
|
||||
private CrypticCoat(final CrypticCoat card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrypticCoat copy() {
|
||||
return new CrypticCoat(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CrypticCoatEffect extends OneShotEffect {
|
||||
|
||||
CrypticCoatEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "cloak the top card of your library, then attach {this} to it";
|
||||
}
|
||||
|
||||
private CrypticCoatEffect(final CrypticCoatEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrypticCoatEffect copy() {
|
||||
return new CrypticCoatEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
List<Permanent> cloakedList = ManifestEffect.doManifestCards(
|
||||
game, source, controller,
|
||||
controller.getLibrary().getTopCards(game, 1), true
|
||||
);
|
||||
if (cloakedList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Permanent cloaked = cloakedList.get(0);
|
||||
new AttachEffect(Outcome.BoostCreature, "attach {this} to it")
|
||||
.setTargetPointer(new FixedTarget(cloaked, game))
|
||||
.apply(game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,6 +79,6 @@ class OrochiSoulReaverManifestEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, controller, targetPlayer.getLibrary().getTopCards(game, 1));
|
||||
return !ManifestEffect.doManifestCards(game, source, controller, targetPlayer.getLibrary().getTopCards(game, 1)).isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,6 @@ class ScrollOfFateEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, controller, new CardsImpl(targetCard.getTargets()).getCards(game));
|
||||
return !ManifestEffect.doManifestCards(game, source, controller, new CardsImpl(targetCard.getTargets()).getCards(game)).isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class ThievingAmalgamManifestEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, controller, targetPlayer.getLibrary().getTopCards(game, 1));
|
||||
return !ManifestEffect.doManifestCards(game, source, controller, targetPlayer.getLibrary().getTopCards(game, 1)).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ class VesuvanShapeshifterFaceDownEffect extends OneShotEffect {
|
|||
permanent.turnFaceDown(source, game, source.getControllerId());
|
||||
permanent.setManifested(false);
|
||||
permanent.setDisguised(false);
|
||||
permanent.setCloaked(false);
|
||||
permanent.setMorphed(true); // cause it morph card TODO: smells bad
|
||||
return permanent.isFaceDown(game);
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public final class MurdersAtKarlovManor extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Crimestopper Sprite", 49, Rarity.COMMON, mage.cards.c.CrimestopperSprite.class));
|
||||
cards.add(new SetCardInfo("Crowd-Control Warden", 193, Rarity.COMMON, mage.cards.c.CrowdControlWarden.class));
|
||||
cards.add(new SetCardInfo("Cryptex", 251, Rarity.RARE, mage.cards.c.Cryptex.class));
|
||||
cards.add(new SetCardInfo("Cryptic Coat", 50, Rarity.RARE, mage.cards.c.CrypticCoat.class));
|
||||
cards.add(new SetCardInfo("Culvert Ambusher", 158, Rarity.UNCOMMON, mage.cards.c.CulvertAmbusher.class));
|
||||
cards.add(new SetCardInfo("Curious Cadaver", 194, Rarity.UNCOMMON, mage.cards.c.CuriousCadaver.class));
|
||||
cards.add(new SetCardInfo("Curious Inquiry", 51, Rarity.UNCOMMON, mage.cards.c.CuriousInquiry.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package org.mage.test.cards.single.mkm;
|
||||
|
||||
import mage.constants.EmptyNames;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class CrypticCoatTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* {@link mage.cards.c.CrypticCoat Cryptic Coat} {2}{U}
|
||||
* Artifact — Equipment
|
||||
* When Cryptic Coat enters the battlefield, cloak the top card of your library, then attach Cryptic Coat to it. (To cloak a card, put it onto the battlefield face down as a 2/2 creature with ward {2}. Turn it face up any time for its mana cost if it’s a creature card.)
|
||||
* Equipped creature gets +1/+0 and can’t be blocked.
|
||||
* {1}{U}: Return Cryptic Coat to its owner’s hand.
|
||||
*/
|
||||
private static final String coat = "Cryptic Coat";
|
||||
|
||||
@Test
|
||||
public void test_CloakCreature() {
|
||||
skipInitShuffling();
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||
addCard(Zone.HAND, playerA, coat);
|
||||
addCard(Zone.LIBRARY, playerA, "Ancient Crab");
|
||||
addCard(Zone.HAND, playerB, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, coat);
|
||||
|
||||
checkPT("Cloaked is 3/2", 1, PhaseStep.BEGIN_COMBAT, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 3, 2);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", EmptyNames.FACE_DOWN_CREATURE.toString());
|
||||
setChoice(playerB, true); // pay for ward
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U}{U}: Turn this face-down permanent face up.");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, "Ancient Crab", 1 + 1, 5);
|
||||
assertDamageReceived(playerA, "Ancient Crab", 3);
|
||||
assertTappedCount("Mountain", true, 3);
|
||||
assertTappedCount("Island", true, 6);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,24 +111,29 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
new TurnFaceUpAbility(turnFaceUpCosts, faceDownType == FaceDownType.MEGAMORPHED)
|
||||
.setCostAdjuster(costAdjuster)
|
||||
);
|
||||
}
|
||||
|
||||
switch (faceDownType) {
|
||||
case MORPHED:
|
||||
case MEGAMORPHED:
|
||||
if (turnFaceUpCosts != null) {
|
||||
// face up rules replace for cost hide
|
||||
this.additionalAbilities.add(new SimpleStaticAbility(Zone.ALL, new InfoEffect(
|
||||
"Turn it face up any time for its morph cost."
|
||||
)));
|
||||
}
|
||||
break;
|
||||
case DISGUISED:
|
||||
case CLOAKED:
|
||||
// ward
|
||||
// Ward {2} -- should not be dependent on turnFaceUpCosts.
|
||||
this.additionalAbilities.add(new WardAbility(new ManaCostsImpl<>("{2}")));
|
||||
|
||||
if (turnFaceUpCosts != null) {
|
||||
// face up rules replace for cost hide
|
||||
this.additionalAbilities.add(new SimpleStaticAbility(Zone.ALL, new InfoEffect(
|
||||
"Turn it face up any time for its disguise/cloaked cost."
|
||||
)));
|
||||
}
|
||||
break;
|
||||
case MANUAL:
|
||||
case MANIFESTED:
|
||||
|
|
@ -137,7 +142,6 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
default:
|
||||
throw new IllegalArgumentException("Un-supported face down type: " + faceDownType);
|
||||
}
|
||||
}
|
||||
|
||||
staticText = "{this} becomes a 2/2 face-down creature, with no text, no name, no subtypes, and no mana cost";
|
||||
foundPermanent = false;
|
||||
|
|
@ -209,6 +213,9 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
case DISGUISED:
|
||||
permanent.setDisguised(true);
|
||||
break;
|
||||
case CLOAKED:
|
||||
permanent.setCloaked(true);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("FaceDownType not yet supported: " + faceDownType);
|
||||
}
|
||||
|
|
@ -228,6 +235,8 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
return BecomesFaceDownCreatureEffect.FaceDownType.DISGUISED;
|
||||
} else if (permanent.isManifested()) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.MANIFESTED;
|
||||
} else if (permanent.isCloaked()) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.CLOAKED;
|
||||
} else if (permanent.isFaceDown(game)) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.MANUAL;
|
||||
} else {
|
||||
|
|
@ -326,7 +335,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST;
|
||||
break;
|
||||
case CLOAKED:
|
||||
tokenName = "TODO-CLOAKED";
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_CLOAK;
|
||||
break;
|
||||
case MANUAL:
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANUAL;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manifest
|
||||
|
|
@ -65,6 +65,7 @@ public class ManifestEffect extends OneShotEffect {
|
|||
|
||||
private final DynamicValue amount;
|
||||
private final boolean isPlural;
|
||||
private final boolean cloakNotManifest;
|
||||
|
||||
public ManifestEffect(int amount) {
|
||||
this(StaticValue.get(amount), amount > 1);
|
||||
|
|
@ -75,9 +76,14 @@ public class ManifestEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
private ManifestEffect(DynamicValue amount, boolean isPlural) {
|
||||
this(amount, isPlural, false);
|
||||
}
|
||||
|
||||
private ManifestEffect(DynamicValue amount, boolean isPlural, boolean cloakNotManifest) {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.amount = amount;
|
||||
this.isPlural = isPlural;
|
||||
this.cloakNotManifest = cloakNotManifest;
|
||||
this.staticText = setText();
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +91,7 @@ public class ManifestEffect extends OneShotEffect {
|
|||
super(effect);
|
||||
this.amount = effect.amount;
|
||||
this.isPlural = effect.isPlural;
|
||||
this.cloakNotManifest = effect.cloakNotManifest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -100,12 +107,16 @@ public class ManifestEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
int manifestAmount = amount.calculate(game, source, this);
|
||||
return doManifestCards(game, source, controller, controller.getLibrary().getTopCards(game, manifestAmount));
|
||||
return !doManifestCards(game, source, controller, controller.getLibrary().getTopCards(game, manifestAmount), cloakNotManifest).isEmpty();
|
||||
}
|
||||
|
||||
public static boolean doManifestCards(Game game, Ability source, Player manifestPlayer, Set<Card> cardsToManifest) {
|
||||
public static List<Permanent> doManifestCards(Game game, Ability source, Player manifestPlayer, Set<Card> cardsToManifest) {
|
||||
return doManifestCards(game, source, manifestPlayer, cardsToManifest, false);
|
||||
}
|
||||
|
||||
public static List<Permanent> doManifestCards(Game game, Ability source, Player manifestPlayer, Set<Card> cardsToManifest, boolean cloakNotManifest) {
|
||||
if (cardsToManifest.isEmpty()) {
|
||||
return false;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// prepare source ability
|
||||
|
|
@ -132,9 +143,10 @@ public class ManifestEffect extends OneShotEffect {
|
|||
|
||||
// zcc + 1 for use case with Rally the Ancestors (see related test)
|
||||
MageObjectReference objectReference = new MageObjectReference(battlefieldCard.getId(), battlefieldCard.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, cloakNotManifest ? FaceDownType.CLOAKED : FaceDownType.MANIFESTED), newSource);
|
||||
}
|
||||
|
||||
List<Permanent> manifested = new ArrayList<>();
|
||||
// move cards to battlefield as face down
|
||||
// TODO: possible buggy for multiple cards, see rule 701.34e - it require manifest one by one (card to check: Omarthis, Ghostfire Initiate)
|
||||
manifestPlayer.moveCards(cardsToManifest, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
|
|
@ -145,18 +157,25 @@ public class ManifestEffect extends OneShotEffect {
|
|||
if (permanent != null) {
|
||||
// TODO: permanent already has manifested status, so code can be deleted later
|
||||
// TODO: add test with battlefield trigger/watcher (must not see normal card, must not see face down status without manifest)
|
||||
if (cloakNotManifest) {
|
||||
permanent.setCloaked(true);
|
||||
} else {
|
||||
permanent.setManifested(true);
|
||||
}
|
||||
manifested.add(permanent);
|
||||
} else {
|
||||
// TODO: looks buggy, card can't be moved to battlefield, but face down effect already active
|
||||
// or it can be face down on another move to battlefield
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return manifested;
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
StringBuilder sb = new StringBuilder("manifest the top ");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(cloakNotManifest ? "cloak" : "manifest");
|
||||
sb.append(" the top ");
|
||||
if (isPlural) {
|
||||
sb.append(CardUtil.numberToText(amount.toString())).append(" cards ");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, targetPlayer, targetPlayer.getLibrary().getTopCards(game, amount));
|
||||
return !ManifestEffect.doManifestCards(game, source, targetPlayer, targetPlayer.getLibrary().getTopCards(game, amount)).isEmpty();
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public enum TokenRepository {
|
|||
// - additional card name for controller like "Morph: face up name"
|
||||
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_CLOAK = "Cloak";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MORPH = "Morph";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE = "Disguise";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_FORETELL = "Foretell";
|
||||
|
|
@ -287,6 +288,10 @@ public enum TokenRepository {
|
|||
// 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"));
|
||||
|
||||
// Cloak
|
||||
// support only 1 image: https://scryfall.com/card/tmkm/21/a-mysterious-creature
|
||||
res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_CLOAK, 1, "https://api.scryfall.com/cards/tmkm/21/en?format=image"));
|
||||
|
||||
// Foretell
|
||||
// https://scryfall.com/search?q=Foretell+unique%3Aprints+otag%3Aassistant-cards&unique=cards&as=grid&order=name
|
||||
res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_FORETELL, 1, "https://api.scryfall.com/cards/tkhm/23/en?format=image"));
|
||||
|
|
|
|||
|
|
@ -450,6 +450,10 @@ public interface Permanent extends Card, Controllable {
|
|||
|
||||
boolean isManifested();
|
||||
|
||||
void setCloaked(boolean value);
|
||||
|
||||
boolean isCloaked();
|
||||
|
||||
boolean isRingBearer();
|
||||
|
||||
void setRingBearer(Game game, boolean value);
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ public class PermanentCard extends PermanentImpl {
|
|||
setManifested(false);
|
||||
setMorphed(false);
|
||||
setDisguised(false);
|
||||
setCloaked(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
protected boolean renowned;
|
||||
protected boolean suspected;
|
||||
protected boolean manifested = false;
|
||||
protected boolean cloaked = false;
|
||||
protected boolean morphed = false;
|
||||
protected boolean disguised = false;
|
||||
protected boolean ringBearerFlag = false;
|
||||
|
|
@ -189,6 +190,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
this.morphed = permanent.morphed;
|
||||
this.disguised = permanent.disguised;
|
||||
this.manifested = permanent.manifested;
|
||||
this.cloaked = permanent.cloaked;
|
||||
this.createOrder = permanent.createOrder;
|
||||
this.prototyped = permanent.prototyped;
|
||||
this.canBeSacrificed = permanent.canBeSacrificed;
|
||||
|
|
@ -1905,6 +1907,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
manifested = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCloaked() {
|
||||
return cloaked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCloaked(boolean value) {
|
||||
cloaked = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMorphed() {
|
||||
return morphed;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue