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

@ -4,19 +4,15 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.RemoveUpToAmountCountersEffect;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetEnchantmentPermanent; import mage.target.common.TargetEnchantmentPermanent;
@ -54,7 +50,7 @@ public final class GlissaSunslayer extends CardImpl {
ability.addMode(mode); ability.addMode(mode);
// Remove up to three counters from target permanent. // Remove up to three counters from target permanent.
mode = new Mode(new GlissaSunslayerEffect()); mode = new Mode(new RemoveUpToAmountCountersEffect(3));
mode.addTarget(new TargetPermanent()); mode.addTarget(new TargetPermanent());
ability.addMode(mode); ability.addMode(mode);
@ -70,54 +66,3 @@ public final class GlissaSunslayer extends CardImpl {
return new GlissaSunslayer(this); return new GlissaSunslayer(this);
} }
} }
class GlissaSunslayerEffect extends OneShotEffect {
GlissaSunslayerEffect() {
super(Outcome.AIDontUseIt);
staticText = "Remove up to three counters from target permanent";
}
private GlissaSunslayerEffect(final GlissaSunslayerEffect effect) {
super(effect);
}
@Override
public GlissaSunslayerEffect copy() {
return new GlissaSunslayerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
int toRemove = 3;
int removed = 0;
String[] counterNames = permanent.getCounters(game).keySet().toArray(new String[0]);
for (String counterName : counterNames) {
if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) {
if (permanent.getCounters(game).get(counterName).getCount() == 1 || (toRemove - removed == 1)) {
permanent.removeCounters(counterName, 1, source, game);
removed++;
} else {
int amount = controller.getAmount(1, Math.min(permanent.getCounters(game).get(counterName).getCount(), toRemove - removed), "How many?", source, game);
if (amount > 0) {
removed += amount;
permanent.removeCounters(counterName, amount, source, game);
}
}
}
if (removed >= toRemove) {
break;
}
}
game.addEffect(new BoostSourceEffect(removed, 0, Duration.EndOfTurn), source);
return true;
}
return true;
}
}

View file

@ -53,7 +53,7 @@ public final class GwenStacy extends ModalDoubleFacedCard {
// Remove two counters from Ghost-Spider: Exile the top card of your library. You may play that card this turn. // Remove two counters from Ghost-Spider: Exile the top card of your library. You may play that card this turn.
this.getRightHalfCard().addAbility(new SimpleActivatedAbility( this.getRightHalfCard().addAbility(new SimpleActivatedAbility(
new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn),
new RemoveCountersSourceCost(CounterType.P1P1.createInstance(2)))); new RemoveCountersSourceCost(2)));
} }
private GwenStacy(final GwenStacy card) { private GwenStacy(final GwenStacy card) {

View file

@ -1,21 +1,14 @@
package mage.cards.h; package mage.cards.h;
import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.RemoveUpToAmountCountersEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.CounterAnyPredicate; import mage.filter.predicate.permanent.CounterAnyPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
@ -42,7 +35,7 @@ public final class HeartlessAct extends CardImpl {
this.getSpellAbility().addTarget(new TargetPermanent(filterWithoutCounters)); this.getSpellAbility().addTarget(new TargetPermanent(filterWithoutCounters));
// Remove up to three counters from target creature. // Remove up to three counters from target creature.
Mode mode = new Mode(new HeartlessActEffect()); Mode mode = new Mode(new RemoveUpToAmountCountersEffect(3));
mode.addTarget(new TargetCreaturePermanent()); mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode); this.getSpellAbility().addMode(mode);
} }
@ -56,54 +49,3 @@ public final class HeartlessAct extends CardImpl {
return new HeartlessAct(this); return new HeartlessAct(this);
} }
} }
class HeartlessActEffect extends OneShotEffect {
HeartlessActEffect() {
super(Outcome.AIDontUseIt);
staticText = "Remove up to three counters from target creature";
}
private HeartlessActEffect(final HeartlessActEffect effect) {
super(effect);
}
@Override
public HeartlessActEffect copy() {
return new HeartlessActEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
int toRemove = 3;
int removed = 0;
String[] counterNames = permanent.getCounters(game).keySet().toArray(new String[0]);
for (String counterName : counterNames) {
if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) {
if (permanent.getCounters(game).get(counterName).getCount() == 1 || (toRemove - removed == 1)) {
permanent.removeCounters(counterName, 1, source, game);
removed++;
} else {
int amount = controller.getAmount(1, Math.min(permanent.getCounters(game).get(counterName).getCount(), toRemove - removed), "How many?", source, game);
if (amount > 0) {
removed += amount;
permanent.removeCounters(counterName, amount, source, game);
}
}
}
if (removed >= toRemove) {
break;
}
}
game.addEffect(new BoostSourceEffect(removed, 0, Duration.EndOfTurn), source);
return true;
}
return true;
}
}

