Skip to content

Commit

Permalink
tests: added test for LKI from copied spell (related to Swan Song fix…
Browse files Browse the repository at this point in the history
… from #12883)
  • Loading branch information
JayDi85 committed Sep 25, 2024
1 parent afde449 commit 701bd68
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.UUID;

/**
* @author LevelX2
* @author LevelX2, JayDi85
*/
public class CopySpellTest extends CardTestPlayerBase {

Expand Down Expand Up @@ -905,4 +905,56 @@ private void cardsMustHaveSameZoneAndZCC(Card originalCard, Card copiedCard, Str
Assert.fail(infoPrefix + " - " + "cards must have same zone and zcc: " + zcc1 + " - " + zone1 + " != " + zcc2 + " - " + zone2);
}
}

/**
* Bug: If Swan Song is used to counter a copied spell, no tokens are created #12883
*/
@Test
public void test_LKI() {
// Counter target enchantment, instant, or sorcery spell.
// Its controller creates a 2/2 blue Bird creature token with flying.
addCard(Zone.HAND, playerA, "Swan Song", 1); // {U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
//
// Until end of turn, whenever a player casts an instant or sorcery spell, that player copies it and
// may choose new targets for the copy.
addCard(Zone.HAND, playerA, "Bonus Round", 1); // {1}{R}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//
addCard(Zone.HAND, playerA, "Lightning Bolt", 1); // {R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerB, "Augmenting Automaton", 1);

checkPermanentCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, "Bird Token", 0);
checkPermanentCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerB, "Grizzly Bears", 1);
checkPermanentCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerB, "Augmenting Automaton", 1);

// prepare copy effect
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", 3);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bonus Round");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);

// cast and duplicate bolt
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
addTarget(playerA, "Grizzly Bears"); // original target
setChoice(playerA, true); // use new target
addTarget(playerA, "Augmenting Automaton"); // copy target
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true); // resolve copy trigger
checkStackObject("on copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", 2);

// counter copy and save Augmenting Automaton
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {U}", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Swan Song", "Lightning Bolt[only copy]", "Lightning Bolt", StackClause.WHILE_COPY_ON_STACK);
setChoice(playerA, false); // no change target for duplicated counter spell (non-relevant here)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);

checkPermanentCount("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, "Bird Token", 1);
checkPermanentCount("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerB, "Grizzly Bears", 0);
checkPermanentCount("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerB, "Augmenting Automaton", 1);

setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ private void printAliases(Game game, TestPlayer player) {
private void printStack(Game game) {
System.out.println("Stack objects: " + game.getStack().size());
game.getStack().forEach(stack -> {
System.out.println(stack.getStackAbility().toString());
System.out.println(stack.getStackAbility().toString() + (stack.isCopy() ? " [copy]" : ""));
});
}

Expand Down
2 changes: 1 addition & 1 deletion Mage/src/main/java/mage/game/stack/SpellStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public boolean counter(UUID objectId, Ability source, Game game, PutCards putCar
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, source, stackObject.getControllerId()))) {
// spells are removed from stack by the card movement
if (!(stackObject instanceof Spell)
|| stackObject.isCopy()) { // ensure that copies of stackobjects have their history recorded ie: Swan Song
|| stackObject.isCopy()) { // !ensure that copies of stackobjects have their history recorded ie: Swan Song
this.remove(stackObject, game);
game.rememberLKI(Zone.STACK, stackObject);
}
Expand Down

0 comments on commit 701bd68

Please sign in to comment.