update RemoveCountersSourceCost, Gwen Stacy, and Price of Betrayal (#13941)

* update RemoveCountersSourceCost, Gwen Stacy, and Price of Betrayal

* added support for choosing multiple counters to RemoveCountersSourceCost

* changed Price of Betrayal to use player.getMultiAmount method

* added REMOVE_COUNTERS to MultiAmountType

* create common RemoveUpToAmountCountersEffect and update cards

* update default target wording on RemoveUpToAmountCountersEffect
This commit is contained in:
Jmlundeen 2025-09-07 16:50:46 -05:00 committed by GitHub
parent 432de6f9fe
commit 4dd7e963bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 270 additions and 297 deletions

View file

@ -0,0 +1,61 @@
package org.mage.test.cards.single.spm;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author Jmlundeen
*/
public class GwenStacyTest extends CardTestPlayerBase {
/*
Gwen Stacy
{1}{R}
Legendary Creature - Human Performer Hero
When Gwen Stacy enters, exile the top card of your library. You may play that card for as long as you control this creature.
{2}{U}{R}{W}: Transform Gwen Stacy. Activate only as a sorcery.
2/1
Ghost-Spider
{2}{U}{R}{W}
Legendary Creature - Spider Human Hero
Flying, vigilance, haste
Whenever you play a land from exile or cast a spell from exile, put a +1/+1 counter on Ghost-Spider.
Remove two counters from Ghost-Spider: Exile the top card of your library. You may play that card this turn.
4/4
*/
private static final String gwenStacy = "Gwen Stacy";
private static final String ghostSpider = "Ghost-Spider";
@Test
@Ignore("Enable after transform mdfc rework")
public void testGhostSpider() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, gwenStacy);
addCard(Zone.BATTLEFIELD, playerA, "Plateau", 4);
addCard(Zone.BATTLEFIELD, playerA, "Island");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ghostSpider, true);
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, ghostSpider, CounterType.P1P1, 1);
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, ghostSpider, CounterType.CHARGE, 1);
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, ghostSpider, CounterType.P0P1, 1);
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Remove two counters");
setChoiceAmount(playerA, 1); // Charge
setChoiceAmount(playerA, 1); // P0P1
setChoiceAmount(playerA, 0); // P1P1
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Mountain");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, ghostSpider, 4 + 1 + 1, 4 + 1 + 1);
}
}

View file

@ -0,0 +1,86 @@
package org.mage.test.cards.single.war;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.TargetPlayer;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
import static org.junit.Assert.assertEquals;
/**
*
* @author Jmlundeen
*/
public class PriceOfBetrayalTest extends CardTestPlayerBase {
/*
Price of Betrayal
{B}
Sorcery
Remove up to five counters from target artifact, creature, planeswalker, or opponent.
*/
private static final String priceOfBetrayal = "Price of Betrayal";
/*
Bear Cub
{1}{G}
Creature - Bear
2/2
*/
private static final String bearCub = "Bear Cub";
@Test
public void testPriceOfBetrayalPermanent() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, priceOfBetrayal);
addCard(Zone.BATTLEFIELD, playerA, bearCub);
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, bearCub, CounterType.P1P1, 3);
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, bearCub, CounterType.CHARGE, 1);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, priceOfBetrayal, bearCub);
setChoiceAmount(playerA, 1); // charge counter
setChoiceAmount(playerA, 3); // P1P1 counter
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, bearCub, 2, 2);
}
@Test
public void testPriceOfBetrayalPlayer() {
setStrictChooseMode(true);
Ability ability = new SimpleActivatedAbility(
new AddCountersTargetEffect(CounterType.ENERGY.createInstance(5)),
new ManaCostsImpl<>("")
);
ability.addTarget(new TargetPlayer(1));
addCustomCardWithAbility("add counter", playerA, ability);
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
addCard(Zone.HAND, playerA, priceOfBetrayal);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target player gets", playerB);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, priceOfBetrayal, playerB);
setChoiceAmount(playerA, 5);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertEquals("Player should have no counters", 0, playerA.getCountersCount(CounterType.ENERGY));
}
}