mirror of
https://github.com/magefree/mage.git
synced 2025-12-21 11:02:00 -08:00
tests: improved tests for Double Season (new tests and docs);
This commit is contained in:
parent
ea86d3e3ef
commit
085ed5a7a7
1 changed files with 185 additions and 69 deletions
|
|
@ -7,14 +7,18 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doubling Season: If an effect would put one or more tokens onto the
|
* Doubling Season:
|
||||||
|
* If an effect would put one or more tokens onto the
|
||||||
* battlefield under your control, it puts twice that many of those tokens onto
|
* battlefield under your control, it puts twice that many of those tokens onto
|
||||||
* the battlefield instead. If an effect would place one or more counters on a
|
* the battlefield instead.
|
||||||
|
* If an effect would place one or more counters on a
|
||||||
* permanent you control, it places twice that many of those counters on that
|
* permanent you control, it places twice that many of those counters on that
|
||||||
* permanent instead.
|
* permanent instead.
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2, JayDi85
|
||||||
*/
|
*/
|
||||||
public class DoublingSeasonTest extends CardTestPlayerBase {
|
public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
|
@ -23,39 +27,77 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
* added to Pallid Mycoderm if Doubling Season is on the battlefield.
|
* added to Pallid Mycoderm if Doubling Season is on the battlefield.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleSporeCounter() {
|
public void test_Counters_ByTrigger() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, put a spore counter on Pallid Mycoderm.
|
||||||
addCard(Zone.HAND, playerA, "Pallid Mycoderm");
|
addCard(Zone.HAND, playerA, "Pallid Mycoderm");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pallid Mycoderm");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pallid Mycoderm");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertCounterCount("Pallid Mycoderm", CounterType.SPORE, 2);
|
assertCounterCount("Pallid Mycoderm", CounterType.SPORE, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that 2 Saproling tokens are created instead of one if Doubling
|
||||||
|
* Season is on the battlefield.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test_Tokens_ByActivate() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, put a spore counter on Pallid Mycoderm.
|
||||||
|
// Remove three spore counters from Pallid Mycoderm: Create a 1/1 green Saproling creature token.
|
||||||
|
addCard(Zone.HAND, playerA, "Pallid Mycoderm");
|
||||||
|
|
||||||
|
// prepare pallid and wait upkeeps to collect spore counters
|
||||||
|
// turn 3 - +2 counters
|
||||||
|
// turn 5 - +2 counters
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pallid Mycoderm");
|
||||||
|
|
||||||
|
// create token and double it
|
||||||
|
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove three spore counters from {this}: Create");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(5, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, "Saproling Token", 1 + 1);
|
||||||
|
assertCounterCount("Pallid Mycoderm", CounterType.SPORE, 2 + 2 - 3);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if 3 damage are prevented with Test of Faith and Doubling Season is
|
* Tests if 3 damage are prevented with Test of Faith and Doubling Season is
|
||||||
* on the battlefield, that 6 +1/+1 counters are added to the target
|
* on the battlefield, that 6 +1/+1 counters are added to the target
|
||||||
* creature.
|
* creature.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleP1P1Counter() {
|
public void test_Counters_ByPreventEffect() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||||
|
// Prevent the next 3 damage that would be dealt to target creature this turn.
|
||||||
|
// For each 1 damage prevented this way, put a +1/+1 counter on that creature.
|
||||||
addCard(Zone.HAND, playerA, "Test of Faith");
|
addCard(Zone.HAND, playerA, "Test of Faith");
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 1);
|
addCard(Zone.BATTLEFIELD, playerB, "Plains", 1);
|
||||||
|
// Lightning Helix deals 3 damage to any target and you gain 3 life.
|
||||||
addCard(Zone.HAND, playerB, "Lightning Helix");
|
addCard(Zone.HAND, playerB, "Lightning Helix");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Silvercoat Lion");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Silvercoat Lion");
|
||||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Helix", "Silvercoat Lion");
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Helix", "Silvercoat Lion");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
|
|
@ -65,33 +107,24 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||||
assertCounterCount("Silvercoat Lion", CounterType.P1P1, 6);
|
assertCounterCount("Silvercoat Lion", CounterType.P1P1, 6);
|
||||||
assertPowerToughness(playerA, "Silvercoat Lion", 8, 8);
|
assertPowerToughness(playerA, "Silvercoat Lion", 8, 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that 2 Saproling tokens are created instead of one if Doubling
|
|
||||||
* Season is on the battlefield.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleTokens() {
|
public void test_Tokens_ByPlaneswalkerActivate() {
|
||||||
|
// +1: Create a 2/2 black Zombie creature token.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Liliana, Dreadhorde General");
|
||||||
|
//
|
||||||
|
// If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.
|
||||||
|
// If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
|
||||||
|
|
||||||
addCard(Zone.HAND, playerA, "Pallid Mycoderm");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pallid Mycoderm");
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove three spore counters from {this}: Create a 1/1 green Saproling creature token.");
|
|
||||||
|
|
||||||
setStopAt(5, PhaseStep.END_TURN);
|
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerA, 20);
|
assertPermanentCount(playerA, "Zombie Token", 2);
|
||||||
assertLife(playerB, 20);
|
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Saproling Token", 2);
|
|
||||||
assertCounterCount("Pallid Mycoderm", CounterType.SPORE, 1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -106,7 +139,7 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
* at the same time and not related to the specific cards.
|
* at the same time and not related to the specific cards.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleRiteOfReplication() {
|
public void test_RiteOfReplication_Tokens_ByMultipleEffects() {
|
||||||
/**
|
/**
|
||||||
* If an effect would put one or more tokens onto the battlefield under
|
* If an effect would put one or more tokens onto the battlefield under
|
||||||
* your control, it puts twice that many of those tokens onto the
|
* your control, it puts twice that many of those tokens onto the
|
||||||
|
|
@ -118,66 +151,78 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
|
||||||
|
|
||||||
// Create a tokenthat's a copy of target creature onto the battlefield. If Rite of Replication was kicked, put five of those tokens onto the battlefield instead.
|
// Create a token that's a copy of target creature onto the battlefield.
|
||||||
|
// If Rite of Replication was kicked, put five of those tokens onto the battlefield instead.
|
||||||
addCard(Zone.HAND, playerA, "Rite of Replication");
|
addCard(Zone.HAND, playerA, "Rite of Replication");
|
||||||
// When Venerable Monk enters the battlefield, you gain 2 life.
|
// When Venerable Monk enters the battlefield, you gain 2 life.
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Venerable Monk", 1);
|
addCard(Zone.BATTLEFIELD, playerB, "Venerable Monk", 1);
|
||||||
|
|
||||||
|
// create 5 * 2 copied tokens
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of Replication", "Venerable Monk");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of Replication", "Venerable Monk");
|
||||||
setChoice(playerA, true);
|
setChoice(playerA, true); // use kicker
|
||||||
|
IntStream.rangeClosed(1, 9).forEach(value -> {
|
||||||
|
setChoice(playerA, "When {this} enters"); // x10 triggers order
|
||||||
|
});
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerA, 40);
|
assertLife(playerA, 20 + 10 * 2); // x10 etb x2 life
|
||||||
assertPermanentCount(playerA, "Venerable Monk", 10);
|
assertPermanentCount(playerA, "Venerable Monk", 10);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doubling Season doesn't create two tokens from opponent's Rite of Raging Storm
|
* Doubling Season doesn't create two tokens from opponent's Rite of Raging Storm
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleRiteOfRagingStorm() {
|
public void test_RiteOfReplication_TokensFromController_CanAttack() {
|
||||||
// At the beginning of each player's upkeep, that player creates a 5/1 red Elemental creature token named Lightning Rager.
|
// At the beginning of each player's upkeep, that player creates a 5/1 red Elemental creature token named Lightning Rager.
|
||||||
// It has trample, haste, and "At the beginning of the end step, sacrifice this creature."
|
// It has trample, haste, and "At the beginning of the end step, sacrifice this creature."
|
||||||
addCard(Zone.HAND, playerA, "Rite of the Raging Storm");// {3}{R}{R}
|
addCard(Zone.HAND, playerA, "Rite of the Raging Storm");// {3}{R}{R}
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||||
|
//
|
||||||
// If an effect would put one or more tokens onto the battlefield under your control, it puts twice that many of those tokens onto the battlefield instead.
|
// If an effect would put one or more tokens onto the battlefield under your control, it puts twice that many of those tokens onto the battlefield instead.
|
||||||
// If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
// If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
|
|
||||||
|
// prepare x2 tokens on turn 2 and turn 3
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of the Raging Storm");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of the Raging Storm");
|
||||||
|
|
||||||
|
// controller's token can attack opponent
|
||||||
attack(3, playerA, "Lightning Rager");
|
attack(3, playerA, "Lightning Rager");
|
||||||
attack(3, playerA, "Lightning Rager");
|
attack(3, playerA, "Lightning Rager");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Rite of the Raging Storm", 1);
|
assertPermanentCount(playerA, "Rite of the Raging Storm", 1);
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Lightning Rager", 2);
|
assertPermanentCount(playerA, "Lightning Rager", 2);
|
||||||
|
assertTappedCount("Lightning Rager", true, 2);
|
||||||
|
|
||||||
assertLife(playerB, 10);
|
assertLife(playerB, 10);
|
||||||
assertLife(playerA, 20);
|
assertLife(playerA, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleRiteOfRagingStormOpponent() {
|
public void test_RiteOfReplication_TokensFromOpponent_CanNotAttack() {
|
||||||
// At the beginning of each player's upkeep, that player creates a 5/1 red Elemental creature token named Lightning Rager.
|
// At the beginning of each player's upkeep, that player creates a 5/1 red Elemental creature token named Lightning Rager.
|
||||||
// It has trample, haste, and "At the beginning of the end step, sacrifice this creature."
|
// It has trample, haste, and "At the beginning of the end step, sacrifice this creature."
|
||||||
addCard(Zone.HAND, playerA, "Rite of the Raging Storm");// {3}{R}{R}
|
addCard(Zone.HAND, playerA, "Rite of the Raging Storm");// {3}{R}{R}
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||||
|
//
|
||||||
// If an effect would put one or more tokens onto the battlefield under your control, it puts twice that many of those tokens onto the battlefield instead.
|
// If an effect would put one or more tokens onto the battlefield under your control, it puts twice that many of those tokens onto the battlefield instead.
|
||||||
// If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
// If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerB, "Doubling Season");
|
||||||
|
|
||||||
|
// prepare x2 tokens on turn 2
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of the Raging Storm");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of the Raging Storm");
|
||||||
|
|
||||||
attack(2, playerB, "Lightning Rager:0"); // Can't attack
|
// opponent's token can not attack
|
||||||
attack(2, playerB, "Lightning Rager:1"); // Can't attack
|
attack(2, playerB, "Lightning Rager"); // can't attack
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -185,13 +230,14 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
Assert.fail("must throw exception on execute");
|
Assert.fail("must throw exception on execute");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 2")) {
|
if (!e.getMessage().contains("Can't find available command - attack:Lightning Rager")) {
|
||||||
Assert.fail("Should have thrown error about cannot attack, but got:\n" + e.getMessage());
|
Assert.fail("Should have thrown error about cannot attack, but got:\n" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Rite of the Raging Storm", 1);
|
assertPermanentCount(playerA, "Rite of the Raging Storm", 1);
|
||||||
assertPermanentCount(playerB, "Lightning Rager", 2);
|
assertPermanentCount(playerB, "Lightning Rager", 2);
|
||||||
|
assertTappedCount("Lightning Rager", true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -202,21 +248,58 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
* on as a cost, not as an effect.
|
* on as a cost, not as an effect.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPlaneswalkerLoyalty() {
|
public void test_LoyaltyCounters_DoubleSeason() {
|
||||||
|
// planeswalker, 2 starting loyalty
|
||||||
|
// +1: Draw a card, then discard a card at random.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Tibalt, the Fiend-Blooded");
|
addCard(Zone.BATTLEFIELD, playerA, "Tibalt, the Fiend-Blooded");
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
// 2 starting loyalty
|
||||||
|
// on etb: x2 from double season
|
||||||
|
int onEtbCount = 2 * 2;
|
||||||
|
checkPermanentCounters("etb counters", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tibalt, the Fiend-Blooded", CounterType.LOYALTY, onEtbCount);
|
||||||
|
|
||||||
|
// on +1 cost: nothing from double season
|
||||||
|
int onCostCount = 1;
|
||||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Draw a card, then discard a card at random.");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Draw a card, then discard a card at random.");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerA, 20);
|
assertLife(playerA, 20);
|
||||||
assertLife(playerB, 20);
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
//Should not be doubled
|
assertCounterCount("Tibalt, the Fiend-Blooded", CounterType.LOYALTY, onEtbCount + onCostCount);
|
||||||
assertCounterCount("Tibalt, the Fiend-Blooded", CounterType.LOYALTY, 3);
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_LoyaltyCounters_Pir() {
|
||||||
|
// If one or more counters would be put on a permanent your team controls, that many plus one of each of those
|
||||||
|
// kinds of counters are put on that permanent instead.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Pir, Imaginative Rascal");
|
||||||
|
//
|
||||||
|
// planeswalker, 2 starting loyalty
|
||||||
|
// +1: Draw a card, then discard a card at random.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Tibalt, the Fiend-Blooded");
|
||||||
|
|
||||||
|
// 2 starting loyalty
|
||||||
|
// on etb: +1 from pir
|
||||||
|
int onEtbCount = 2 + 1;
|
||||||
|
checkPermanentCounters("etb counters", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tibalt, the Fiend-Blooded", CounterType.LOYALTY, onEtbCount);
|
||||||
|
|
||||||
|
// on +1 cost: +1 from pir
|
||||||
|
int onCostCount = 1 + 1;
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Draw a card, then discard a card at random.");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
|
assertCounterCount("Tibalt, the Fiend-Blooded", CounterType.LOYALTY, onEtbCount + onCostCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -225,51 +308,84 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
* https://github.com/magefree/mage/issues/5802
|
* https://github.com/magefree/mage/issues/5802
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPlaneswalkerWithoutReplacementEffect() {
|
public void test_LoyaltyCounters_SeasonAndPir_SeasonFirst() {
|
||||||
//addCard(Zone.BATTLEFIELD, playerA, "Pir, Imaginative Rascal");
|
/*
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Fire Artisan");
|
details explain from https://www.reddit.com/r/mtgrules/comments/aql1it/doubling_season_and_pir_imaginative_rascal/
|
||||||
|
|
||||||
|
When you activate Tezzeret's ability to make Thopters, you'll put on 4.
|
||||||
|
In this case, Doubling Season can't apply initially because it's a cost and not an effect,
|
||||||
|
but Pir can apply making it 2 and then that lets Season in the door to make it 4.
|
||||||
|
|
||||||
|
Related rules:
|
||||||
|
616.1
|
||||||
|
If two or more replacement and/or prevention effects are attempting to modify the way an event affects an
|
||||||
|
object or player, the affected object’s controller (or its owner if it has no controller) or the affected
|
||||||
|
player chooses one to apply, following the steps listed below [..].
|
||||||
|
616.1e
|
||||||
|
Once the chosen effect has been applied, this process is repeated (taking into account only replacement or
|
||||||
|
prevention effects that would now be applicable) until there are no more left to apply.
|
||||||
|
614.16
|
||||||
|
Some replacement effects apply “if an effect would create one or more tokens” or “if an effect would
|
||||||
|
put one or more counters on a permanent.” These replacement effects apply if the effect of a resolving
|
||||||
|
spell or ability creates a token or puts a counter on a permanent, and they also apply if another replacement
|
||||||
|
or prevention effect does so, even if the original event being modified wasn’t itself an effect.
|
||||||
|
*/
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
|
//
|
||||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
// If one or more counters would be put on a permanent your team controls, that many plus one of each of those
|
||||||
|
// kinds of counters are put on that permanent instead.
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
addCard(Zone.BATTLEFIELD, playerA, "Pir, Imaginative Rascal");
|
||||||
execute();
|
// planeswalker, 4 starting loyalty
|
||||||
|
// +1: Exile the top card of your library. You may play it this turn.
|
||||||
assertCounterCount(playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, 4 + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPlaneswalkerWithReplacementEffect() {
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Fire Artisan");
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Fire Artisan");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season"); // x2 counters
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Pir, Imaginative Rascal"); // +1 counter
|
|
||||||
|
|
||||||
|
// choose etb replacement effects (from season and pir)
|
||||||
|
setChoice(playerA, "Doubling Season");
|
||||||
|
|
||||||
|
// 4 starting loyalty
|
||||||
|
// on etb: x2 from double season, +1 from pir
|
||||||
|
int onEtbCount = 4 * 2 + 1;
|
||||||
|
checkPermanentCounters("etb counters", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, onEtbCount);
|
||||||
|
|
||||||
|
// +1 cost (no double effect on cost, +1 effect from pir, double effect after pir's effect)
|
||||||
|
int onCostCount = (1 + 1) * 2;
|
||||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertCounterCount(playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, 4 + (1 + 1) * 2);
|
assertCounterCount(playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, onEtbCount + onCostCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlaneswalkerCreatesToken() {
|
public void test_LoyaltyCounters_SeasonAndPir_PirFirst() {
|
||||||
setStrictChooseMode(true);
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
|
//
|
||||||
|
// If one or more counters would be put on a permanent your team controls, that many plus one of each of those
|
||||||
|
// kinds of counters are put on that permanent instead.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Pir, Imaginative Rascal");
|
||||||
|
// planeswalker, 4 starting loyalty
|
||||||
|
// +1: Exile the top card of your library. You may play it this turn.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Fire Artisan");
|
||||||
|
|
||||||
// +1: Create a 2/2 black Zombie creature token.
|
// choose etb replacement effects (from season and pir)
|
||||||
// -4: Each player sacrifices two creatures.
|
setChoice(playerA, "Pir, Imaginative Rascal");
|
||||||
// -9: Each opponent chooses a permanent they control of each permanent type and sacrifices the rest.
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Liliana, Dreadhorde General");
|
|
||||||
// If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.
|
|
||||||
// If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season"); //
|
|
||||||
|
|
||||||
|
// 4 starting loyalty
|
||||||
|
// on etb: +1 from pir, x2 from double season
|
||||||
|
int onEtbCount = (4 + 1) * 2;
|
||||||
|
checkPermanentCounters("etb counters", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, onEtbCount);
|
||||||
|
|
||||||
|
// +1 cost (no double effect on cost, +1 effect from pir, double effect after pir's effect)
|
||||||
|
int onCostCount = (1 + 1) * 2;
|
||||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
||||||
|
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Zombie Token", 2);
|
assertCounterCount(playerA, "Chandra, Fire Artisan", CounterType.LOYALTY, onEtbCount + onCostCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue