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:
Jmlundeen 2025-08-09 17:53:43 -05:00 committed by GitHub
parent 2833460e59
commit 574d7f91a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 610 additions and 387 deletions

View file

@ -337,4 +337,20 @@ public class BargainTest extends CardTestPlayerBase {
assertLife(playerA, 20 + 3);
assertTappedCount("Forest", true, 7);
}
@Test
public void testCantBargainWithRestriction() {
setStrictChooseMode(true);
// Players cant 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();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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 isnt on the battlefield, its 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);
}
}

View file

@ -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();