View file

@ -1,19 +1,13 @@
package mage.cards.p; package mage.cards.p;
import mage.abilities.Ability; import mage.abilities.effects.common.RemoveUpToAmountCountersEffect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.filter.FilterOpponent; import mage.filter.FilterOpponent;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.common.FilterPermanentOrPlayer; import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetPermanentOrPlayer; import mage.target.common.TargetPermanentOrPlayer;
import java.util.UUID; import java.util.UUID;
@ -39,7 +33,7 @@ public final class PriceOfBetrayal extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Remove up to five counters from target artifact, creature, planeswalker or opponent. // Remove up to five counters from target artifact, creature, planeswalker or opponent.
this.getSpellAbility().addEffect(new PriceOfBetrayalEffect()); this.getSpellAbility().addEffect(new RemoveUpToAmountCountersEffect(5));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(1, 1, filter2, false)); this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(1, 1, filter2, false));
} }
@ -52,81 +46,3 @@ public final class PriceOfBetrayal extends CardImpl {
return new PriceOfBetrayal(this); return new PriceOfBetrayal(this);
} }
} }
class PriceOfBetrayalEffect extends OneShotEffect {
PriceOfBetrayalEffect() {
super(Outcome.AIDontUseIt);
staticText = "Remove up to five counters from target artifact, creature, planeswalker, or opponent.";
}
private PriceOfBetrayalEffect(final PriceOfBetrayalEffect effect) {
super(effect);
}
@Override
public PriceOfBetrayalEffect copy() {
return new PriceOfBetrayalEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
// from permanent
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
int toRemove = 5;
int removed = 0;
String[] counterNames = permanent.getCounters(game).keySet().toArray(new String[0]);
for (String counterName : counterNames) {
if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) {
if (permanent.getCounters(game).get(counterName).getCount() == 1 || (toRemove - removed == 1)) {
permanent.removeCounters(counterName, 1, source, game);
removed++;
} else {
int amount = controller.getAmount(1, Math.min(permanent.getCounters(game).get(counterName).getCount(), toRemove - removed), "How many?", source, game);
if (amount > 0) {
removed += amount;
permanent.removeCounters(counterName, amount, source, game);
}
}
}
if (removed >= toRemove) {
break;
}
}
return true;
}
// from player
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
int toRemove = 5;
int removed = 0;
for (Counter counter : player.getCountersAsCopy().values()) {
String counterName = counter.getName();
if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) {
if (player.getCountersCount(counterName) == 1 || (toRemove - removed == 1)) {
player.loseCounters(counterName, 1, source, game);
removed++;
} else {
int amount = controller.getAmount(1, Math.min(player.getCountersCount(counterName), toRemove - removed), "How many?", source, game);
if (amount > 0) {
removed += amount;
player.loseCounters(counterName, amount, source, game);
}
}
}
if (removed >= toRemove) {
break;
}
}
return true;
}
return false;
}
}

View file

