mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 05:22:02 -08:00
[WHO] implemented Disguise ability (new face down type, ability and token image, #10653)
This commit is contained in:
parent
ab787a2b8b
commit
9ea3356b77
16 changed files with 313 additions and 41 deletions
|
|
@ -429,6 +429,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
case BESTOW:
|
||||
case MORPH:
|
||||
case MEGAMORPH:
|
||||
case DISGUISE:
|
||||
// from Snapcaster Mage:
|
||||
// If you cast a spell from a graveyard using its flashback ability, you can't pay other alternative costs
|
||||
// (such as that of Foil). (2018-12-07)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class BecomesFaceDownCreatureAllEffect extends ContinuousEffectImpl {
|
|||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof MorphAbility) {
|
||||
this.turnFaceUpAbilityMap.put(card.getId(), new TurnFaceUpAbility(((MorphAbility) ability).getMorphCosts()));
|
||||
this.turnFaceUpAbilityMap.put(card.getId(), new TurnFaceUpAbility(((MorphAbility) ability).getFaceUpCosts()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import mage.abilities.common.TurnFaceUpAbility;
|
|||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.keyword.WardAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.repository.TokenInfo;
|
||||
|
|
@ -26,9 +28,11 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Support different face down types: morph/manifest and disguise/cloak
|
||||
* <p>
|
||||
* This effect lets the card be a 2/2 face-down creature, with no text, no name,
|
||||
* no subtypes, and no mana cost, if it's face down on the battlefield. And it
|
||||
* adds the a TurnFaceUpAbility ability.
|
||||
* adds the TurnFaceUpAbility and other additional abilities
|
||||
* <p>
|
||||
* Warning, if a card has multiple face down abilities then keep only one face up cost
|
||||
* Example: Mischievous Quanar
|
||||
|
|
@ -51,7 +55,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
|
||||
protected int zoneChangeCounter;
|
||||
protected Ability turnFaceUpAbility = null;
|
||||
protected List<Ability> additionalAbilities = new ArrayList<>();
|
||||
protected MageObjectReference objectReference = null;
|
||||
protected boolean foundPermanent;
|
||||
protected FaceDownType faceDownType;
|
||||
|
|
@ -76,9 +80,18 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
super(duration, Layer.CopyEffects_1, SubLayer.FaceDownEffects_1b, Outcome.BecomeCreature);
|
||||
this.objectReference = objectReference;
|
||||
this.zoneChangeCounter = Integer.MIN_VALUE;
|
||||
|
||||
// additional abilities
|
||||
// face up
|
||||
if (turnFaceUpCosts != null) {
|
||||
this.turnFaceUpAbility = new TurnFaceUpAbility(turnFaceUpCosts, faceDownType == FaceDownType.MEGAMORPHED);
|
||||
this.additionalAbilities.add(new TurnFaceUpAbility(turnFaceUpCosts, faceDownType == FaceDownType.MEGAMORPHED));
|
||||
}
|
||||
// ward
|
||||
if (faceDownType == FaceDownType.DISGUISED
|
||||
|| faceDownType == faceDownType.CLOAKED) {
|
||||
this.additionalAbilities.add(new WardAbility(new ManaCostsImpl<>("{2}")));
|
||||
}
|
||||
|
||||
staticText = "{this} becomes a 2/2 face-down creature, with no text, no name, no subtypes, and no mana cost";
|
||||
foundPermanent = false;
|
||||
this.faceDownType = faceDownType;
|
||||
|
|
@ -87,9 +100,9 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
protected BecomesFaceDownCreatureEffect(final BecomesFaceDownCreatureEffect effect) {
|
||||
super(effect);
|
||||
this.zoneChangeCounter = effect.zoneChangeCounter;
|
||||
if (effect.turnFaceUpAbility != null) {
|
||||
this.turnFaceUpAbility = effect.turnFaceUpAbility.copy();
|
||||
}
|
||||
effect.additionalAbilities.forEach(ability -> {
|
||||
this.additionalAbilities.add(ability.copy());
|
||||
});
|
||||
this.objectReference = effect.objectReference;
|
||||
this.foundPermanent = effect.foundPermanent;
|
||||
this.faceDownType = effect.faceDownType;
|
||||
|
|
@ -139,27 +152,33 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
foundPermanent = true;
|
||||
switch (faceDownType) {
|
||||
case MANIFESTED:
|
||||
case MANUAL: // sets manifested image
|
||||
case MANUAL: // sets manifested image // TODO: wtf
|
||||
permanent.setManifested(true);
|
||||
break;
|
||||
case MORPHED:
|
||||
case MEGAMORPHED:
|
||||
permanent.setMorphed(true);
|
||||
break;
|
||||
case DISGUISED:
|
||||
permanent.setDisguised(true);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("FaceDownType not yet supported: " + faceDownType);
|
||||
}
|
||||
}
|
||||
makeFaceDownObject(game, source.getSourceId(), permanent, faceDownType, this.turnFaceUpAbility);
|
||||
makeFaceDownObject(game, source.getSourceId(), permanent, faceDownType, this.additionalAbilities);
|
||||
} else if (duration == Duration.Custom && foundPermanent) {
|
||||
discard();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: implement multiple face down types?!
|
||||
public static FaceDownType findFaceDownType(Game game, Permanent permanent) {
|
||||
if (permanent.isMorphed()) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.MORPHED;
|
||||
} else if (permanent.isDisguised()) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.DISGUISED;
|
||||
} else if (permanent.isManifested()) {
|
||||
return BecomesFaceDownCreatureEffect.FaceDownType.MANIFESTED;
|
||||
} else if (permanent.isFaceDown(game)) {
|
||||
|
|
@ -172,7 +191,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
/**
|
||||
* Convert any object (card, token) to face down (remove/hide all face up information and make it a 2/2 creature)
|
||||
*/
|
||||
public static void makeFaceDownObject(Game game, UUID sourceId, MageObject object, FaceDownType faceDownType, Ability turnFaceUpAbility) {
|
||||
public static void makeFaceDownObject(Game game, UUID sourceId, MageObject object, FaceDownType faceDownType, List<Ability> additionalAbilities) {
|
||||
String originalObjectInfo = object.toString();
|
||||
|
||||
// warning, it's a direct changes to the object (without game state, so no game param here)
|
||||
|
|
@ -200,38 +219,45 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
//
|
||||
// so keep all tune face up abilities and other face down compatible
|
||||
if (ability.getWorksFaceDown()) {
|
||||
// only face up abilities hidden by default (see below), so no needs in setRuleVisible
|
||||
//ability.setRuleVisible(true);
|
||||
// keep face down abilities active, but hide it from rules description
|
||||
// example: When Dog Walker is turned face up, create two tapped 1/1 white Dog creature tokens
|
||||
ability.setRuleVisible(false);
|
||||
|
||||
// but do not hide default ability (becomes a 2/2 face-down creature)
|
||||
if (!ability.getRuleVisible() && !ability.getEffects().isEmpty()) {
|
||||
if (ability.getEffects().get(0) instanceof BecomesFaceDownCreatureEffect) {
|
||||
ability.setRuleVisible(true);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ability.getRuleVisible() && !ability.getEffects().isEmpty()) {
|
||||
if (ability.getEffects().get(0) instanceof BecomesFaceDownCreatureEffect) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// all other can be removed
|
||||
abilitiesToRemove.add(ability);
|
||||
}
|
||||
|
||||
// add face up abilities
|
||||
// TODO: add here all possible face up like morph/disguis, manifest/cloak?
|
||||
// add additional abilities like face up
|
||||
if (object instanceof Permanent) {
|
||||
// as permanent
|
||||
Permanent permanentObject = (Permanent) object;
|
||||
permanentObject.removeAbilities(abilitiesToRemove, sourceId, game);
|
||||
if (turnFaceUpAbility != null) {
|
||||
Ability faceUp = turnFaceUpAbility.copy();
|
||||
faceUp.setRuleVisible(true);
|
||||
permanentObject.addAbility(faceUp, sourceId, game);
|
||||
if (additionalAbilities != null) {
|
||||
additionalAbilities.forEach(blueprintAbility -> {
|
||||
Ability newAbility = blueprintAbility.copy();
|
||||
newAbility.setRuleVisible(true);
|
||||
permanentObject.addAbility(newAbility, sourceId, game);
|
||||
});
|
||||
}
|
||||
} else if (object instanceof CardImpl) {
|
||||
// as card
|
||||
CardImpl cardObject = (CardImpl) object;
|
||||
cardObject.getAbilities().removeAll(abilitiesToRemove);
|
||||
if (turnFaceUpAbility != null) {
|
||||
Ability faceUp = turnFaceUpAbility.copy();
|
||||
faceUp.setRuleVisible(true);
|
||||
cardObject.addAbility(faceUp);
|
||||
if (additionalAbilities != null) {
|
||||
additionalAbilities.forEach(blueprintAbility -> {
|
||||
Ability newAbility = blueprintAbility.copy();
|
||||
newAbility.setRuleVisible(true);
|
||||
cardObject.addAbility(newAbility);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -247,15 +273,15 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl {
|
|||
case MEGAMORPHED:
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH;
|
||||
break;
|
||||
case DISGUISED:
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE;
|
||||
break;
|
||||
case MANIFESTED:
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST;
|
||||
break;
|
||||
case CLOAKED:
|
||||
tokenName = "TODO-CLOAKED";
|
||||
break;
|
||||
case DISGUISED:
|
||||
tokenName = "TODO-DISGUISED";
|
||||
break;
|
||||
case MANUAL:
|
||||
tokenName = TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANUAL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,91 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.SpellAbilityCastMode;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.TimingRule;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
* TODO: Implement this
|
||||
* 702.168. Disguise
|
||||
* <p>
|
||||
* 702.168a
|
||||
* Disguise is a static ability that functions in any zone from which you could play the card it’s on,
|
||||
* and the disguise effect works any time the card is face down. “Disguise [cost]” means “You may cast this
|
||||
* card as a 2/2 face-down creature with ward {2}, no name, no subtypes, and no mana cost by paying {3} rather
|
||||
* than paying its mana cost.” (See rule 708, “Face-Down Spells and Permanents.”)
|
||||
* <p>
|
||||
* 702.168b
|
||||
* To cast a card using its disguise ability, turn the card face down and announce that you are using a disguise ability.
|
||||
* It becomes a 2/2 face-down creature card with ward {2}, no name, no subtypes, and no mana cost. Any effects or
|
||||
* prohibitions that would apply to casting a card with these characteristics (and not the face-up card’s characteristics)
|
||||
* are applied to casting this card. These values are the copiable values of that object’s characteristics.
|
||||
* (See rule 613, “Interaction of Continuous Effects,” and rule 707, “Copying Objects.”) Put it onto the stack
|
||||
* (as a face-down spell with the same characteristics), and pay {3} rather than pay its mana cost. This follows the
|
||||
* rules for paying alternative costs. You can use a disguise ability to cast a card from any zone from which you
|
||||
* could normally cast it. When the spell resolves, it enters the battlefield with the same characteristics the spell
|
||||
* had. The disguise effect applies to the face-down object wherever it is, and it ends when the permanent is turned
|
||||
* face up.
|
||||
* <p>
|
||||
* 702.168c
|
||||
* You can’t normally cast a card face down. A disguise ability allows you to do so.
|
||||
* <p>
|
||||
* 702.168d
|
||||
* Any time you have priority, you may turn a face-down permanent you control with a disguise ability face up.
|
||||
* This is a special action; it doesn’t use the stack (see rule 116). To do this, show all players what the
|
||||
* permanent’s disguise cost would be if it were face up, pay that cost, then turn the permanent face up.
|
||||
* (If the permanent wouldn’t have a disguise cost if it were face up, it can’t be turned face up this way.)
|
||||
* The disguise effect on it ends, and it regains its normal characteristics. Any abilities relating to the
|
||||
* permanent entering the battlefield don’t trigger when it’s turned face up and don’t have any effect,
|
||||
* because the permanent has already entered the battlefield.
|
||||
* <p>
|
||||
* 702.168e
|
||||
* If a permanent’s disguise cost includes X, other abilities of that permanent may also refer to X.
|
||||
* The value of X in those abilities is equal to the value of X chosen as the disguise special action was taken.
|
||||
* <p>
|
||||
* 702.168f
|
||||
* See rule 708, “Face-Down Spells and Permanents,” for more information about how to cast cards with a disguise ability.
|
||||
* <p>
|
||||
* <p>
|
||||
* MorphAbility as a reference implementation
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class DisguiseAbility extends SpellAbility {
|
||||
|
||||
protected static final String ABILITY_KEYWORD = "Disguise";
|
||||
protected static final String REMINDER_TEXT = "You may cast this card face down for {3} as a 2/2 creature with "
|
||||
+ "ward {2}. Turn it face up any time for its disguise cost.";
|
||||
|
||||
protected Costs<Cost> disguiseCosts;
|
||||
|
||||
public DisguiseAbility(Card card, Cost disguiseCost) {
|
||||
super(new GenericManaCost(3), card.getName());
|
||||
this.timing = TimingRule.SORCERY;
|
||||
this.disguiseCosts = new CostsImpl<>();
|
||||
this.disguiseCosts.add(disguiseCost);
|
||||
this.setSpellAbilityCastMode(SpellAbilityCastMode.DISGUISE);
|
||||
this.setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE);
|
||||
|
||||
// face down effect (hidden by default, visible in face down objects)
|
||||
Ability ability = new SimpleStaticAbility(new BecomesFaceDownCreatureEffect(
|
||||
this.disguiseCosts, BecomesFaceDownCreatureEffect.FaceDownType.DISGUISED));
|
||||
ability.setWorksFaceDown(true);
|
||||
ability.setRuleVisible(false);
|
||||
addSubAbility(ability);
|
||||
}
|
||||
|
||||
private DisguiseAbility(final DisguiseAbility ability) {
|
||||
super(ability);
|
||||
this.disguiseCosts = ability.disguiseCosts; // can't be changed TODO: looks buggy, need research
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -24,8 +93,16 @@ public class DisguiseAbility extends SpellAbility {
|
|||
return new DisguiseAbility(this);
|
||||
}
|
||||
|
||||
public Costs<Cost> getFaceUpCosts() {
|
||||
return this.disguiseCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Disguise";
|
||||
boolean isMana = disguiseCosts.get(0) instanceof ManaCost;
|
||||
return ABILITY_KEYWORD + (isMana ? " " : "—")
|
||||
+ this.disguiseCosts.getText()
|
||||
+ (isMana ? ' ' : ". ")
|
||||
+ " <i>(" + REMINDER_TEXT + ")</i>";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public class MorphAbility extends SpellAbility {
|
|||
|
||||
// face down effect (hidden by default, visible in face down objects)
|
||||
Ability ability = new SimpleStaticAbility(new BecomesFaceDownCreatureEffect(
|
||||
morphCosts, (useMegamorph ? FaceDownType.MEGAMORPHED : FaceDownType.MORPHED)));
|
||||
this.morphCosts, (useMegamorph ? FaceDownType.MEGAMORPHED : FaceDownType.MORPHED)));
|
||||
ability.setWorksFaceDown(true);
|
||||
ability.setRuleVisible(false);
|
||||
addSubAbility(ability);
|
||||
|
|
@ -92,7 +92,7 @@ public class MorphAbility extends SpellAbility {
|
|||
|
||||
protected MorphAbility(final MorphAbility ability) {
|
||||
super(ability);
|
||||
this.morphCosts = ability.morphCosts; // can't be changed
|
||||
this.morphCosts = ability.morphCosts; // can't be changed TODO: looks buggy, need research
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -100,8 +100,8 @@ public class MorphAbility extends SpellAbility {
|
|||
return new MorphAbility(this);
|
||||
}
|
||||
|
||||
public Costs<Cost> getMorphCosts() {
|
||||
return morphCosts;
|
||||
public Costs<Cost> getFaceUpCosts() {
|
||||
return this.morphCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public interface Card extends MageObject, Ownerable {
|
|||
|
||||
boolean turnFaceUp(Ability source, Game game, UUID playerId);
|
||||
|
||||
// TODO: need research, is it lost morph and other face down statuses?
|
||||
boolean turnFaceDown(Ability source, Game game, UUID playerId);
|
||||
|
||||
boolean isFlipCard();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public enum TokenRepository {
|
|||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST = "Manifest";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MORPH = "Morph";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH = "Megamorph";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE = "Disguise";
|
||||
public static final String XMAGE_IMAGE_NAME_FACE_DOWN_FORETELL = "Foretell";
|
||||
public static final String XMAGE_IMAGE_NAME_COPY = "Copy";
|
||||
public static final String XMAGE_IMAGE_NAME_CITY_BLESSING = "City's Blessing";
|
||||
|
|
@ -288,6 +289,10 @@ public enum TokenRepository {
|
|||
res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH, 2, "https://api.scryfall.com/cards/ta25/15/en?format=image"));
|
||||
res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_MEGAMORPH, 3, "https://api.scryfall.com/cards/tc19/27/en?format=image"));
|
||||
|
||||
// Disguise
|
||||
// support only 1 image: https://scryfall.com/card/tmkm/21/a-mysterious-creature
|
||||
res.add(createXmageToken(XMAGE_IMAGE_NAME_FACE_DOWN_DISGUISE, 1, "https://api.scryfall.com/cards/tmkm/21/en?format=image"));
|
||||
|
||||
// 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"));
|
||||
|
|
|
|||
|
|
@ -22,12 +22,15 @@ public enum SpellAbilityCastMode {
|
|||
PROTOTYPE("Prototype"),
|
||||
MORPH("Morph", false, true, SpellAbilityCastMode.MORPH_ADDITIONAL_RULE),
|
||||
MEGAMORPH("Megamorph", false, true, SpellAbilityCastMode.MORPH_ADDITIONAL_RULE),
|
||||
DISGUISE("Disguise", false, true, SpellAbilityCastMode.DISGUISE_ADDITIONAL_RULE),
|
||||
TRANSFORMED("Transformed", true),
|
||||
DISTURB("Disturb", true),
|
||||
MORE_THAN_MEETS_THE_EYE("More than Meets the Eye", true);
|
||||
|
||||
private static final String MORPH_ADDITIONAL_RULE = "You may cast this card as a 2/2 face-down creature, with no text,"
|
||||
+ " no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost.";
|
||||
private static final String DISGUISE_ADDITIONAL_RULE = "You may cast this card face down for {3} as a 2/2 creature with "
|
||||
+ "ward {2}. Turn it face up any time for its disguise cost.";
|
||||
|
||||
private final String text;
|
||||
|
||||
|
|
@ -90,12 +93,18 @@ public enum SpellAbilityCastMode {
|
|||
break;
|
||||
case MORPH:
|
||||
case MEGAMORPH:
|
||||
case DISGUISE:
|
||||
if (cardCopy instanceof Spell) {
|
||||
//Spell doesn't support setName, so make a copy of the card (we're blowing it away anyway)
|
||||
// TODO: research - is it possible to apply face down code to spell instead workaround with card
|
||||
cardCopy = ((Spell) cardCopy).getCard().copy();
|
||||
}
|
||||
BecomesFaceDownCreatureEffect.makeFaceDownObject(game, null, cardCopy, BecomesFaceDownCreatureEffect.FaceDownType.MORPHED, null);
|
||||
BecomesFaceDownCreatureEffect.FaceDownType faceDownType = BecomesFaceDownCreatureEffect.FaceDownType.MORPHED;
|
||||
if (this == DISGUISE) {
|
||||
faceDownType = BecomesFaceDownCreatureEffect.FaceDownType.DISGUISED;
|
||||
}
|
||||
// no needs in additional abilities for spell
|
||||
BecomesFaceDownCreatureEffect.makeFaceDownObject(game, null, cardCopy, faceDownType, null);
|
||||
break;
|
||||
case NORMAL:
|
||||
case MADNESS:
|
||||
|
|
|
|||
|
|
@ -442,6 +442,10 @@ public interface Permanent extends Card, Controllable {
|
|||
|
||||
boolean isMorphed();
|
||||
|
||||
void setDisguised(boolean value);
|
||||
|
||||
boolean isDisguised();
|
||||
|
||||
void setManifested(boolean value);
|
||||
|
||||
boolean isManifested();
|
||||
|
|
|
|||
|
|
@ -176,10 +176,12 @@ public class PermanentCard extends PermanentImpl {
|
|||
@Override
|
||||
public boolean turnFaceUp(Ability source, Game game, UUID playerId) {
|
||||
if (super.turnFaceUp(source, game, playerId)) {
|
||||
// TODO: miss types, abilities, color and other things for restore?!
|
||||
power.setModifiedBaseValue(power.getBaseValue());
|
||||
toughness.setModifiedBaseValue(toughness.getBaseValue());
|
||||
setManifested(false);
|
||||
setMorphed(false);
|
||||
setDisguised(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
protected boolean suspected;
|
||||
protected boolean manifested = false;
|
||||
protected boolean morphed = false;
|
||||
protected boolean disguised = false;
|
||||
protected boolean ringBearerFlag = false;
|
||||
protected boolean canBeSacrificed = true;
|
||||
protected int classLevel = 1;
|
||||
|
|
@ -186,6 +187,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
this.protectorId = permanent.protectorId;
|
||||
|
||||
this.morphed = permanent.morphed;
|
||||
this.disguised = permanent.disguised;
|
||||
this.manifested = permanent.manifested;
|
||||
this.createOrder = permanent.createOrder;
|
||||
this.prototyped = permanent.prototyped;
|
||||
|
|
@ -1908,6 +1910,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
morphed = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisguised() {
|
||||
return disguised;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisguised(boolean value) {
|
||||
disguised = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRarity(Rarity rarity) {
|
||||
this.rarity = rarity;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class CopyTokenFunction {
|
|||
if (source instanceof PermanentCard) {
|
||||
// create token from non-token permanent
|
||||
|
||||
// morph/manifest must hide all info
|
||||
// face down must hide all info
|
||||
PermanentCard sourcePermanent = (PermanentCard) source;
|
||||
BecomesFaceDownCreatureEffect.FaceDownType faceDownType = BecomesFaceDownCreatureEffect.findFaceDownType(game, sourcePermanent);
|
||||
if (faceDownType != null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue