mirror of
https://github.com/correl/mage.git
synced 2024-11-14 19:19:32 +00:00
Tokens rework: fixed morph support, fixed test (related to #10139)
This commit is contained in:
parent
94819ff91c
commit
3986196aa4
6 changed files with 110 additions and 66 deletions
|
@ -12,10 +12,13 @@ import mage.abilities.costs.mana.GenericManaCost;
|
|||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect.FaceDownType;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.EmptyToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
|
@ -134,24 +137,40 @@ public class MorphAbility extends AlternativeSourceCostsImpl {
|
|||
morphCosts.getText() + (isMana ? ' ' : ". ") + alternativeCost.getReminderText();
|
||||
}
|
||||
|
||||
public static void setPermanentToFaceDownCreature(MageObject mageObject, Game game) {
|
||||
mageObject.getPower().setModifiedBaseValue(2);
|
||||
mageObject.getToughness().setModifiedBaseValue(2);
|
||||
mageObject.getAbilities().clear();
|
||||
mageObject.getColor(game).setColor(new ObjectColor());
|
||||
mageObject.setName("");
|
||||
mageObject.removeAllCardTypes(game);
|
||||
mageObject.addCardType(game, CardType.CREATURE);
|
||||
mageObject.removeAllSubTypes(game);
|
||||
mageObject.getSuperType().clear();
|
||||
mageObject.getManaCost().clear();
|
||||
/**
|
||||
* Hide all info and make it a 2/2 creature
|
||||
*
|
||||
* @param targetObject
|
||||
* @param sourcePermanent source of the face down status
|
||||
* @param game
|
||||
*/
|
||||
public static void setPermanentToFaceDownCreature(MageObject targetObject, Permanent sourcePermanent, Game game) {
|
||||
targetObject.getPower().setModifiedBaseValue(2);
|
||||
targetObject.getToughness().setModifiedBaseValue(2);
|
||||
targetObject.getAbilities().clear();
|
||||
targetObject.getColor(game).setColor(new ObjectColor());
|
||||
targetObject.setName("");
|
||||
targetObject.removeAllCardTypes(game);
|
||||
targetObject.addCardType(game, CardType.CREATURE);
|
||||
targetObject.removeAllSubTypes(game);
|
||||
targetObject.getSuperType().clear();
|
||||
targetObject.getManaCost().clear();
|
||||
|
||||
Token emptyImage = new EmptyToken();
|
||||
emptyImage.setOriginalExpansionSetCode("");
|
||||
emptyImage.setExpansionSetCodeForImage("");
|
||||
emptyImage.setOriginalCardNumber("");
|
||||
|
||||
// TODO: add morph image here?
|
||||
if (mageObject instanceof Permanent) {
|
||||
if (targetObject instanceof Permanent) {
|
||||
// hide image info
|
||||
CardUtil.copySetAndCardNumber((Permanent) mageObject, "", "", 0);
|
||||
CardUtil.copySetAndCardNumber(targetObject, emptyImage);
|
||||
// hide rarity info
|
||||
((Permanent) mageObject).setRarity(Rarity.SPECIAL);
|
||||
((Permanent) targetObject).setRarity(Rarity.SPECIAL);
|
||||
} else if (targetObject instanceof Token) {
|
||||
CardUtil.copySetAndCardNumber(targetObject, emptyImage);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Wrong code usage: un-supported targetObject in face down method: " + targetObject.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1912,9 +1912,10 @@ public abstract class GameImpl implements Game {
|
|||
newBluePrint.reset(this);
|
||||
|
||||
//getState().addCard(permanent);
|
||||
if (copyFromPermanent.isMorphed() || copyFromPermanent.isManifested()
|
||||
if (copyFromPermanent.isMorphed()
|
||||
|| copyFromPermanent.isManifested()
|
||||
|| copyFromPermanent.isFaceDown(this)) {
|
||||
MorphAbility.setPermanentToFaceDownCreature(newBluePrint, this);
|
||||
MorphAbility.setPermanentToFaceDownCreature(newBluePrint, copyFromPermanent, this);
|
||||
}
|
||||
newBluePrint.assignNewId();
|
||||
if (copyFromPermanent.isTransformed()) {
|
||||
|
|
|
@ -1185,9 +1185,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
@Override
|
||||
public boolean entersBattlefield(Ability source, Game game, Zone fromZone, boolean fireEvent) {
|
||||
controlledFromStartOfControllerTurn = false;
|
||||
if (this.isFaceDown(game)) {
|
||||
if (this.isFaceDown(game)) { // ?? add morphed/manifested here ??
|
||||
// remove some attributes here, because first apply effects comes later otherwise abilities (e.g. color related) will unintended trigger
|
||||
MorphAbility.setPermanentToFaceDownCreature(this, game);
|
||||
MorphAbility.setPermanentToFaceDownCreature(this, this, game);
|
||||
}
|
||||
|
||||
if (game.replaceEvent(new EntersTheBattlefieldEvent(this, source, getControllerId(), fromZone, EnterEventType.SELF))) {
|
||||
|
|
|
@ -19,6 +19,8 @@ import java.util.UUID;
|
|||
*/
|
||||
public class PermanentToken extends PermanentImpl {
|
||||
|
||||
// non-modifyable container with token characteristics
|
||||
// this PermanentToken resets to it on each game cycle
|
||||
protected Token token;
|
||||
|
||||
public PermanentToken(Token token, UUID controllerId, Game game) {
|
||||
|
|
|
@ -1789,7 +1789,7 @@ public final class CardUtil {
|
|||
* Copy image related data from one object to another (card number, set code, token type)
|
||||
* Use it in copy/transform effects
|
||||
*/
|
||||
public static void copySetAndCardNumber(Permanent permanent, MageObject copyFromObject) {
|
||||
public static void copySetAndCardNumber(MageObject targetObject, MageObject copyFromObject) {
|
||||
String needSetCode;
|
||||
String needCardNumber;
|
||||
int needTokenType;
|
||||
|
@ -1810,23 +1810,37 @@ public final class CardUtil {
|
|||
needCardNumber = ((Card) copyFromObject).getCardNumber();
|
||||
needTokenType = 0;
|
||||
} else if (copyFromObject instanceof Token) {
|
||||
// TODO: make this work
|
||||
return;
|
||||
needSetCode = ((Token) copyFromObject).getOriginalExpansionSetCode();
|
||||
needCardNumber = ((Token) copyFromObject).getOriginalCardNumber();
|
||||
needTokenType = ((Token) copyFromObject).getTokenType();
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported copyFromObject class: " + copyFromObject.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
copySetAndCardNumber(permanent, needSetCode, needCardNumber, needTokenType);
|
||||
}
|
||||
|
||||
public static void copySetAndCardNumber(Permanent permanent, String newSetCode, String newCardNumber, Integer newTokenType) {
|
||||
if (permanent instanceof PermanentToken) {
|
||||
((PermanentToken) permanent).getToken().setOriginalExpansionSetCode(newSetCode);
|
||||
((PermanentToken) permanent).getToken().setExpansionSetCodeForImage(newCardNumber);
|
||||
((PermanentToken) permanent).getToken().setTokenType(newTokenType);
|
||||
if (targetObject instanceof Permanent) {
|
||||
copySetAndCardNumber((Permanent) targetObject, needSetCode, needCardNumber, needTokenType);
|
||||
} else if (targetObject instanceof Token) {
|
||||
copySetAndCardNumber((Token) targetObject, needSetCode, needCardNumber, needTokenType);
|
||||
} else {
|
||||
permanent.setExpansionSetCode(newSetCode);
|
||||
permanent.setCardNumber(newCardNumber);
|
||||
throw new IllegalStateException("Unsupported target object class: " + targetObject.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void copySetAndCardNumber(Permanent targetPermanent, String newSetCode, String newCardNumber, Integer newTokenType) {
|
||||
if (targetPermanent instanceof PermanentToken) {
|
||||
copySetAndCardNumber(((PermanentToken) targetPermanent).getToken(), newSetCode, newCardNumber, newTokenType);
|
||||
} else if (targetPermanent instanceof PermanentCard) {
|
||||
targetPermanent.setExpansionSetCode(newSetCode);
|
||||
targetPermanent.setCardNumber(newCardNumber);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Wrong code usage: un-supported target permanent type: " + targetPermanent.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void copySetAndCardNumber(Token targetToken, String newSetCode, String newCardNumber, Integer newTokenType) {
|
||||
targetToken.setOriginalExpansionSetCode(newSetCode);
|
||||
targetToken.setExpansionSetCodeForImage(newSetCode);
|
||||
targetToken.setOriginalCardNumber(newCardNumber);
|
||||
targetToken.setTokenType(newTokenType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import mage.game.permanent.PermanentToken;
|
|||
import mage.game.permanent.token.EmptyToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
|
@ -44,59 +45,68 @@ public class CopyTokenFunction {
|
|||
// else gained abililies would be copied too.
|
||||
target.setEntersTransformed(source instanceof Permanent && ((Permanent) source).isTransformed());
|
||||
MageObject sourceObj;
|
||||
|
||||
// from another token
|
||||
if (source instanceof PermanentToken) {
|
||||
// create token from another token
|
||||
Token sourceToken = ((PermanentToken) source).getToken();
|
||||
sourceObj = sourceToken;
|
||||
copyToToken(target, sourceObj, game);
|
||||
if (sourceToken.getBackFace() != null) {
|
||||
target.getBackFace().setOriginalExpansionSetCode(sourceToken.getOriginalExpansionSetCode());
|
||||
target.getBackFace().setOriginalCardNumber(sourceToken.getOriginalCardNumber());
|
||||
target.getBackFace().setCopySourceCard(sourceToken.getBackFace().getCopySourceCard());
|
||||
copyToToken(target.getBackFace(), sourceToken.getBackFace(), game);
|
||||
}
|
||||
// to show the source image, the original values have to be used
|
||||
target.setOriginalExpansionSetCode(sourceToken.getOriginalExpansionSetCode());
|
||||
target.setOriginalCardNumber(sourceToken.getOriginalCardNumber());
|
||||
target.setCopySourceCard(((PermanentToken) source).getToken().getCopySourceCard());
|
||||
|
||||
copyToToken(target, sourceObj, game);
|
||||
CardUtil.copySetAndCardNumber(target, source);
|
||||
if (sourceToken.getBackFace() != null) {
|
||||
copyToToken(target.getBackFace(), sourceToken.getBackFace(), game);
|
||||
CardUtil.copySetAndCardNumber(target.getBackFace(), sourceToken.getBackFace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// from a permanent
|
||||
if (source instanceof PermanentCard) {
|
||||
// create token from non-token permanent
|
||||
if (((PermanentCard) source).isMorphed() || ((PermanentCard) source).isManifested()) {
|
||||
MorphAbility.setPermanentToFaceDownCreature(target, game);
|
||||
|
||||
// morph/manifest must hide all info
|
||||
if (((PermanentCard) source).isMorphed()
|
||||
|| ((PermanentCard) source).isManifested()
|
||||
|| source.isFaceDown(game)) {
|
||||
MorphAbility.setPermanentToFaceDownCreature(target, (PermanentCard) source, game);
|
||||
return;
|
||||
}
|
||||
sourceObj = ((PermanentCard) source).getMainCard();
|
||||
copyToToken(target, sourceObj, game);
|
||||
if (((Card) sourceObj).isTransformable()) {
|
||||
target.getBackFace().setOriginalExpansionSetCode(source.getExpansionSetCode());
|
||||
target.getBackFace().setOriginalCardNumber(source.getCardNumber());
|
||||
target.getBackFace().setCopySourceCard(((Card) sourceObj).getSecondCardFace());
|
||||
copyToToken(target.getBackFace(), ((Card) sourceObj).getSecondCardFace(), game);
|
||||
}
|
||||
|
||||
target.setOriginalExpansionSetCode(source.getExpansionSetCode());
|
||||
target.setOriginalCardNumber(source.getCardNumber());
|
||||
sourceObj = source.getMainCard();
|
||||
target.setCopySourceCard((Card) sourceObj);
|
||||
|
||||
copyToToken(target, sourceObj, game);
|
||||
CardUtil.copySetAndCardNumber(target, sourceObj);
|
||||
if (((Card) sourceObj).isTransformable()) {
|
||||
copyToToken(target.getBackFace(), ((Card) sourceObj).getSecondCardFace(), game);
|
||||
CardUtil.copySetAndCardNumber(target.getBackFace(), ((Card) sourceObj).getSecondCardFace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// from another object like card (example: Embalm ability)
|
||||
sourceObj = source;
|
||||
copyToToken(target, sourceObj, game);
|
||||
if (source.isTransformable()) {
|
||||
target.getBackFace().setOriginalExpansionSetCode(source.getExpansionSetCode());
|
||||
target.getBackFace().setOriginalCardNumber(source.getCardNumber());
|
||||
target.getBackFace().setCopySourceCard(source.getSecondCardFace());
|
||||
copyToToken(target.getBackFace(), source.getSecondCardFace(), game);
|
||||
}
|
||||
// create token from non-permanent object like card (example: Embalm ability)
|
||||
target.setOriginalExpansionSetCode(source.getExpansionSetCode());
|
||||
target.setOriginalCardNumber(source.getCardNumber());
|
||||
target.setCopySourceCard(source);
|
||||
|
||||
copyToToken(target, sourceObj, game);
|
||||
CardUtil.copySetAndCardNumber(target, sourceObj);
|
||||
if (source.isTransformable()) {
|
||||
if (target.getBackFace() == null) {
|
||||
// if you catch this then a weird use case here: card with single face copy another token with double face??
|
||||
// must create back face??
|
||||
throw new IllegalStateException("Wrong code usage: back face must be non null: " + target.getName() + " - " + target.getClass().getSimpleName());
|
||||
}
|
||||
copyToToken(target.getBackFace(), source.getSecondCardFace(), game);
|
||||
CardUtil.copySetAndCardNumber(target.getBackFace(), source.getSecondCardFace());
|
||||
}
|
||||
}
|
||||
|
||||
private static Token copyToToken(Token target, MageObject sourceObj, Game game) {
|
||||
private static void copyToToken(Token target, MageObject sourceObj, Game game) {
|
||||
// modify all attributes permanently (without game usage)
|
||||
// ignore images settings here, it will be setup later due needs in face down
|
||||
// (after copy or after put to battlefield)
|
||||
target.setName(sourceObj.getName());
|
||||
target.getColor().setColor(sourceObj.getColor());
|
||||
target.getManaCost().clear();
|
||||
|
@ -128,8 +138,6 @@ public class CopyTokenFunction {
|
|||
target.setToughness(sourceObj.getToughness().getBaseValue());
|
||||
target.setStartingLoyalty(sourceObj.getStartingLoyalty());
|
||||
target.setStartingDefense(sourceObj.getStartingDefense());
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
private Token from(Card source, Game game, Spell spell) {
|
||||
|
|
Loading…
Reference in a new issue