@ -1,15 +1,10 @@
package mage.cards.r; package mage.cards.r;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.RemoveUpToAmountCountersEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID; import java.util.UUID;
@ -23,7 +18,7 @@ public final class RenderInert extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Remove up to five counters from target permanent. // Remove up to five counters from target permanent.
this.getSpellAbility().addEffect(new RenderInertEffect()); this.getSpellAbility().addEffect(new RemoveUpToAmountCountersEffect(5));
this.getSpellAbility().addTarget(new TargetPermanent()); this.getSpellAbility().addTarget(new TargetPermanent());
// Draw a card. // Draw a card.
@ -39,50 +34,3 @@ public final class RenderInert extends CardImpl {
return new RenderInert(this); return new RenderInert(this);
} }
} }
class RenderInertEffect extends OneShotEffect {
RenderInertEffect() {
super(Outcome.Benefit);
staticText = "remove up to five counters from target permanent";
}
private RenderInertEffect(final RenderInertEffect effect) {
super(effect);
}
@Override
public RenderInertEffect copy() {
return new RenderInertEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller == null || permanent == null) {
return false;
}
int toRemove = 5;
int removed = 0;
String[] counterNames = permanent.getCounters(game).keySet().toArray(new String[0]);
for (String counterName : counterNames) {
if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) {
if (permanent.getCounters(game).get(counterName).getCount() == 1 || (toRemove - removed == 1)) {
permanent.removeCounters(counterName, 1, source, game);
removed++;
} else {
int amount = controller.getAmount(1, Math.min(permanent.getCounters(game).get(counterName).getCount(), toRemove - removed), "How many?", source, game);
if (amount > 0) {
removed += amount;
permanent.removeCounters(counterName, amount, source, game);
}
}
}
if (removed >= toRemove) {
break;
}
}
return true;
}
}

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

View file

