Transform: all DFC can transform now

This commit is contained in:
Hans Mackowiak
2025-09-20 14:32:30 +02:00
parent ea293a46b1
commit 90bd0c73d0
8 changed files with 18 additions and 59 deletions

View File

@@ -168,21 +168,7 @@ public final class CardRules implements ICardCharacteristics {
}
public boolean isTransformable() {
if (CardSplitType.Transform == getSplitType()) {
return true;
}
if (CardSplitType.Modal != getSplitType()) {
return false;
}
for (ICardFace face : getAllFaces()) {
for (String spell : face.getAbilities()) {
if (spell.contains("AB$ SetState") && spell.contains("Mode$ Transform")) {
return true;
}
}
// TODO check keywords if needed
}
return false;
return CardSplitType.Transform == getSplitType() || CardSplitType.Modal == getSplitType();
}
public ICardFace getWSpecialize() {

View File

@@ -156,7 +156,7 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard {
return false;
CardSplitType cst = this.cardRules.getSplitType();
//expand this on future for other tokens that has other backsides besides transform..
return cst == CardSplitType.Transform;
return cst == CardSplitType.Transform || cst == CardSplitType.Modal;
}
@Override

View File

@@ -220,10 +220,6 @@ public class GameAction {
//copied.setGamePieceType(GamePieceType.COPIED_SPELL);
}
if (c.isTransformed()) {
copied.incrementTransformedTimestamp();
}
if (cause != null && cause.isSpell() && c.equals(cause.getHostCard())) {
copied.setCastSA(cause);
copied.setSplitStateToPlayAbility(cause);

View File

@@ -993,9 +993,6 @@ public final class GameActionUtil {
oldCard.setBackSide(false);
oldCard.setState(oldCard.getFaceupCardStateName(), true);
oldCard.unanimateBestow();
if (ability.isDisturb() || ability.hasParam("CastTransformed")) {
oldCard.undoIncrementTransformedTimestamp();
}
if (ability.hasParam("Prototype")) {
oldCard.removeCloneState(oldCard.getPrototypeTimestamp());

View File

@@ -287,22 +287,17 @@ public class CopyPermanentEffect extends TokenEffectBase {
int id = newOwner == null ? 0 : newOwner.getGame().nextCardId();
// need to create a physical card first, i need the original card faces
copy = CardFactory.getCard(original.getPaperCard(), newOwner, id, host.getGame());
copy.setStates(CardFactory.getCloneStates(original, copy, sa));
// force update the now set State
if (original.isTransformable()) {
copy.setState(original.isTransformed() ? CardStateName.Backside : CardStateName.Original, true, true);
// 707.8a If an effect creates a token that is a copy of a transforming permanent or a transforming double-faced card not on the battlefield,
// the resulting token is a transforming token that has both a front face and a back face.
// The characteristics of each face are determined by the copiable values of the same face of the permanent it is a copy of, as modified by any other copy effects that apply to that permanent.
// If the token is a copy of a transforming permanent with its back face up, the token enters the battlefield with its back face up.
// This rule does not apply to tokens that are created with their own set of characteristics and enter the battlefield as a copy of a transforming permanent due to a replacement effect.
copy.setBackSide(original.isBackSide());
if (original.isTransformed()) {
copy.incrementTransformedTimestamp();
}
}
copy.setStates(CardFactory.getCloneStates(original, copy, sa));
// force update the now set State
if (original.isTransformable()) {
copy.setState(original.isTransformed() ? CardStateName.Backside : CardStateName.Original, true, true);
} else {
copy.setState(copy.getCurrentStateName(), true, true);
}

View File

@@ -257,7 +257,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
private long worldTimestamp = -1;
private long bestowTimestamp = -1;
private long transformedTimestamp = 0;
private long transformedTimestamp = -1;
private long prototypeTimestamp = -1;
private long mutatedTimestamp = -1;
private int timesMutated = 0;
@@ -425,8 +425,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
public long getPrototypeTimestamp() { return prototypeTimestamp; }
public long getTransformedTimestamp() { return transformedTimestamp; }
public void incrementTransformedTimestamp() { this.transformedTimestamp++; }
public void undoIncrementTransformedTimestamp() { this.transformedTimestamp--; }
public void setTransformedTimestamp(long ts) { this.transformedTimestamp = ts; }
// The following methods are used to selectively update certain view components (text,
// P/T, card types) in order to avoid card flickering due to aggressive full update
@@ -696,7 +695,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(this);
getGame().getTriggerHandler().runTrigger(TriggerType.Transformed, runParams, false);
}
incrementTransformedTimestamp();
setTransformedTimestamp(ts);
return retResult;
} else if (mode.equals("Flip")) {
@@ -1070,7 +1069,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
}
public final boolean isDoubleFaced() {
return isTransformable() || isMeldable() || isModal();
return isTransformable() || isMeldable();
}
public final boolean isFlipCard() {
@@ -1132,7 +1131,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
}
public final boolean isTransformed() {
return getTransformedTimestamp() != 0;
if (isMeldable() || hasMergedCard()) {
return false;
}
return this.isTransformable() && isBackSide();
}
public final boolean isFlipped() {
@@ -7638,9 +7640,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
if (sa.isBestow()) {
animateBestow();
}
if (sa.isDisturb() || sa.hasParam("CastTransformed")) {
incrementTransformedTimestamp();
}
if (sa.hasParam("Prototype") && prototypeTimestamp == -1) {
long next = game.getNextTimestamp();
addCloneState(CardFactory.getCloneStates(this, this, sa), next);

View File

@@ -131,9 +131,7 @@ public class CardCopyService {
c.setState(in.getCurrentStateName(), false);
c.setRules(in.getRules());
if (in.isTransformed()) {
c.incrementTransformedTimestamp();
}
c.setBackSide(in.isBackSide());
return c;
}
@@ -168,9 +166,6 @@ public class CardCopyService {
// The characteristics of its front and back face are determined by the copiable values of the same face of the spell it is a copy of, as modified by any other copy effects.
// If the spell it is a copy of has its back face up, the copy is created with its back face up. The token thats put onto the battlefield as that spell resolves is a transforming token.
to.setBackSide(copyFrom.isBackSide());
if (copyFrom.isTransformed()) {
to.incrementTransformedTimestamp();
}
} else if (fromIsTransformedCard) {
copyState(copyFrom, copyFrom.getCurrentStateName(), to, CardStateName.Original);
} else {
@@ -274,9 +269,6 @@ public class CardCopyService {
}
newCopy.setFlipped(copyFrom.isFlipped());
newCopy.setBackSide(copyFrom.isBackSide());
if (copyFrom.isTransformed()) {
newCopy.incrementTransformedTimestamp();
}
if (newCopy.hasAlternateState()) {
newCopy.setState(copyFrom.getCurrentStateName(), false, true);
}

View File

@@ -87,22 +87,16 @@ public class CardFactory {
// need to create a physical card first, i need the original card faces
final Card copy = getCard(original.getPaperCard(), controller, id, game);
copy.setStates(getCloneStates(original, copy, sourceSA));
// force update the now set State
if (original.isTransformable()) {
copy.setState(original.isTransformed() ? CardStateName.Backside : CardStateName.Original, true, true);
// 707.8a If an effect creates a token that is a copy of a transforming permanent or a transforming double-faced card not on the battlefield,
// the resulting token is a transforming token that has both a front face and a back face.
// The characteristics of each face are determined by the copiable values of the same face of the permanent it is a copy of, as modified by any other copy effects that apply to that permanent.
// If the token is a copy of a transforming permanent with its back face up, the token enters the battlefield with its back face up.
// This rule does not apply to tokens that are created with their own set of characteristics and enter the battlefield as a copy of a transforming permanent due to a replacement effect.
copy.setBackSide(original.isBackSide());
if (original.isTransformed()) {
copy.incrementTransformedTimestamp();
}
}
copy.setStates(getCloneStates(original, copy, sourceSA));
// force update the now set State
if (original.isTransformable()) {
copy.setState(original.isTransformed() ? CardStateName.Backside : CardStateName.Original, true, true);
} else {
copy.setState(copy.getCurrentStateName(), true, true);
}