mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
LKICopy Transform and flip (#3146)
* LKICopy Transform and flip * Update CardUtil.java Fix newCopy state when flipped or transformed * Update CardUtil.java fix backside * Update CardUtil.java add EffectSource * CardStateName.Transformed needs to be copied * Fixes #3201 somewhat * Fix CardState for Fused Spells * GameSimulationTest: Add Ratadrabik + TDFC token test
This commit is contained in:
@@ -511,6 +511,7 @@ public final class AbilityFactory {
|
||||
totalCost.add(parseAbilityCost(rightState, rightMap, rightType));
|
||||
|
||||
final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, leftState, leftState);
|
||||
left.setCardState(card.getState(CardStateName.Original));
|
||||
final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, rightState, rightState);
|
||||
left.appendSubAbility(right);
|
||||
return left;
|
||||
|
||||
@@ -753,6 +753,19 @@ public class CardFactory {
|
||||
final CardState ret2 = new CardState(out, CardStateName.Transformed);
|
||||
ret2.copyFrom(in.getState(CardStateName.Transformed), false, sa);
|
||||
result.put(CardStateName.Transformed, ret2);
|
||||
} else if (in.isSplitCard()) {
|
||||
// for split cards, copy all three states
|
||||
final CardState ret1 = new CardState(out, CardStateName.Original);
|
||||
ret1.copyFrom(in.getState(CardStateName.Original), false, sa);
|
||||
result.put(CardStateName.Original, ret1);
|
||||
|
||||
final CardState ret2 = new CardState(out, CardStateName.LeftSplit);
|
||||
ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, sa);
|
||||
result.put(CardStateName.LeftSplit, ret2);
|
||||
|
||||
final CardState ret3 = new CardState(out, CardStateName.RightSplit);
|
||||
ret3.copyFrom(in.getState(CardStateName.RightSplit), false, sa);
|
||||
result.put(CardStateName.RightSplit, ret3);
|
||||
} else {
|
||||
// in all other cases just copy the current state to original
|
||||
final CardState ret = new CardState(out, CardStateName.Original);
|
||||
|
||||
@@ -194,24 +194,49 @@ public final class CardUtil {
|
||||
newCopy.setController(in.getController(), 0);
|
||||
newCopy.setCommander(in.isCommander());
|
||||
|
||||
newCopy.setRules(in.getRules());
|
||||
|
||||
// needed to ensure that the LKI object has correct CMC info no matter what state the original card was in
|
||||
// (e.g. Scrap Trawler + transformed Harvest Hand)
|
||||
newCopy.setLKICMC(in.getCMC());
|
||||
// used for the purpose of cards that care about the zone the card was known to be in last
|
||||
newCopy.setLastKnownZone(in.getLastKnownZone());
|
||||
// copy EffectSource for description
|
||||
newCopy.setEffectSource(getLKICopy(in.getEffectSource(), cachedMap));
|
||||
|
||||
newCopy.getCurrentState().copyFrom(in.getState(in.getFaceupCardStateName()), true);
|
||||
if (in.isFlipCard()) {
|
||||
newCopy.getState(CardStateName.Original).copyFrom(in.getState(CardStateName.Original), true);
|
||||
newCopy.addAlternateState(CardStateName.Flipped, false);
|
||||
newCopy.getState(CardStateName.Flipped).copyFrom(in.getState(CardStateName.Flipped), true);
|
||||
} else if (in.isTransformable()) {
|
||||
newCopy.getState(CardStateName.Original).copyFrom(in.getState(CardStateName.Original), true);
|
||||
newCopy.addAlternateState(CardStateName.Transformed, false);
|
||||
newCopy.getState(CardStateName.Transformed).copyFrom(in.getState(CardStateName.Transformed), true);
|
||||
} else if (in.isAdventureCard()) {
|
||||
newCopy.getState(CardStateName.Original).copyFrom(in.getState(CardStateName.Original), true);
|
||||
newCopy.addAlternateState(CardStateName.Adventure, false);
|
||||
newCopy.getState(CardStateName.Adventure).copyFrom(in.getState(CardStateName.Adventure), true);
|
||||
} else if (in.isSplitCard()) {
|
||||
newCopy.getState(CardStateName.Original).copyFrom(in.getState(CardStateName.Original), true);
|
||||
newCopy.addAlternateState(CardStateName.LeftSplit, false);
|
||||
newCopy.getState(CardStateName.LeftSplit).copyFrom(in.getState(CardStateName.LeftSplit), true);
|
||||
newCopy.addAlternateState(CardStateName.RightSplit, false);
|
||||
newCopy.getState(CardStateName.RightSplit).copyFrom(in.getState(CardStateName.RightSplit), true);
|
||||
} else {
|
||||
newCopy.getCurrentState().copyFrom(in.getState(in.getFaceupCardStateName()), true);
|
||||
}
|
||||
newCopy.setFlipped(in.isFlipped());
|
||||
newCopy.setBackSide(in.isBackSide());
|
||||
if (in.isTransformed()) {
|
||||
newCopy.incrementTransformedTimestamp();
|
||||
}
|
||||
newCopy.setState(newCopy.getFaceupCardStateName(), false, true);
|
||||
if (in.isFaceDown()) {
|
||||
newCopy.turnFaceDownNoUpdate();
|
||||
newCopy.setType(new CardType(in.getFaceDownState().getType()));
|
||||
// prevent StackDescription from revealing face
|
||||
newCopy.updateStateForView();
|
||||
}
|
||||
|
||||
if (in.isAdventureCard() && in.getFaceupCardStateName().equals(CardStateName.Original)) {
|
||||
newCopy.addAlternateState(CardStateName.Adventure, false);
|
||||
newCopy.getState(CardStateName.Adventure).copyFrom(in.getState(CardStateName.Adventure), true);
|
||||
}
|
||||
// prevent StackDescription from revealing face
|
||||
newCopy.updateStateForView();
|
||||
|
||||
/*
|
||||
if (in.isCloned()) {
|
||||
@@ -300,9 +325,6 @@ public final class CardUtil {
|
||||
newCopy.setTimestamp(in.getTimestamp());
|
||||
|
||||
newCopy.setBestowTimestamp(in.getBestowTimestamp());
|
||||
if (in.isTransformed()) {
|
||||
newCopy.incrementTransformedTimestamp();
|
||||
}
|
||||
|
||||
newCopy.setForetold(in.isForetold());
|
||||
newCopy.setForetoldThisTurn(in.isForetoldThisTurn());
|
||||
|
||||
@@ -1779,7 +1779,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
|
||||
AssertJUnit.assertTrue(clonedOutLaw.isCloned());
|
||||
AssertJUnit.assertTrue(clonedOutLaw.isTransformable());
|
||||
AssertJUnit.assertFalse(clonedOutLaw.hasState(CardStateName.Transformed));
|
||||
AssertJUnit.assertTrue(clonedOutLaw.hasState(CardStateName.Transformed));
|
||||
AssertJUnit.assertTrue(clonedOutLaw.canTransform(null));
|
||||
AssertJUnit.assertFalse(clonedOutLaw.isBackSide());
|
||||
|
||||
@@ -1800,7 +1800,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
|
||||
AssertJUnit.assertTrue(transformOutLaw.isCloned());
|
||||
AssertJUnit.assertTrue(transformOutLaw.isTransformable());
|
||||
AssertJUnit.assertFalse(transformOutLaw.hasState(CardStateName.Transformed));
|
||||
AssertJUnit.assertTrue(transformOutLaw.hasState(CardStateName.Transformed));
|
||||
AssertJUnit.assertTrue(transformOutLaw.canTransform(null));
|
||||
AssertJUnit.assertTrue(transformOutLaw.isBackSide());
|
||||
|
||||
@@ -2451,13 +2451,9 @@ public class GameSimulationTest extends SimulationTest {
|
||||
// whereas Naban doesn't see Memnarch to double the trigger
|
||||
addCardToZone("Memnarch", p, ZoneType.Library);
|
||||
|
||||
addCard("Forest", p);
|
||||
addCard("Forest", p);
|
||||
addCard("Island", p);
|
||||
addCard("Island", p);
|
||||
addCard("Island", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Forest", 2, p);
|
||||
addCards("Island", 3, p);
|
||||
addCards("Mountain", 2, p);
|
||||
|
||||
Card genesis = addCardToZone("Genesis Ultimatum", p, ZoneType.Hand);
|
||||
|
||||
@@ -2473,4 +2469,46 @@ public class GameSimulationTest extends SimulationTest {
|
||||
// 2 damage dealt for 2 artifacts
|
||||
AssertJUnit.assertEquals(18, simGame.getPlayers().get(1).getLife());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLKITransformableTokenCopy() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(0);
|
||||
|
||||
String untransformedName = "Heliod, the Radiant Dawn";
|
||||
String transformedName = "Heliod, the Warped Eclipse";
|
||||
|
||||
addCard("Ratadrabik of Urborg", p);
|
||||
Card heliod = addCard(untransformedName, p);
|
||||
|
||||
addCards("Island", 4, p);
|
||||
addCards("Swamp", 3, p);
|
||||
|
||||
Card murder = addCardToZone("Murder", p, ZoneType.Hand);
|
||||
SpellAbility murderSA = murder.getFirstSpellAbility();
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
SpellAbility transformSA = findSAWithPrefix(heliod, "{3}{U/P}: Transform");
|
||||
|
||||
GameSimulator sim = createSimulator(game, p);
|
||||
AssertJUnit.assertNotNull(transformSA);
|
||||
sim.simulateSpellAbility(transformSA);
|
||||
|
||||
Game simGame = sim.getSimulatedGameState();
|
||||
|
||||
Card transformedHeliod = findCardWithName(simGame, transformedName);
|
||||
AssertJUnit.assertNotNull(transformedHeliod);
|
||||
murderSA.getTargets().add(transformedHeliod);
|
||||
|
||||
sim.simulateSpellAbility(murderSA);
|
||||
simGame = sim.getSimulatedGameState();
|
||||
|
||||
Card transformedHeliodToken = findCardWithName(simGame, transformedName);
|
||||
AssertJUnit.assertNotNull(transformedHeliodToken);
|
||||
AssertJUnit.assertTrue(transformedHeliodToken.isToken());
|
||||
AssertJUnit.assertTrue(transformedHeliodToken.isTransformable());
|
||||
AssertJUnit.assertTrue(transformedHeliodToken.isTransformed());
|
||||
AssertJUnit.assertTrue(transformedHeliodToken.isBackSide());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user