mirror of
https://github.com/magefree/mage.git
synced 2025-12-23 20:11:59 -08:00
fix Yasharn, Implacable Earth and Angel of Jubilation (#13753)
* Fix Angel of Jubilation and Yasharn, Implacable Earth * canPaySacrificeCost filter was not checking if the source ability was a spell or activated ability * Create common CantPayLifeOrSacrificeEffect * add some docs for CantPayLifeOrSacrificeEffect * change player pay life restrictions and remove player sacrifice cost filter * pay life cost restriction is now an enum set so multiple effects apply together * sacrifice cost filter was removed and replaced with PAY_SACRIFICE_COST event * convert CantPayLifeEffect to CantPayLifeOrSacrificeAbility * Changed to combine life restriction and sacrifice cost restriction * update bargain ability cost adjustors using canPay * fix Thran Portal * Effect was incorrectly adjusting the cost of mana abilities on itself. * Fixed ability adding type to itself during ETB * Add additional tests * update PayLifeCostRestrictions to be mutually exclusive
This commit is contained in:
parent
2833460e59
commit
574d7f91a5
18 changed files with 610 additions and 387 deletions
|
|
@ -337,4 +337,20 @@ public class BargainTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20 + 3);
|
||||
assertTappedCount("Forest", true, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantBargainWithRestriction() {
|
||||
setStrictChooseMode(true);
|
||||
// Players can’t pay life or sacrifice nonland permanents to cast spells or activate abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Yasharn, Implacable Earth");
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, relic);
|
||||
|
||||
checkPlayableAbility("restricted by Yasharn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", false);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.token.FoodToken;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -18,12 +24,14 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*/
|
||||
public class AngelOfJubilationTest extends CardTestPlayerBase {
|
||||
|
||||
public static final String angelOfJubilation = "Angel of Jubilation";
|
||||
|
||||
/**
|
||||
* Tests boosting other non black creatures
|
||||
*/
|
||||
@Test
|
||||
public void testBoost() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Devout Chaplain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Corpse Traders");
|
||||
|
||||
|
|
@ -33,7 +41,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPowerToughness(playerA, "Angel of Jubilation", 3, 3);
|
||||
assertPowerToughness(playerA, angelOfJubilation, 3, 3);
|
||||
assertPowerToughness(playerA, "Devout Chaplain", 3, 3);
|
||||
assertPowerToughness(playerA, "Corpse Traders", 3, 3);
|
||||
}
|
||||
|
|
@ -43,14 +51,14 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
*/
|
||||
@Test
|
||||
public void testNoBoostOnBattlefieldLeave() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Devout Chaplain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Corpse Traders");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Angel of Jubilation");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", angelOfJubilation);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -58,14 +66,14 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 0);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 0);
|
||||
assertPowerToughness(playerA, "Devout Chaplain", 2, 2);
|
||||
assertPowerToughness(playerA, "Corpse Traders", 3, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreatures() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Corpse Traders");
|
||||
|
||||
|
|
@ -81,7 +89,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeNonCreaturePermanents() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barrin, Master Wizard");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
|
|
@ -89,20 +97,20 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Food Chain");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent: Return target creature to its owner's hand.");
|
||||
addTarget(playerB, "Angel of Jubilation"); // return to hand
|
||||
addTarget(playerB, angelOfJubilation); // return to hand
|
||||
setChoice(playerB, "Food Chain"); // sacrifice cost
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 0);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 0);
|
||||
assertPermanentCount(playerB, "Food Chain", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreaturesAsPartOfPermanentsOptions() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barrin, Master Wizard");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves", 2);
|
||||
|
|
@ -115,13 +123,13 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 1);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 1);
|
||||
assertPermanentCount(playerB, "Nantuko Husk", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeAll() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Corpse Traders");
|
||||
addCard(Zone.HAND, playerB, "Soulblast");
|
||||
|
|
@ -142,7 +150,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreatureSource() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Children of Korlis");
|
||||
|
||||
checkPlayableAbility("Can't sac", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice", false);
|
||||
|
|
@ -155,7 +163,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeAllLands() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Tomb of Urami");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4);
|
||||
|
||||
|
|
@ -169,7 +177,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeNonCreatureSource() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tundra");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Wasteland");
|
||||
|
||||
|
|
@ -195,7 +203,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStrictChooseMode(true);
|
||||
// Other nonblack creatures you control get +1/+1.
|
||||
// Players can't pay life or sacrifice creatures to cast spells or activate abilities
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
|
||||
// Indestructible
|
||||
|
|
@ -234,7 +242,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStrictChooseMode(true);
|
||||
// Other nonblack creatures you control get +1/+1.
|
||||
// Players can't pay life or sacrifice creatures to cast spells or activate abilities
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
|
||||
// Pay 7 life: Draw seven cards.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Griselbrand");
|
||||
|
|
@ -244,4 +252,90 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanSacrificeTriggeredAbility() {
|
||||
/*
|
||||
Unscrupulous Contractor
|
||||
{2}{B}
|
||||
Creature — Human Assassin
|
||||
When this creature enters, you may sacrifice a creature. When you do, target player draws two cards and loses 2 life.
|
||||
Plot {2}{B}
|
||||
3/2
|
||||
*/
|
||||
String contractor = "Unscrupulous Contractor";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
2/2
|
||||
*/
|
||||
String cub = "Bear Cub";
|
||||
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.HAND, playerA, contractor);
|
||||
addCard(Zone.HAND, playerB, contractor);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, contractor);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, cub);
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, contractor);
|
||||
setChoice(playerB, true);
|
||||
setChoice(playerB, cub);
|
||||
addTarget(playerB, playerB);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 2);
|
||||
assertLife(playerA, 20 - 2);
|
||||
assertGraveyardCount(playerA, cub, 1);
|
||||
|
||||
assertHandCount(playerB, 1 + 2); //draw + contractor effect
|
||||
assertLife(playerB, 20 - 2);
|
||||
assertGraveyardCount(playerB, cub, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canSacToMondrakWithArtifacts() {
|
||||
setStrictChooseMode(true);
|
||||
//Mondrak, Glory Dominus
|
||||
//{2}{W}{W}
|
||||
//Legendary Creature — Phyrexian Horror
|
||||
//If one or more tokens would be created under your control, twice that many of those tokens are created instead.
|
||||
//{1}{W/P}{W/P}, Sacrifice two other artifacts and/or creatures: Put an indestructible counter on Mondrak.
|
||||
String mondrak = "Mondrak, Glory Dominus";
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.ALL,
|
||||
new CreateTokenEffect(new FoodToken(), 2),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
addCustomCardWithAbility("Token-maker", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, mondrak);
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bear Cub", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
||||
checkPlayableAbility("Can't activate Mondrak", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice", false);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "create two");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice");
|
||||
setChoice(playerA, "Food Token", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, mondrak, CounterType.INDESTRUCTIBLE, 1);
|
||||
assertPermanentCount(playerA, "Bear Cub", 2);
|
||||
assertPermanentCount(playerA, "Food Token", 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.mage.test.cards.single.dmu;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -76,4 +75,26 @@ public class KarnsSylexTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20 - 3);
|
||||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not work with mana abilities, e.g. Thran Portal, with Yasharn, Implacable Earth.
|
||||
*/
|
||||
@Test
|
||||
public void blockedManaAbilitiesWithYasharn() {
|
||||
addCard(Zone.HAND, playerA, "Thran Portal");
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerA, karnsSylex);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Yasharn, Implacable Earth");
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thran Portal");
|
||||
setChoice(playerA, "Thran");
|
||||
setChoice(playerA, "Mountain");
|
||||
|
||||
checkPlayableAbility("restricted by Yasharn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", false);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import mage.constants.Zone;
|
|||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.t.ThranPortal Thran Portal}
|
||||
* Land Gate
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
package org.mage.test.cards.single.znr;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.token.FoodToken;
|
||||
import mage.game.permanent.token.TreasureToken;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -23,21 +30,26 @@ public class YasharnImplacableEarthTest extends CardTestPlayerBase {
|
|||
* Test that players can't pay life to cast a spell.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void cantPayLifeToCast() {
|
||||
// {W}{B}
|
||||
// As an additional cost to cast this spell, pay 5 life or sacrifice a creature or enchantment.
|
||||
// Destroy target creature.
|
||||
addCard(Zone.HAND, playerA, "Final Payment");
|
||||
//{4}{B/P}{B/P}{B/P}
|
||||
//Legendary Creature — Phyrexian Horror Minion
|
||||
//2/2
|
||||
//Lifelink
|
||||
//For each {B} in a cost, you may pay 2 life rather than pay that mana.
|
||||
//Whenever you cast a black spell, put a +1/+1 counter on K'rrik.
|
||||
addCard(Zone.HAND, playerA, "K'rrik, Son of Yawgmoth");
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Final Payment", yasharn);
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "Silvercoat Lion");
|
||||
checkPlayableAbility("Can't cast Final Payment", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Final Payment", false);
|
||||
checkPlayableAbility("Can't cast K'rrik", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast K'rrik, Son of Yawgmoth", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
|
@ -71,22 +83,20 @@ public class YasharnImplacableEarthTest extends CardTestPlayerBase {
|
|||
* Test that players can't sacrifice a nonland permanent to cast a spell.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void cantSacrificeNonlandToCast() {
|
||||
// {1}{B}
|
||||
// As an additional cost to cast this spell, sacrifice an artifact or creature.
|
||||
// Draw two cards and create a Treasure token.
|
||||
addCard(Zone.HAND, playerA, "Deadly Dispute");
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bear Cub");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deadly Dispute");
|
||||
setChoice(playerA, yasharn);
|
||||
checkPlayableAbility("Can't cast Deadly Dispute", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Deadly Dispute", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, "Treasure Token", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,9 +127,13 @@ public class YasharnImplacableEarthTest extends CardTestPlayerBase {
|
|||
*/
|
||||
@Test
|
||||
public void canSacrificeLandToCast() {
|
||||
//Crop Rotation
|
||||
//{G}
|
||||
//As an additional cost to cast this spell, sacrifice a land.
|
||||
//Search your library for a land card, put that card onto the battlefield, then shuffle.
|
||||
addCard(Zone.HAND, playerA, "Crop Rotation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.HAND, playerA, "Crop Rotation");
|
||||
addCard(Zone.LIBRARY, playerA, "Mountain");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
|
@ -156,4 +170,159 @@ public class YasharnImplacableEarthTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "Island", 1);
|
||||
assertGraveyardCount(playerA, "Evolving Wilds", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a player cannot sacrifice artifacts or creatures to activate abilities
|
||||
*/
|
||||
@Test
|
||||
public void cantSacToMondrakWithArtifacts() {
|
||||
setStrictChooseMode(true);
|
||||
//Mondrak, Glory Dominus
|
||||
//{2}{W}{W}
|
||||
//Legendary Creature — Phyrexian Horror
|
||||
//If one or more tokens would be created under your control, twice that many of those tokens are created instead.
|
||||
//{1}{W/P}{W/P}, Sacrifice two other artifacts and/or creatures: Put an indestructible counter on Mondrak.
|
||||
String mondrak = "Mondrak, Glory Dominus";
|
||||
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.ALL,
|
||||
new CreateTokenEffect(new TreasureToken(), 2),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
ability.addEffect(new CreateTokenEffect(new FoodToken(), 2));
|
||||
|
||||
addCustomCardWithAbility("Token-maker", playerA, ability);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mondrak);
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bear Cub", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
||||
checkPlayableAbility("Can't activate Mondrak with creatures", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice", false);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "create two");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
checkPlayableAbility("Can't activate Mondrak with creatures or artifacts", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice", false);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Bear Cub", 2);
|
||||
assertPermanentCount(playerA, "Treasure Token", 4);
|
||||
assertPermanentCount(playerA, "Food Token", 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canSacrificeTriggeredAbility() {
|
||||
/*
|
||||
Unscrupulous Contractor
|
||||
{2}{B}
|
||||
Creature — Human Assassin
|
||||
When this creature enters, you may sacrifice a creature. When you do, target player draws two cards and loses 2 life.
|
||||
Plot {2}{B}
|
||||
3/2
|
||||
*/
|
||||
String contractor = "Unscrupulous Contractor";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
2/2
|
||||
*/
|
||||
String cub = "Bear Cub";
|
||||
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.HAND, playerA, contractor);
|
||||
addCard(Zone.HAND, playerB, contractor);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, contractor);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, cub);
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, contractor);
|
||||
setChoice(playerB, true);
|
||||
setChoice(playerB, cub);
|
||||
addTarget(playerB, playerB);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 2);
|
||||
assertLife(playerA, 20 - 2);
|
||||
assertGraveyardCount(playerA, cub, 1);
|
||||
|
||||
assertHandCount(playerB, 1 + 2); //draw + contractor effect
|
||||
assertLife(playerB, 20 - 2);
|
||||
assertGraveyardCount(playerB, cub, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canPayLifeForTriggeredAbility() {
|
||||
/*
|
||||
Arrogant Poet
|
||||
{1}{B}
|
||||
Creature — Human Warlock
|
||||
Whenever this creature attacks, you may pay 2 life. If you do, it gains flying until end of turn.
|
||||
2/1
|
||||
*/
|
||||
String poet = "Arrogant Poet";
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, poet);
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
|
||||
attack(1, playerA, poet);
|
||||
setChoice(playerA, true); // pay 2 life
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 20 - 2); // combat damage
|
||||
assertLife(playerA, 20 - 2); // paid life
|
||||
assertAbility(playerA, poet, FlyingAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canSacWithGrist() {
|
||||
/*
|
||||
Grist, the Hunger Tide
|
||||
{1}{B}{G}
|
||||
Legendary Planeswalker — Grist
|
||||
As long as Grist isn’t on the battlefield, it’s a 1/1 Insect creature in addition to its other types.
|
||||
+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.
|
||||
−2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.
|
||||
−5: Each opponent loses life equal to the number of creature cards in your graveyard.
|
||||
Loyalty: 3
|
||||
*/
|
||||
String grist = "Grist, the Hunger Tide";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
2/2
|
||||
*/
|
||||
String cub = "Bear Cub";
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grist);
|
||||
addCard(Zone.BATTLEFIELD, playerA, yasharn);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, grist + "@gristB");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:");
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, cub);
|
||||
addTarget(playerA, "@gristB");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(grist, CounterType.LOYALTY, 1);
|
||||
assertGraveyardCount(playerB, grist, 1);
|
||||
assertGraveyardCount(playerA, cub, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3760,13 +3760,13 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PayLifeCostLevel getPayLifeCostLevel() {
|
||||
return computerPlayer.getPayLifeCostLevel();
|
||||
public EnumSet<PayLifeCostRestriction> getPayLifeCostRestrictions() {
|
||||
return computerPlayer.getPayLifeCostRestrictions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayLifeCostLevel(PayLifeCostLevel payLifeCostLevel) {
|
||||
computerPlayer.setPayLifeCostLevel(payLifeCostLevel);
|
||||
public void addPayLifeCostRestriction(PayLifeCostRestriction payLifeCostRestriction) {
|
||||
computerPlayer.addPayLifeCostRestriction(payLifeCostRestriction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -3774,16 +3774,6 @@ public class TestPlayer implements Player {
|
|||
return computerPlayer.canPaySacrificeCost(permanent, source, controllerId, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterPermanent getSacrificeCostFilter() {
|
||||
return computerPlayer.getSacrificeCostFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCanPaySacrificeCostFilter(FilterPermanent permanent) {
|
||||
computerPlayer.setCanPaySacrificeCostFilter(permanent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canLoseByZeroOrLessLife() {
|
||||
return computerPlayer.canLoseByZeroOrLessLife();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue