fix Molten Disaster (#12307)

* add test case

* unify KickedCondition for battlefield and stack usage

* cleanup Molten Disaster to common classes
This commit is contained in:
xenohedron 2024-05-27 17:25:02 -04:00 committed by GitHub
parent 69e9f3de8a
commit bdebf7020c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 164 additions and 141 deletions

View file

@ -13,7 +13,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*/
public class KickerTest extends CardTestPlayerBase {
/**
/*
* 702.32. Kicker 702.32a Kicker is a static ability that functions while
* the spell with kicker is on the stack. Kicker [cost] means You may pay
* an additional [cost] as you cast this spell. Paying a spell's kicker
@ -722,4 +722,49 @@ public class KickerTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Brain in a Jar", 1);
}
@Test
public void test_ConditionOnStackNotKicked() {
String scourge = "Scourge of the Skyclaves"; // 1B Creature
/* Kicker {4}{B}
When you cast this spell, if it was kicked, each player loses half their life, rounded up.
Scourge of the Skyclavess power and toughness are each equal to 20 minus the highest life total among players.
*/
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.HAND, playerA, scourge);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, scourge);
setChoice(playerA, false); // no kicker
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, scourge, 1);
}
@Test
public void test_ConditionOnStackKicked() {
String scourge = "Scourge of the Skyclaves"; // 1B Creature
/* Kicker {4}{B}
When you cast this spell, if it was kicked, each player loses half their life, rounded up.
Scourge of the Skyclavess power and toughness are each equal to 20 minus the highest life total among players.
*/
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.HAND, playerA, scourge);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, scourge);
setChoice(playerA, true); // kicked
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 10);
assertLife(playerB, 10);
assertPowerToughness(playerA, scourge, 10, 10);
}
}

View file

@ -59,4 +59,90 @@ public class SplitSecondTest extends CardTestPlayerBase {
assertLife(playerB, 20 - 2 - 2);
assertPermanentCount(playerA, "Raging Goblin", 1);
}
private static final String molten = "Molten Disaster";
/* {X}{R}{R} Sorcery
Kicker {R}
If this spell was kicked, it has split second.
Molten Disaster deals X damage to each creature without flying and each player.
*/
private static final String shock = "Shock";
private static final String crab = "Fortress Crab"; // 1/6
private static final String gnomes = "Bottle Gnomes"; // Sacrifice Bottle Gnomes: You gain 3 life.
private static final String bear = "Runeclaw Bear"; // 2/2
private static final String drake = "Seacoast Drake"; // 1/3 flying
public void setupMoltenDisaster() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerA, molten);
addCard(Zone.HAND, playerB, shock);
addCard(Zone.BATTLEFIELD, playerA, crab);
addCard(Zone.BATTLEFIELD, playerA, gnomes);
addCard(Zone.BATTLEFIELD, playerB, bear);
addCard(Zone.BATTLEFIELD, playerB, drake);
}
@Test
public void testMoltenDisasterUnkicked() {
setupMoltenDisaster();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, molten);
setChoice(playerA, false); // no kicker
setChoice(playerA, "X=1");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, shock, crab);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20 - 1 + 3);
assertLife(playerB, 20 - 1);
assertDamageReceived(playerA, crab, 1 + 2);
assertGraveyardCount(playerA, gnomes, 1);
assertDamageReceived(playerB, bear, 1);
assertDamageReceived(playerB, drake, 0);
}
@Test
public void testMoltenDisasterKickedNoSpell() {
setupMoltenDisaster();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, molten);
setChoice(playerA, true); // no kicker
setChoice(playerA, "X=1");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, shock, crab);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
try {
execute();
throw new AssertionError("expected failure to cast Shock");
} catch (AssertionError e) {
Assert.assertTrue(e.getMessage().contains("Can't find ability to activate command: Cast Shock$target=Fortress Crab"));
}
}
@Test
public void testMoltenDisasterKickedNoAbility() {
setupMoltenDisaster();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, molten);
setChoice(playerA, true); // no kicker
setChoice(playerA, "X=1");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
try {
execute();
throw new AssertionError("expected failure to activate sacrifice ability");
} catch (AssertionError e) {
Assert.assertTrue(e.getMessage().contains("Can't find ability to activate command: Sacrifice"));
}
}
}