@ -3,19 +3,15 @@ package mage.abilities.costs.common;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl; import mage.abilities.costs.CostImpl;
import mage.choices.Choice; import mage.constants.MultiAmountType;
import mage.choices.ChoiceImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.counters.Counter; import mage.counters.Counter;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.RandomUtil; import mage.util.CardUtil;
import java.util.Iterator; import java.util.*;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -31,6 +27,12 @@ public class RemoveCountersSourceCost extends CostImpl {
this.text = "remove a counter from {this}"; this.text = "remove a counter from {this}";
} }
public RemoveCountersSourceCost(int amount) {
this.amount = amount;
this.name = "";
this.text = "remove " + CardUtil.numberToText(amount) + " counters from {this}";
}
public RemoveCountersSourceCost(Counter counter) { public RemoveCountersSourceCost(Counter counter) {
this.amount = counter.getCount(); this.amount = counter.getCount();
this.name = counter.getName(); this.name = counter.getName();
@ -56,8 +58,8 @@ public class RemoveCountersSourceCost extends CostImpl {
.getCounters(game) .getCounters(game)
.values() .values()
.stream() .stream()
.map(Counter::getCount) .mapToInt(Counter::getCount)
.anyMatch(i -> i >= amount); .sum() >= amount;
} else { } else {
// specific counter // specific counter
return permanent.getCounters(game).getCount(name) >= amount; return permanent.getCounters(game).getCount(name) >= amount;
@ -71,36 +73,22 @@ public class RemoveCountersSourceCost extends CostImpl {
if (player == null || permanent == null) { if (player == null || permanent == null) {
return paid; return paid;
} }
String toRemove;
if (name.isEmpty()) { if (name.isEmpty()) {
Set<String> toChoose = new LinkedHashSet<>(permanent.getCounters(game).keySet()); List<String> toChoose = new ArrayList<>(permanent.getCounters(game).keySet());
switch (toChoose.size()) { if (toChoose.isEmpty()) {
case 0:
return paid; return paid;
case 1:
toRemove = RandomUtil.randomFromCollection(toChoose);
break;
case 2:
Iterator<String> iterator = toChoose.iterator();
String choice1 = iterator.next();
String choice2 = iterator.next();
toRemove = player.chooseUse(
Outcome.UnboostCreature, "Choose a type of counter to remove",
null, choice1, choice2, source, game
) ? choice1 : choice2;
break;
default:
Choice choice = new ChoiceImpl(true);
choice.setChoices(toChoose);
choice.setMessage("Choose a type of counter to remove");
player.choose(Outcome.UnboostCreature, choice, game);
toRemove = choice.getChoice();
}
} else { } else {
toRemove = name; List<Integer> counterList = player.getMultiAmount(Outcome.UnboostCreature, toChoose, 0, amount, amount, MultiAmountType.REMOVE_COUNTERS, game);
for (int i = 0; i < toChoose.size(); i++) {
int amountToRemove = counterList.get(i);
if (amountToRemove > 0) {
permanent.removeCounters(toChoose.get(i), amountToRemove, source, game);
} }
if (permanent.getCounters(game).getCount(toRemove) >= amount) { }
permanent.removeCounters(toRemove, amount, source, game); paid = true;
}
} else if (permanent.getCounters(game).getCount(name) >= amount){
permanent.removeCounters(name, amount, source, game);
this.paid = true; this.paid = true;
} }
return paid; return paid;

View file

@ -0,0 +1,86 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.MultiAmountType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.ArrayList;
import java.util.List;
public class RemoveUpToAmountCountersEffect extends OneShotEffect {
final DynamicValue amount;
public RemoveUpToAmountCountersEffect(int amount) {
super(Outcome.Neutral);
this.amount = StaticValue.get(amount);
}
public RemoveUpToAmountCountersEffect(DynamicValue amount) {
super(Outcome.Neutral);
this.amount = amount;
}
private RemoveUpToAmountCountersEffect(final RemoveUpToAmountCountersEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public RemoveUpToAmountCountersEffect copy() {
return new RemoveUpToAmountCountersEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
int max = this.amount.calculate(game, source, this);
// from permanent
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
List<String> toChoose = new ArrayList<>(permanent.getCounters(game).keySet());
List<Integer> counterList = controller.getMultiAmount(Outcome.UnboostCreature, toChoose, 0, 0, max, MultiAmountType.REMOVE_COUNTERS, game);
for (int i = 0; i < toChoose.size(); i++) {
int amountToRemove = counterList.get(i);
if (amountToRemove > 0) {
permanent.removeCounters(toChoose.get(i), amountToRemove, source, game);
}
}
return true;
}
// from player
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
List<String> toChoose = new ArrayList<>(player.getCountersAsCopy().keySet());
List<Integer> counterList = controller.getMultiAmount(Outcome.Neutral, toChoose, 0, 0, max, MultiAmountType.REMOVE_COUNTERS, game);
for (int i = 0; i < toChoose.size(); i++) {
int amountToRemove = counterList.get(i);
if (amountToRemove > 0) {
player.loseCounters(toChoose.get(i), amountToRemove, source, game);
}
}
return true;
}
return false;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return "remove up to " + CardUtil.numberToText(this.amount.toString()) + " counters from " + getTargetPointer().describeTargets(mode.getTargets(), "that permanent");
}
}

View file

@ -15,6 +15,7 @@ public class MultiAmountType {
public static final MultiAmountType P1P1 = new MultiAmountType("Add +1/+1 counters", "Distribute +1/+1 counters among creatures"); public static final MultiAmountType P1P1 = new MultiAmountType("Add +1/+1 counters", "Distribute +1/+1 counters among creatures");
public static final MultiAmountType COUNTERS = new MultiAmountType("Choose counters", "Move counters"); public static final MultiAmountType COUNTERS = new MultiAmountType("Choose counters", "Move counters");
public static final MultiAmountType REMOVE_COUNTERS = new MultiAmountType("Choose counters", "Remove counters");
public static final MultiAmountType CHEAT_LANDS = new MultiAmountType("Choose lands", "Add lands to your battlefield", true); public static final MultiAmountType CHEAT_LANDS = new MultiAmountType("Choose lands", "Add lands to your battlefield", true);
private final String title; private final String title;