Fix #9649 and clean up counter effect text generation

This commit is contained in:
Alex W. Jackson 2022-10-14 00:41:02 -04:00
parent 5ec2cd0378
commit 332db3aecb
17 changed files with 117 additions and 374 deletions

View file

@ -74,6 +74,9 @@ public class PutCounterOnCreatureTriggeredAbility extends TriggeredAbilityImpl {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (permanent == null) {
permanent = game.getPermanentEntering(event.getTargetId());
}
if (permanent == null || !filter.match(permanent, controllerId, this, game)) {
return false;
}

View file

@ -11,7 +11,6 @@ import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
import mage.util.RandomUtil;
import java.util.Iterator;
@ -27,19 +26,15 @@ public class RemoveCountersSourceCost extends CostImpl {
private final String name;
public RemoveCountersSourceCost() {
this((Counter) null);
this.amount = 1;
this.name = "";
this.text = "remove a counter from {this}";
}
public RemoveCountersSourceCost(Counter counter) {
this.amount = counter != null ? counter.getCount() : 1;
this.name = counter != null ? counter.getName() : "";
this.text = new StringBuilder("remove ")
.append((amount == 1 ? CounterType.findArticle(name) : CardUtil.numberToText(amount)))
.append(name.isEmpty() ? "" : (' ' + name))
.append(" counter")
.append((amount != 1 ? "s" : ""))
.append(" from {this}").toString();
this.amount = counter.getCount();
this.name = counter.getName();
this.text = "remove " + counter.getDescription() + " from {this}";
}
private RemoveCountersSourceCost(RemoveCountersSourceCost cost) {

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common.counter;
import mage.MageObject;
@ -6,14 +5,10 @@ import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.Locale;
/**
* @author North
@ -27,7 +22,7 @@ public class AddCountersAllEffect extends OneShotEffect {
super(Outcome.Benefit);
this.counter = counter;
this.filter = filter;
setText();
staticText = "put " + counter.getDescription() + " on each " + filter.getMessage();
}
public AddCountersAllEffect(final AddCountersAllEffect effect) {
@ -45,7 +40,7 @@ public class AddCountersAllEffect extends OneShotEffect {
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
permanent.addCounters(counter.copy(), source.getControllerId(), source, game);
if (!game.isSimulation()) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts " + counter.getCount() + ' ' + counter.getName().toLowerCase(Locale.ENGLISH)
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts " + counter.getCount() + ' ' + counter.getName()
+ " counter on " + permanent.getLogName());
}
}
@ -55,18 +50,6 @@ public class AddCountersAllEffect extends OneShotEffect {
return false;
}
private void setText() {
StringBuilder sb = new StringBuilder();
sb.append("put ");
if (counter.getCount() > 1) {
sb.append(CardUtil.numberToText(counter.getCount(), "a")).append(' ').append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counters on each ");
} else {
sb.append(CounterType.findArticle(counter.getName())).append(' ').append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counter on each ");
}
sb.append(filter.getMessage());
staticText = sb.toString();
}
@Override
public AddCountersAllEffect copy() {
return new AddCountersAllEffect(this);

View file

@ -6,13 +6,10 @@ import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.Locale;
/**
* @author LevelX2
*/
@ -20,7 +17,6 @@ public class AddCountersAttachedEffect extends OneShotEffect {
private Counter counter;
private DynamicValue amount;
private String textEnchanted;
public AddCountersAttachedEffect(Counter counter, String textEnchanted) {
this(counter, StaticValue.get(1), textEnchanted);
@ -35,8 +31,7 @@ public class AddCountersAttachedEffect extends OneShotEffect {
super(Outcome.Benefit);
this.counter = counter.copy();
this.amount = amount;
this.textEnchanted = textEnchanted;
setText();
staticText = CardUtil.getAddRemoveCountersText(amount, counter, textEnchanted, true);
}
public AddCountersAttachedEffect(final AddCountersAttachedEffect effect) {
@ -45,7 +40,6 @@ public class AddCountersAttachedEffect extends OneShotEffect {
this.counter = effect.counter.copy();
}
this.amount = effect.amount;
this.textEnchanted = effect.textEnchanted;
}
@Override
@ -67,38 +61,8 @@ public class AddCountersAttachedEffect extends OneShotEffect {
return false;
}
private void setText() {
if (!staticText.isEmpty()) {
return;
}
StringBuilder sb = new StringBuilder();
// put a +1/+1 counter on it
sb.append("put ");
boolean plural = true;
if (amount.toString().equals("X")) {
sb.append("X ");
} else if (counter.getCount() > 1) {
sb.append(CardUtil.numberToText(counter.getCount())).append(' ');
} else {
sb.append(CounterType.findArticle(counter.getName())).append(' ');
plural = false;
}
sb.append(counter.getName().toLowerCase(Locale.ENGLISH));
if (plural) {
sb.append(" counters on ");
} else {
sb.append(" counter on ");
}
sb.append(textEnchanted);
if (!amount.getMessage().isEmpty()) {
sb.append(" for each ").append(amount.getMessage());
}
staticText = sb.toString();
}
@Override
public AddCountersAttachedEffect copy() {
return new AddCountersAttachedEffect(this);
}
}

View file

@ -1,11 +1,9 @@
package mage.abilities.effects.common.counter;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -30,7 +28,7 @@ public class AddCountersControllerEffect extends OneShotEffect {
super(Outcome.Benefit);
this.counter = counter.copy();
this.enchantedEquipped = enchantedEquipped;
setText();
staticText = "its controller gets " + counter.getDescription();
}
public AddCountersControllerEffect(final AddCountersControllerEffect effect) {
@ -66,16 +64,6 @@ public class AddCountersControllerEffect extends OneShotEffect {
return false;
}
private void setText() {
if (counter.getCount() > 1) {
StringBuilder sb = new StringBuilder();
sb.append("its controller gets ").append(Integer.toString(counter.getCount())).append(' ').append(counter.getName()).append(" counters");
staticText = sb.toString();
} else {
staticText = "its controller gets " + CounterType.findArticle(counter.getName()) + " " + counter.getName() + " counter";
}
}
@Override
public AddCountersControllerEffect copy() {
return new AddCountersControllerEffect(this);

View file

@ -8,7 +8,6 @@ import mage.cards.Card;
import mage.constants.AbilityType;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -16,7 +15,6 @@ import mage.util.CardUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
/**
@ -54,7 +52,7 @@ public class AddCountersSourceEffect extends OneShotEffect {
this.informPlayers = informPlayers;
this.amount = amount;
this.putOnCard = putOnCard;
setText();
staticText = CardUtil.getAddRemoveCountersText(amount, counter, "{this}", true);
}
public AddCountersSourceEffect(final AddCountersSourceEffect effect) {
@ -95,7 +93,7 @@ public class AddCountersSourceEffect extends OneShotEffect {
if (informPlayers && !game.isSimulation()) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
game.informPlayers(player.getLogName() + " puts " + newCounter.getCount() + ' ' + newCounter.getName().toLowerCase(Locale.ENGLISH) + " counter on " + card.getLogName());
game.informPlayers(player.getLogName() + " puts " + newCounter.getCount() + ' ' + newCounter.getName() + " counter on " + card.getLogName());
}
}
return true;
@ -124,7 +122,7 @@ public class AddCountersSourceEffect extends OneShotEffect {
int amountAdded = permanent.getCounters(game).getCount(newCounter.getName()) - before;
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
game.informPlayers(player.getLogName() + " puts " + amountAdded + ' ' + newCounter.getName().toLowerCase(Locale.ENGLISH) + " counter on " + permanent.getLogName());
game.informPlayers(player.getLogName() + " puts " + amountAdded + ' ' + newCounter.getName() + " counter on " + permanent.getLogName());
}
}
}
@ -133,32 +131,8 @@ public class AddCountersSourceEffect extends OneShotEffect {
return true;
}
private void setText() {
StringBuilder sb = new StringBuilder();
sb.append("put ");
boolean plural = true;
if (counter.getCount() > 1) {
sb.append(CardUtil.numberToText(counter.getCount())).append(' ');
} else if (amount.toString().equals("X") && amount.getMessage().isEmpty()) {
sb.append("X ");
} else {
sb.append(CounterType.findArticle(counter.getName())).append(' ');
plural = false;
}
sb.append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counter");
if (plural) {
sb.append('s');
}
sb.append(" on {this}");
if (!amount.getMessage().isEmpty()) {
sb.append(" for each ").append(amount.getMessage());
}
staticText = sb.toString();
}
@Override
public AddCountersSourceEffect copy() {
return new AddCountersSourceEffect(this);
}
}

View file

@ -13,10 +13,8 @@ import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil;
import java.util.Locale;
import java.util.UUID;
/**
@ -79,17 +77,17 @@ public class AddCountersTargetEffect extends OneShotEffect {
permanent.addCounters(newCounter, source.getControllerId(), source, game);
affectedTargets++;
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts "
+ newCounter.getCount() + ' ' + newCounter.getName().toLowerCase(Locale.ENGLISH) + " counters on " + permanent.getLogName());
+ newCounter.getCount() + ' ' + newCounter.getName() + " counters on " + permanent.getLogName());
} else if (player != null) {
player.addCounters(newCounter, source.getControllerId(), source, game);
affectedTargets++;
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts "
+ newCounter.getCount() + ' ' + newCounter.getName().toLowerCase(Locale.ENGLISH) + " counters on " + player.getLogName());
+ newCounter.getCount() + ' ' + newCounter.getName() + " counters on " + player.getLogName());
} else if (card != null) {
card.addCounters(newCounter, source.getControllerId(), source, game);
affectedTargets++;
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts "
+ newCounter.getCount() + ' ' + newCounter.getName().toLowerCase(Locale.ENGLISH) + " counters on " + card.getLogName());
+ newCounter.getCount() + ' ' + newCounter.getName() + " counters on " + card.getLogName());
}
}
return affectedTargets > 0;
@ -102,51 +100,11 @@ public class AddCountersTargetEffect extends OneShotEffect {
if (!staticText.isEmpty()) {
return staticText;
}
StringBuilder sb = new StringBuilder();
sb.append("put ");
String counterName = counter.getName().toLowerCase(Locale.ENGLISH);
if (counter.getCount() > 1) {
sb.append(CardUtil.numberToText(counter.getCount())).append(' ');
} else {
sb.append(CounterType.findArticle(counterName)).append(' ');
}
sb.append(counterName).append(" counter");
if (counter.getCount() > 1) {
sb.append('s');
}
sb.append(" on ");
Target target = mode.getTargets().getEffectTarget(this.targetPointer);
if (target != null) {
if (target.getNumberOfTargets() == 0) {
if (target.getMaxNumberOfTargets() > 1) {
sb.append("each of ");
}
sb.append("up to ");
}
if (target.getMaxNumberOfTargets() > 1 || target.getNumberOfTargets() == 0) {
sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets()))
.append(" target ").append(target.getTargetName());
} else {
if (!target.getTargetName().startsWith("another")) {
sb.append("target ");
}
sb.append(target.getTargetName());
}
} else {
sb.append("that creature");
}
if (!amount.getMessage().isEmpty()) {
sb.append(" for each ").append(amount.getMessage());
}
return sb.toString();
return CardUtil.getAddRemoveCountersText(amount, counter, getTargetPointer().describeTargets(mode.getTargets(), "that creature"), true);
}
@Override
public AddCountersTargetEffect copy() {
return new AddCountersTargetEffect(this);
}
}

View file

@ -1,101 +0,0 @@
package mage.abilities.effects.common.counter;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.filter.Filter;
import mage.game.Game;
import mage.players.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* @author Gal Lerman
*/
public class AddRemoveAllTimeSuspentCountersEffect extends OneShotEffect {
private final Counter counter;
private final Filter<Card> filter;
private final boolean removeCounter;
private final String actionStr;
public AddRemoveAllTimeSuspentCountersEffect(Counter counter, Filter<Card> filter, boolean removeCounter) {
super(Outcome.Benefit);
this.counter = counter;
this.filter = filter;
this.removeCounter = removeCounter;
actionStr = removeCounter ? " removes " : " puts ";
setText();
}
public AddRemoveAllTimeSuspentCountersEffect(final AddRemoveAllTimeSuspentCountersEffect effect) {
super(effect);
this.counter = effect.counter.copy();
this.filter = effect.filter.copy();
this.removeCounter = effect.removeCounter;
this.actionStr = effect.actionStr;
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
if (counter != null) {
List<Card> permanents = new ArrayList<>(game.getBattlefield().getAllActivePermanents());
execute(game, controller, sourceObject, source, permanents, removeCounter);
final List<Card> exiledCards = game.getExile().getAllCards(game);
execute(game, controller, sourceObject, source, exiledCards, removeCounter);
}
return true;
}
return false;
}
private void execute(final Game game, final Player controller, final MageObject sourceObject, Ability source, final List<Card> cards, final boolean removeCounter) {
for (Card card : cards) {
if (filter.match(card, game)) {
final String counterName = counter.getName();
if (removeCounter) {
final Counter existingCounterOfSameType = card.getCounters(game).get(counterName);
final int countersToRemove = Math.min(existingCounterOfSameType.getCount(), counter.getCount());
final Counter modifiedCounter = new Counter(counterName, countersToRemove);
card.removeCounters(modifiedCounter, source, game);
} else {
card.addCounters(counter, source.getControllerId(), source, game);
}
if (!game.isSimulation()) {
game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ")
.append(controller.getLogName()).append(actionStr)
.append(counter.getCount()).append(' ').append(counterName.toLowerCase(Locale.ENGLISH))
.append(" counter on ").append(card.getName()).toString());
}
}
}
}
private void setText() {
StringBuilder sb = new StringBuilder();
final String actionsStr2 = removeCounter ? "remove " : " put ";
sb.append(actionsStr2);
if (counter.getCount() > 1) {
sb.append(Integer.toString(counter.getCount())).append(' ').append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counters on each ");
} else {
sb.append(CounterType.findArticle(counter.getName())).append(' ').append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counter on each ");
}
sb.append(filter.getMessage());
staticText = sb.toString();
}
@Override
public AddRemoveAllTimeSuspentCountersEffect copy() {
return new AddRemoveAllTimeSuspentCountersEffect(this);
}
}

View file

@ -5,10 +5,8 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
/**
* @author Loki
@ -20,7 +18,7 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
public RemoveCounterSourceEffect(Counter counter) {
super(Outcome.UnboostCreature);
this.counter = counter;
setText();
staticText = "remove " + counter.getDescription() + " from {this}";
}
public RemoveCounterSourceEffect(RemoveCounterSourceEffect effect) {
@ -63,14 +61,4 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
public RemoveCounterSourceEffect copy() {
return new RemoveCounterSourceEffect(this);
}
private void setText() {
if (counter.getCount() > 1) {
StringBuilder sb = new StringBuilder();
sb.append("remove ").append(CardUtil.numberToText(counter.getCount())).append(' ').append(counter.getName()).append(" counters from {this}");
staticText = sb.toString();
} else {
staticText = "remove " + CounterType.findArticle(counter.getName()) + " " + counter.getName() + " counter from {this}";
}
}
}

View file

@ -8,11 +8,9 @@ import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.HashSet;
import java.util.Set;
@ -41,7 +39,7 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent p = game.getPermanent(targetPointer.getFirst(game, source));
Permanent p = game.getPermanent(getTargetPointer().getFirst(game, source));
if (p != null) {
Counter toRemove = (counter == null ? selectCounterType(game, source, p) : counter);
if (toRemove != null && p.getCounters(game).getCount(toRemove.getName()) >= toRemove.getCount()) {
@ -52,7 +50,7 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
}
}
} else {
Card c = game.getCard(targetPointer.getFirst(game, source));
Card c = game.getCard(getTargetPointer().getFirst(game, source));
if (c != null && counter != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) {
c.removeCounters(counter.getName(), counter.getCount(), source, game);
if (!game.isSimulation()) {
@ -106,15 +104,9 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
String text = "remove ";
if (counter == null) {
text += "a counter";
} else {
text += CardUtil.numberToText(counter.getCount(), CounterType.findArticle(counter.getName())) + ' ' + counter.getName();
text += counter.getCount() > 1 ? " counters" : " counter";
}
text += " from target " + (mode.getTargets().isEmpty() ? " object" : mode.getTargets().get(0).getTargetName());
return text;
return "remove "
+ (counter == null ? "a counter" : counter.getDescription())
+ " from "
+ getTargetPointer().describeTargets(mode.getTargets(), "that creature");
}
}

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common.counter;
import mage.abilities.Ability;
@ -7,13 +6,10 @@ import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.Locale;
/**
* @author noahg
*/
@ -21,7 +17,6 @@ public class RemoveCountersAttachedEffect extends OneShotEffect {
private Counter counter;
private DynamicValue amount;
private String textEnchanted;
public RemoveCountersAttachedEffect(Counter counter, String textEnchanted) {
this(counter, StaticValue.get(0), textEnchanted);
@ -36,8 +31,7 @@ public class RemoveCountersAttachedEffect extends OneShotEffect {
super(Outcome.UnboostCreature);
this.counter = counter.copy();
this.amount = amount;
this.textEnchanted = textEnchanted;
setText();
this.staticText = CardUtil.getAddRemoveCountersText(amount, counter, textEnchanted, false);
}
public RemoveCountersAttachedEffect(final RemoveCountersAttachedEffect effect) {
@ -46,7 +40,6 @@ public class RemoveCountersAttachedEffect extends OneShotEffect {
this.counter = effect.counter.copy();
}
this.amount = effect.amount;
this.textEnchanted = effect.textEnchanted;
}
@Override
@ -64,27 +57,8 @@ public class RemoveCountersAttachedEffect extends OneShotEffect {
return false;
}
private void setText() {
StringBuilder sb = new StringBuilder();
// put a +1/+1 counter on it
sb.append("remove ");
if (counter.getCount() > 1) {
sb.append(CardUtil.numberToText(counter.getCount())).append(' ');
sb.append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counters from ");
} else {
sb.append(CounterType.findArticle(counter.getName())).append(' ');
sb.append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counter from ");
}
sb.append(textEnchanted);
if (!amount.getMessage().isEmpty()) {
sb.append(" for each ").append(amount.getMessage());
}
staticText = sb.toString();
}
@Override
public RemoveCountersAttachedEffect copy() {
return new RemoveCountersAttachedEffect(this);
}
}