Refactor SourceHasCounterCondition to be an IntCompareCondition (#13724)

* refactor SourceHasCounterCondition to be an IntCompareCondition

* add comment for arguments
This commit is contained in:
Evan Kranzler 2025-06-07 21:03:21 -04:00 committed by GitHub
parent c7f2263ddb
commit 0e179ccc1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
61 changed files with 697 additions and 706 deletions

View file

@ -23,7 +23,11 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
* zone = BATTLEFIELD optional = false
*/
public EntersBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter) {
this(Zone.BATTLEFIELD, effect, filter, false);
this(effect, filter, false);
}
public EntersBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) {
this(Zone.BATTLEFIELD, effect, filter, optional);
}
public EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) {

View file

@ -1,86 +1,87 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.cards.Card;
import mage.abilities.condition.IntCompareCondition;
import mage.constants.ComparisonType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.Optional;
/**
* @author nantuko
* Don't use ComparisonType.OR_GREATER with value 0
*
* @author TheElk801
*/
public class SourceHasCounterCondition implements Condition {
public class SourceHasCounterCondition extends IntCompareCondition {
private final CounterType counterType;
private int amount = 1;
private int from = -1;
private int to;
public SourceHasCounterCondition(CounterType type) {
this.counterType = type;
public SourceHasCounterCondition(CounterType counterType) {
this(counterType, 1);
}
public SourceHasCounterCondition(CounterType type, int amount) {
this.counterType = type;
this.amount = amount;
public SourceHasCounterCondition(CounterType counterType, int amount) {
this(counterType, ComparisonType.OR_GREATER, amount);
}
public SourceHasCounterCondition(CounterType type, int from, int to) {
this.counterType = type;
this.from = from;
this.to = to;
public SourceHasCounterCondition(CounterType counterType, ComparisonType type, int value) {
super(type, value);
this.counterType = counterType;
}
@Override
@SuppressWarnings("null")
public boolean apply(Game game, Ability source) {
Card card = null;
protected int getInputValue(Game game, Ability source) {
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (permanent == null) {
card = game.getCard(source.getSourceId());
if (card == null) {
return false;
}
}
if (from != -1) { //range compare
int count;
if (card != null) {
count = card.getCounters(game).getCount(counterType);
} else {
count = permanent.getCounters(game).getCount(counterType);
}
if (to == Integer.MAX_VALUE) {
return count >= from;
}
return count >= from && count <= to;
} else // single compare (lte)
{
if (card != null) {
return card.getCounters(game).getCount(counterType) >= amount;
} else {
return permanent.getCounters(game).getCount(counterType) >= amount;
}
if (permanent != null) {
return permanent.getCounters(game).getCount(counterType);
}
return Optional.ofNullable(source)
.map(Ability::getSourceId)
.map(game::getCard)
.map(card -> card.getCounters(game).getCount(counterType))
.orElse(0);
}
@Override
public String toString() {
if (from != -1) {
if (from == 0) {
if (to == 0) {
return "{this} has no " + this.counterType.toString() + " counters on it";
switch (type) {
case EQUAL_TO:
StringBuilder sb = new StringBuilder("there ");
switch (value) {
case 0:
sb.append("are no ");
break;
case 1:
sb.append("is exactly one ");
break;
default:
sb.append("are exactly ");
sb.append(CardUtil.numberToText(value));
sb.append(' ');
}
return "{this} has " + CardUtil.numberToText(to) + " or fewer " + this.counterType.toString() + " counters on it";
}
if (to == Integer.MAX_VALUE) {
return "{this} has " + CardUtil.numberToText(from) + " or more " + this.counterType.toString() + " counters on it";
}
return "{this} has between " + from + " and " + to + " " + this.counterType.toString() + " counters on it";
} else {
return "{this} has " + CardUtil.numberToText(amount) + " or more " + this.counterType.toString() + " counters on it";
sb.append(counterType.getName());
sb.append(" counter");
if (value != 1) {
sb.append('s');
}
sb.append(" on {this}");
return sb.toString();
case OR_GREATER:
if (value == 0) {
throw new IllegalArgumentException("0 or greater should not be used");
}
return "there are " + CardUtil.numberToText(value) + " or more " + counterType.getName() + " counters on {this}";
case OR_LESS:
return "{this} has " + CardUtil.numberToText(value) + " or fewer " + counterType.getName() + " counters on it";
case FEWER_THAN:
return "{this} has fewer than " + CardUtil.numberToText(value) + ' ' + counterType.getName() + " counters on it";
case MORE_THAN:
return "{this} has more than " + CardUtil.numberToText(value) + ' ' + counterType.getName() + " counters on it";
default:
throw new UnsupportedOperationException("There should be a comparison type");
}
}
}

View file

@ -1,7 +1,6 @@
package mage.abilities.keyword;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
@ -13,6 +12,7 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.AddContinuousEffectToGame;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
@ -37,7 +37,7 @@ public class ImpendingAbility extends AlternativeSourceCostsImpl {
private static final String IMPENDING_REMINDER = "If you cast this spell for its impending cost, " +
"it enters with %s time counters and isn't a creature until the last is removed. " +
"At the beginning of your end step, remove a time counter from it.";
private static final Condition counterCondition = new SourceHasCounterCondition(CounterType.TIME, 0, 0);
private static final Condition counterCondition = new SourceHasCounterCondition(CounterType.TIME, ComparisonType.EQUAL_TO, 0);
public ImpendingAbility(int amount, String manaString) {
super(IMPENDING_KEYWORD + ' ' + amount, String.format(IMPENDING_REMINDER, CardUtil.numberToText(amount)), new ManaCostsImpl<>(manaString), IMPENDING_KEYWORD);

View file

@ -4,14 +4,15 @@ import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.CompoundCondition;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.counters.CounterType;
import java.util.ArrayList;
@ -46,7 +47,11 @@ public class LevelerCardBuilder {
public List<Ability> build() {
List<Ability> constructed = new ArrayList<>();
Condition condition = new SourceHasCounterCondition(CounterType.LEVEL, level1, level2);
Condition condition = new CompoundCondition(
"",
new SourceHasCounterCondition(CounterType.LEVEL, ComparisonType.OR_GREATER, level1),
new SourceHasCounterCondition(CounterType.LEVEL, ComparisonType.OR_LESS, level2)
);
for (Ability ability : abilities) {
ContinuousEffect effect = new GainAbilitySourceEffect(ability);
ConditionalContinuousEffect abEffect = new ConditionalContinuousEffect(effect, condition, "");

View file

@ -11,7 +11,7 @@ import mage.constants.SubType;
public final class PilotCrewToken extends TokenImpl {
public PilotCrewToken() {
super("Pilot Token", "1/1 colorless Pilot creature token with \"This creature crews Vehicles as though its power were 2 greater.\"");
super("Pilot Token", "1/1 colorless Pilot creature token with \"This token crews Vehicles as though its power were 2 greater.\"");
cardType.add(CardType.CREATURE);
subtype.add(SubType.PILOT);
power = new MageInt(1);