mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
CounterType: turn wrapper into an interface (#8572)
* CounterType: turn wrapper into an interface * remove CounterType.get(CounterEnumType) helper
This commit is contained in:
@@ -563,7 +563,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
int thisRemove = Math.min(prefCard.getCounters(cType), stillToRemove);
|
||||
if (thisRemove > 0) {
|
||||
removed += thisRemove;
|
||||
table.put(null, prefCard, CounterType.get(cType), thisRemove);
|
||||
table.put(null, prefCard, cType, thisRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,7 +573,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
@Override
|
||||
public PaymentDecision visit(CostRemoveAnyCounter cost) {
|
||||
final int c = cost.getAbilityAmount(ability);
|
||||
final Card originalHost = ObjectUtils.defaultIfNull(ability.getOriginalHost(), source);
|
||||
final Card originalHost = ObjectUtils.getIfNull(ability.getOriginalHost(), source);
|
||||
|
||||
if (c <= 0) {
|
||||
return null;
|
||||
@@ -716,7 +716,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
int over = Math.min(crd.getCounters(CounterEnumType.QUEST) - e, c - toRemove);
|
||||
if (over > 0) {
|
||||
toRemove += over;
|
||||
table.put(null, crd, CounterType.get(CounterEnumType.QUEST), over);
|
||||
table.put(null, crd, CounterEnumType.QUEST, over);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ public class ComputerUtil {
|
||||
public static CardCollection chooseUntapType(final Player ai, final String type, final Card activate, final boolean untap, final int amount, SpellAbility sa) {
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, sa);
|
||||
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterType.get(CounterEnumType.STUN)));
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterEnumType.STUN));
|
||||
|
||||
if (untap) {
|
||||
typeList.remove(activate);
|
||||
@@ -2542,7 +2542,7 @@ public class ComputerUtil {
|
||||
|
||||
boolean opponent = controller.isOpponentOf(ai);
|
||||
|
||||
final CounterType p1p1Type = CounterType.get(CounterEnumType.P1P1);
|
||||
final CounterType p1p1Type = CounterEnumType.P1P1;
|
||||
|
||||
if (!sa.hasParam("AILogic")) {
|
||||
return Aggregates.random(options);
|
||||
|
||||
@@ -171,7 +171,7 @@ public class SpecialAiLogic {
|
||||
final boolean isInfect = source.hasKeyword(Keyword.INFECT); // Flesh-Eater Imp
|
||||
int lethalDmg = isInfect ? 10 - defPlayer.getPoisonCounters() : defPlayer.getLife();
|
||||
|
||||
if (isInfect && !combat.getDefenderByAttacker(source).canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
if (isInfect && !combat.getDefenderByAttacker(source).canReceiveCounters(CounterEnumType.POISON)) {
|
||||
lethalDmg = Integer.MAX_VALUE; // won't be able to deal poison damage to kill the opponent
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ public class SpecialAiLogic {
|
||||
final boolean isInfect = source.hasKeyword(Keyword.INFECT);
|
||||
int lethalDmg = isInfect ? 10 - defPlayer.getPoisonCounters() : defPlayer.getLife();
|
||||
|
||||
if (isInfect && !combat.getDefenderByAttacker(source).canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
if (isInfect && !combat.getDefenderByAttacker(source).canReceiveCounters(CounterEnumType.POISON)) {
|
||||
lethalDmg = Integer.MAX_VALUE; // won't be able to deal poison damage to kill the opponent
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public abstract class CountersAi extends SpellAbilityAi {
|
||||
} else if (type.equals("DIVINITY")) {
|
||||
final CardCollection boon = CardLists.filter(list, c -> c.getCounters(CounterEnumType.DIVINITY) == 0);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(boon);
|
||||
} else if (CounterType.get(type).isKeywordCounter()) {
|
||||
} else if (CounterType.getType(type).isKeywordCounter()) {
|
||||
choice = ComputerUtilCard.getBestCreatureAI(CardLists.getNotKeyword(list, type));
|
||||
} else {
|
||||
// The AI really should put counters on cards that can use it.
|
||||
|
||||
@@ -154,7 +154,7 @@ public class CountersMultiplyAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (counterType == null || counterType.is(type)) {
|
||||
addTargetsByCounterType(ai, sa, aiList, CounterType.get(type));
|
||||
addTargetsByCounterType(ai, sa, aiList, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,7 @@ public class CountersMultiplyAi extends SpellAbilityAi {
|
||||
if (!oppList.isEmpty()) {
|
||||
// not enough targets
|
||||
if (sa.canAddMoreTarget()) {
|
||||
final CounterType type = CounterType.get(CounterEnumType.M1M1);
|
||||
final CounterType type = CounterEnumType.M1M1;
|
||||
if (counterType == null || counterType == type) {
|
||||
addTargetsByCounterType(ai, sa, oppList, type);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class CountersProliferateAi extends SpellAbilityAi {
|
||||
public <T extends GameEntity> T chooseSingleEntity(Player ai, SpellAbility sa, Collection<T> options, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
|
||||
// Proliferate is always optional for all, no need to select best
|
||||
|
||||
final CounterType poison = CounterType.get(CounterEnumType.POISON);
|
||||
final CounterType poison = CounterEnumType.POISON;
|
||||
|
||||
boolean aggroAI = (((PlayerControllerAi) ai.getController()).getAi()).getBooleanProperty(AiProps.PLAY_AGGRO);
|
||||
// because countertype can't be chosen anymore, only look for poison counters
|
||||
|
||||
@@ -170,7 +170,7 @@ public class CountersPutAi extends CountersAi {
|
||||
CardCollection oppCreatM1 = CardLists.filter(oppCreat, CardPredicates.hasCounter(CounterEnumType.M1M1));
|
||||
oppCreatM1 = CardLists.getNotKeyword(oppCreatM1, Keyword.UNDYING);
|
||||
|
||||
oppCreatM1 = CardLists.filter(oppCreatM1, input -> input.getNetToughness() <= 1 && input.canReceiveCounters(CounterType.get(CounterEnumType.M1M1)));
|
||||
oppCreatM1 = CardLists.filter(oppCreatM1, input -> input.getNetToughness() <= 1 && input.canReceiveCounters(CounterEnumType.M1M1));
|
||||
|
||||
Card best = ComputerUtilCard.getBestAI(oppCreatM1);
|
||||
if (best != null) {
|
||||
@@ -336,7 +336,7 @@ public class CountersPutAi extends CountersAi {
|
||||
Game game = ai.getGame();
|
||||
Combat combat = game.getCombat();
|
||||
|
||||
if (!source.canReceiveCounters(CounterType.get(CounterEnumType.P1P1)) || source.getCounters(CounterEnumType.P1P1) > 0) {
|
||||
if (!source.canReceiveCounters(CounterEnumType.P1P1) || source.getCounters(CounterEnumType.P1P1) > 0) {
|
||||
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
|
||||
} else if (combat != null && ph.is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||
return doCombatAdaptLogic(source, amount, combat);
|
||||
@@ -608,7 +608,7 @@ public class CountersPutAi extends CountersAi {
|
||||
return new AiAbilityDecision(0, AiPlayDecision.MissingNeededCards);
|
||||
}
|
||||
|
||||
final int currCounters = cards.get(0).getCounters(CounterType.get(type));
|
||||
final int currCounters = cards.get(0).getCounters(CounterType.getType(type));
|
||||
// each non +1/+1 counter on the card is a 10% chance of not
|
||||
// activating this ability.
|
||||
|
||||
@@ -623,7 +623,7 @@ public class CountersPutAi extends CountersAi {
|
||||
}
|
||||
|
||||
// Useless since the card already has the keyword (or for another reason)
|
||||
if (ComputerUtil.isUselessCounter(CounterType.get(type), cards.get(0))) {
|
||||
if (ComputerUtil.isUselessCounter(CounterType.getType(type), cards.get(0))) {
|
||||
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
|
||||
}
|
||||
}
|
||||
@@ -961,8 +961,8 @@ public class CountersPutAi extends CountersAi {
|
||||
protected Card chooseSingleCard(final Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
|
||||
// Bolster does use this
|
||||
// TODO need more or less logic there?
|
||||
final CounterType m1m1 = CounterType.get(CounterEnumType.M1M1);
|
||||
final CounterType p1p1 = CounterType.get(CounterEnumType.P1P1);
|
||||
final CounterType m1m1 = CounterEnumType.M1M1;
|
||||
final CounterType p1p1 = CounterEnumType.P1P1;
|
||||
|
||||
// no logic if there is no options or no to choice
|
||||
if (!isOptional && Iterables.size(options) <= 1) {
|
||||
@@ -1083,8 +1083,8 @@ public class CountersPutAi extends CountersAi {
|
||||
if (e instanceof Card) {
|
||||
Card c = (Card) e;
|
||||
if (c.getController().isOpponentOf(ai)) {
|
||||
if (options.contains(CounterType.get(CounterEnumType.M1M1)) && !c.hasKeyword(Keyword.UNDYING)) {
|
||||
return CounterType.get(CounterEnumType.M1M1);
|
||||
if (options.contains(CounterEnumType.M1M1) && !c.hasKeyword(Keyword.UNDYING)) {
|
||||
return CounterEnumType.M1M1;
|
||||
}
|
||||
for (CounterType type : options) {
|
||||
if (ComputerUtil.isNegativeCounter(type, c)) {
|
||||
@@ -1101,12 +1101,12 @@ public class CountersPutAi extends CountersAi {
|
||||
} else if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
if (p.isOpponentOf(ai)) {
|
||||
if (options.contains(CounterType.get(CounterEnumType.POISON))) {
|
||||
return CounterType.get(CounterEnumType.POISON);
|
||||
if (options.contains(CounterEnumType.POISON)) {
|
||||
return CounterEnumType.POISON;
|
||||
}
|
||||
} else {
|
||||
if (options.contains(CounterType.get(CounterEnumType.EXPERIENCE))) {
|
||||
return CounterType.get(CounterEnumType.EXPERIENCE);
|
||||
if (options.contains(CounterEnumType.EXPERIENCE)) {
|
||||
return CounterEnumType.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,18 +218,18 @@ public class CountersPutOrRemoveAi extends SpellAbilityAi {
|
||||
Card tgt = (Card) params.get("Target");
|
||||
|
||||
// planeswalker has high priority for loyalty counters
|
||||
if (tgt.isPlaneswalker() && options.contains(CounterType.get(CounterEnumType.LOYALTY))) {
|
||||
return CounterType.get(CounterEnumType.LOYALTY);
|
||||
if (tgt.isPlaneswalker() && options.contains(CounterEnumType.LOYALTY)) {
|
||||
return CounterEnumType.LOYALTY;
|
||||
}
|
||||
|
||||
if (tgt.getController().isOpponentOf(ai)) {
|
||||
// creatures with BaseToughness below or equal zero might be
|
||||
// killed if their counters are removed
|
||||
if (tgt.isCreature() && tgt.getBaseToughness() <= 0) {
|
||||
if (options.contains(CounterType.get(CounterEnumType.P1P1))) {
|
||||
return CounterType.get(CounterEnumType.P1P1);
|
||||
} else if (options.contains(CounterType.get(CounterEnumType.M1M1))) {
|
||||
return CounterType.get(CounterEnumType.M1M1);
|
||||
if (options.contains(CounterEnumType.P1P1)) {
|
||||
return CounterEnumType.P1P1;
|
||||
} else if (options.contains(CounterEnumType.M1M1)) {
|
||||
return CounterEnumType.M1M1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,17 +241,17 @@ public class CountersPutOrRemoveAi extends SpellAbilityAi {
|
||||
}
|
||||
} else {
|
||||
// this counters are treat first to be removed
|
||||
if ("Dark Depths".equals(tgt.getName()) && options.contains(CounterType.get(CounterEnumType.ICE))) {
|
||||
if ("Dark Depths".equals(tgt.getName()) && options.contains(CounterEnumType.ICE)) {
|
||||
CardCollectionView marit = ai.getCardsIn(ZoneType.Battlefield, "Marit Lage");
|
||||
boolean maritEmpty = marit.isEmpty() || Iterables.contains(marit, (Predicate<Card>) Card::ignoreLegendRule);
|
||||
|
||||
if (maritEmpty) {
|
||||
return CounterType.get(CounterEnumType.ICE);
|
||||
return CounterEnumType.ICE;
|
||||
}
|
||||
} else if (tgt.hasKeyword(Keyword.UNDYING) && options.contains(CounterType.get(CounterEnumType.P1P1))) {
|
||||
return CounterType.get(CounterEnumType.P1P1);
|
||||
} else if (tgt.hasKeyword(Keyword.PERSIST) && options.contains(CounterType.get(CounterEnumType.M1M1))) {
|
||||
return CounterType.get(CounterEnumType.M1M1);
|
||||
} else if (tgt.hasKeyword(Keyword.UNDYING) && options.contains(CounterEnumType.P1P1)) {
|
||||
return CounterEnumType.P1P1;
|
||||
} else if (tgt.hasKeyword(Keyword.PERSIST) && options.contains(CounterEnumType.M1M1)) {
|
||||
return CounterEnumType.M1M1;
|
||||
}
|
||||
|
||||
// fallback logic, select positive counter to add more
|
||||
|
||||
@@ -384,7 +384,7 @@ public class CountersRemoveAi extends SpellAbilityAi {
|
||||
if (targetCard.getController().isOpponentOf(ai)) {
|
||||
// if its a Planeswalker try to remove Loyality first
|
||||
if (targetCard.isPlaneswalker()) {
|
||||
return CounterType.get(CounterEnumType.LOYALTY);
|
||||
return CounterEnumType.LOYALTY;
|
||||
}
|
||||
for (CounterType type : options) {
|
||||
if (!ComputerUtil.isNegativeCounter(type, targetCard)) {
|
||||
@@ -392,10 +392,10 @@ public class CountersRemoveAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.contains(CounterType.get(CounterEnumType.M1M1)) && targetCard.hasKeyword(Keyword.PERSIST)) {
|
||||
return CounterType.get(CounterEnumType.M1M1);
|
||||
} else if (options.contains(CounterType.get(CounterEnumType.P1P1)) && targetCard.hasKeyword(Keyword.UNDYING)) {
|
||||
return CounterType.get(CounterEnumType.P1P1);
|
||||
if (options.contains(CounterEnumType.M1M1) && targetCard.hasKeyword(Keyword.PERSIST)) {
|
||||
return CounterEnumType.M1M1;
|
||||
} else if (options.contains(CounterEnumType.P1P1) && targetCard.hasKeyword(Keyword.UNDYING)) {
|
||||
return CounterEnumType.P1P1;
|
||||
}
|
||||
for (CounterType type : options) {
|
||||
if (ComputerUtil.isNegativeCounter(type, targetCard)) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.cost.*;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -370,7 +369,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
|
||||
// try to make opponent lose to poison
|
||||
// currently only Caress of Phyrexia
|
||||
if (getPoison != null && oppA.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
if (getPoison != null && oppA.canReceiveCounters(CounterEnumType.POISON)) {
|
||||
if (oppA.getPoisonCounters() + numCards > 9) {
|
||||
sa.getTargets().add(oppA);
|
||||
return true;
|
||||
@@ -414,7 +413,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
if (getPoison != null && ai.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
if (getPoison != null && ai.canReceiveCounters(CounterEnumType.POISON)) {
|
||||
if (numCards + ai.getPoisonCounters() >= 8) {
|
||||
aiTarget = false;
|
||||
}
|
||||
@@ -472,7 +471,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
// ally would lose because of poison
|
||||
if (getPoison != null && ally.canReceiveCounters(CounterType.get(CounterEnumType.POISON)) && ally.getPoisonCounters() + numCards > 9) {
|
||||
if (getPoison != null && ally.canReceiveCounters(CounterEnumType.POISON) && ally.getPoisonCounters() + numCards > 9) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ public class ManaAi extends SpellAbilityAi {
|
||||
int numCounters = 0;
|
||||
int manaSurplus = 0;
|
||||
if ("Count$xPaid".equals(host.getSVar("X")) && sa.getPayCosts().hasSpecificCostType(CostRemoveCounter.class)) {
|
||||
CounterType ctrType = CounterType.get(CounterEnumType.KI); // Petalmane Baku
|
||||
CounterType ctrType = CounterEnumType.KI; // Petalmane Baku
|
||||
for (CostPart part : sa.getPayCosts().getCostParts()) {
|
||||
if (part instanceof CostRemoveCounter) {
|
||||
ctrType = ((CostRemoveCounter)part).counter;
|
||||
|
||||
@@ -6,7 +6,6 @@ import forge.ai.ComputerUtil;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.GameLossReason;
|
||||
@@ -65,7 +64,7 @@ public class PoisonAi extends SpellAbilityAi {
|
||||
boolean result;
|
||||
if (sa.usesTargeting()) {
|
||||
result = tgtPlayer(ai, sa, mandatory);
|
||||
} else if (mandatory || !ai.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
} else if (mandatory || !ai.canReceiveCounters(CounterEnumType.POISON)) {
|
||||
// mandatory or ai is uneffected
|
||||
result = true;
|
||||
} else {
|
||||
@@ -90,7 +89,7 @@ public class PoisonAi extends SpellAbilityAi {
|
||||
PlayerCollection betterTgts = tgts.filter(input -> {
|
||||
if (input.cantLoseCheck(GameLossReason.Poisoned)) {
|
||||
return false;
|
||||
} else if (!input.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
} else if (!input.canReceiveCounters(CounterEnumType.POISON)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -109,7 +108,7 @@ public class PoisonAi extends SpellAbilityAi {
|
||||
if (tgts.isEmpty()) {
|
||||
if (mandatory) {
|
||||
// AI is uneffected
|
||||
if (ai.canBeTargetedBy(sa) && !ai.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) {
|
||||
if (ai.canBeTargetedBy(sa) && !ai.canReceiveCounters(CounterEnumType.POISON)) {
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
@@ -121,7 +120,7 @@ public class PoisonAi extends SpellAbilityAi {
|
||||
if (input.cantLoseCheck(GameLossReason.Poisoned)) {
|
||||
return true;
|
||||
}
|
||||
return !input.canReceiveCounters(CounterType.get(CounterEnumType.POISON));
|
||||
return !input.canReceiveCounters(CounterEnumType.POISON);
|
||||
});
|
||||
if (!betterAllies.isEmpty()) {
|
||||
allies = betterAllies;
|
||||
|
||||
@@ -8,7 +8,6 @@ import forge.ai.SpellAbilityAi;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerController;
|
||||
@@ -40,7 +39,7 @@ public class TimeTravelAi extends SpellAbilityAi {
|
||||
// so removing them is good; stuff on the battlefield is usually stuff like Vanishing or As Foretold, which favors adding Time
|
||||
// counters for better effect, but exceptions should be added here).
|
||||
Card target = (Card)params.get("Target");
|
||||
return !ComputerUtil.isNegativeCounter(CounterType.get(CounterEnumType.TIME), target);
|
||||
return !ComputerUtil.isNegativeCounter(CounterEnumType.TIME, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1822,8 +1822,8 @@ public class GameAction {
|
||||
|
||||
private boolean stateBasedAction704_5q(Card c) {
|
||||
boolean checkAgain = false;
|
||||
final CounterType p1p1 = CounterType.get(CounterEnumType.P1P1);
|
||||
final CounterType m1m1 = CounterType.get(CounterEnumType.M1M1);
|
||||
final CounterType p1p1 = CounterEnumType.P1P1;
|
||||
final CounterType m1m1 = CounterEnumType.M1M1;
|
||||
int plusOneCounters = c.getCounters(p1p1);
|
||||
int minusOneCounters = c.getCounters(m1m1);
|
||||
if (plusOneCounters > 0 && minusOneCounters > 0) {
|
||||
@@ -1843,7 +1843,7 @@ public class GameAction {
|
||||
return checkAgain;
|
||||
}
|
||||
private boolean stateBasedAction704_5r(Card c) {
|
||||
final CounterType dreamType = CounterType.get(CounterEnumType.DREAM);
|
||||
final CounterType dreamType = CounterEnumType.DREAM;
|
||||
|
||||
int old = c.getCounters(dreamType);
|
||||
if (old <= 0) {
|
||||
|
||||
@@ -33,7 +33,6 @@ import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.event.GameEventCardAttachment;
|
||||
import forge.game.keyword.Keyword;
|
||||
@@ -305,9 +304,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
Integer value = counters.get(counterName);
|
||||
return value == null ? 0 : value;
|
||||
}
|
||||
public final int getCounters(final CounterEnumType counterType) {
|
||||
return getCounters(CounterType.get(counterType));
|
||||
}
|
||||
|
||||
public void setCounters(final CounterType counterType, final Integer num) {
|
||||
if (num <= 0) {
|
||||
@@ -316,9 +312,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
counters.put(counterType, num);
|
||||
}
|
||||
}
|
||||
public void setCounters(final CounterEnumType counterType, final Integer num) {
|
||||
setCounters(CounterType.get(counterType), num);
|
||||
}
|
||||
|
||||
abstract public void setCounters(final Map<CounterType, Integer> allCounters);
|
||||
|
||||
@@ -328,10 +321,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
abstract public int subtractCounter(final CounterType counterName, final int n, final Player remover);
|
||||
abstract public void clearCounters();
|
||||
|
||||
public boolean canReceiveCounters(final CounterEnumType type) {
|
||||
return canReceiveCounters(CounterType.get(type));
|
||||
}
|
||||
|
||||
public final void addCounter(final CounterType counterType, int n, final Player source, GameEntityCounterTable table) {
|
||||
if (n <= 0 || !canReceiveCounters(counterType)) {
|
||||
// As per rule 107.1b
|
||||
@@ -351,18 +340,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
table.put(source, this, counterType, n);
|
||||
}
|
||||
|
||||
public final void addCounter(final CounterEnumType counterType, final int n, final Player source, GameEntityCounterTable table) {
|
||||
addCounter(CounterType.get(counterType), n, source, table);
|
||||
}
|
||||
|
||||
public int subtractCounter(final CounterEnumType counterName, final int n, final Player remover) {
|
||||
return subtractCounter(CounterType.get(counterName), n, remover);
|
||||
}
|
||||
|
||||
abstract public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params);
|
||||
public void addCounterInternal(final CounterEnumType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||
addCounterInternal(CounterType.get(counterType), n, source, fireEvents, table, params);
|
||||
}
|
||||
public Integer getCounterMax(final CounterType counterType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CardZoneTable;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.card.token.TokenInfo;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.event.GameEventTokenCreated;
|
||||
@@ -86,7 +85,7 @@ public class AmassEffect extends TokenEffectBase {
|
||||
}
|
||||
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("CounterType", CounterType.get(CounterEnumType.P1P1));
|
||||
params.put("CounterType", CounterEnumType.P1P1);
|
||||
params.put("Amount", amount);
|
||||
Card tgt = activator.getController().chooseSingleEntityForEffect(tgtCards, sa, Localizer.getInstance().getMessage("lblChooseAnArmy"), false, params);
|
||||
|
||||
|
||||
@@ -369,8 +369,8 @@ public class RollDiceEffect extends SpellAbilityEffect {
|
||||
List<Card> canIncrementDice = new ArrayList<>();
|
||||
for (Card c : xenosquirrels) {
|
||||
// Xenosquirrels must have a P1P1 counter on it to remove in order to modify
|
||||
Integer P1P1Counters = c.getCounters().get(CounterType.get(CounterEnumType.P1P1));
|
||||
if (P1P1Counters != null && P1P1Counters > 0 && c.canRemoveCounters(CounterType.get(CounterEnumType.P1P1))) {
|
||||
Integer P1P1Counters = c.getCounters().get(CounterEnumType.P1P1);
|
||||
if (P1P1Counters != null && P1P1Counters > 0 && c.canRemoveCounters(CounterEnumType.P1P1)) {
|
||||
canIncrementDice.add(c);
|
||||
}
|
||||
}
|
||||
@@ -399,6 +399,7 @@ public class RollDiceEffect extends SpellAbilityEffect {
|
||||
* @param repParams replacement effect parameters
|
||||
* @return list of final roll results after applying ignores and replacements, sorted in ascending order
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<Integer> rollAction(int amount, int sides, int ignore, List<Integer> rollsResult, List<Integer> ignored, Map<Player, Integer> ignoreChosenMap, Set<Card> dicePTExchanges, Player player, Map<AbilityKey, Object> repParams) {
|
||||
|
||||
repParams.put(AbilityKey.Sides, sides);
|
||||
@@ -416,6 +417,8 @@ public class RollDiceEffect extends SpellAbilityEffect {
|
||||
ignoreChosenMap = (Map<Player, Integer>) repParams.get(AbilityKey.IgnoreChosen);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
List<Integer> naturalRolls = (rollsResult == null ? new ArrayList<>() : rollsResult);
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
@@ -37,7 +38,7 @@ public class TimeTravelEffect extends SpellAbilityEffect {
|
||||
|
||||
PlayerController pc = activator.getController();
|
||||
|
||||
final CounterEnumType counterType = CounterEnumType.TIME;
|
||||
final CounterType counterType = CounterEnumType.TIME;
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
FCollection<Card> list = new FCollection<>();
|
||||
|
||||
@@ -6442,10 +6442,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
|
||||
DamageType damageType = DamageType.Normal;
|
||||
if (isPlaneswalker()) { // 120.3c
|
||||
subtractCounter(CounterType.get(CounterEnumType.LOYALTY), damageIn, null, true);
|
||||
subtractCounter(CounterEnumType.LOYALTY, damageIn, null, true);
|
||||
}
|
||||
if (isBattle()) {
|
||||
subtractCounter(CounterType.get(CounterEnumType.DEFENSE), damageIn, null, true);
|
||||
subtractCounter(CounterEnumType.DEFENSE, damageIn, null, true);
|
||||
}
|
||||
if (isCreature()) {
|
||||
if (source.isWitherDamage()) { // 120.3d
|
||||
|
||||
@@ -2568,7 +2568,7 @@ public class CardFactoryUtil {
|
||||
} else if (keyword.equals("Sunburst")) {
|
||||
// Rule 702.43a If this object is entering the battlefield as a creature,
|
||||
// ignoring any type-changing effects that would affect it
|
||||
CounterType t = CounterType.get(host.isCreature() ? CounterEnumType.P1P1 : CounterEnumType.CHARGE);
|
||||
CounterType t = host.isCreature() ? CounterEnumType.P1P1 : CounterEnumType.CHARGE;
|
||||
|
||||
StringBuilder sb = new StringBuilder("etbCounter:");
|
||||
sb.append(t).append(":Sunburst:no Condition:");
|
||||
|
||||
@@ -213,16 +213,10 @@ public final class CardPredicates {
|
||||
public static Predicate<Card> hasCounter(final CounterType type) {
|
||||
return hasCounter(type, 1);
|
||||
}
|
||||
public static Predicate<Card> hasCounter(final CounterEnumType type) {
|
||||
return hasCounter(type, 1);
|
||||
}
|
||||
|
||||
public static Predicate<Card> hasCounter(final CounterType type, final int n) {
|
||||
return c -> c.getCounters(type) >= n;
|
||||
}
|
||||
public static Predicate<Card> hasCounter(final CounterEnumType type, final int n) {
|
||||
return hasCounter(CounterType.get(type), n);
|
||||
}
|
||||
|
||||
public static Predicate<Card> hasLessCounter(final CounterType type, final int n) {
|
||||
return c -> {
|
||||
@@ -230,16 +224,10 @@ public final class CardPredicates {
|
||||
return x > 0 && x <= n;
|
||||
};
|
||||
}
|
||||
public static Predicate<Card> hasLessCounter(final CounterEnumType type, final int n) {
|
||||
return hasLessCounter(CounterType.get(type), n);
|
||||
}
|
||||
|
||||
public static Predicate<Card> canReceiveCounters(final CounterType counter) {
|
||||
return c -> c.canReceiveCounters(counter);
|
||||
}
|
||||
public static Predicate<Card> canReceiveCounters(final CounterEnumType counter) {
|
||||
return canReceiveCounters(CounterType.get(counter));
|
||||
}
|
||||
|
||||
public static Predicate<Card> hasGreaterPowerThan(final int minPower) {
|
||||
return c -> c.getNetPower() > minPower;
|
||||
@@ -248,9 +236,6 @@ public final class CardPredicates {
|
||||
public static Comparator<Card> compareByCounterType(final CounterType type) {
|
||||
return Comparator.comparingInt(arg0 -> arg0.getCounters(type));
|
||||
}
|
||||
public static Comparator<Card> compareByCounterType(final CounterEnumType type) {
|
||||
return compareByCounterType(CounterType.get(type));
|
||||
}
|
||||
|
||||
public static Predicate<Card> hasSVar(final String name) {
|
||||
return c -> c.hasSVar(name);
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.Locale;
|
||||
* @author Clemens Koza
|
||||
* @version V0.0 17.02.2010
|
||||
*/
|
||||
public enum CounterEnumType {
|
||||
public enum CounterEnumType implements CounterType {
|
||||
|
||||
M1M1("-1/-1", "-1/-1", 255, 110, 106),
|
||||
P1P1("+1/+1", "+1/+1", 96, 226, 23),
|
||||
@@ -555,4 +555,14 @@ public enum CounterEnumType {
|
||||
|
||||
public static final ImmutableList<CounterEnumType> values = ImmutableList.copyOf(values());
|
||||
|
||||
@Override
|
||||
public boolean is(CounterEnumType eType) {
|
||||
return this == eType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeywordCounter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package forge.game.card;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public record CounterKeywordType(String keyword) implements CounterType {
|
||||
|
||||
// Rule 122.1b
|
||||
static ImmutableList<String> keywordCounter = ImmutableList.of(
|
||||
"Flying", "First Strike", "Double Strike", "Deathtouch", "Decayed", "Exalted", "Haste", "Hexproof",
|
||||
"Indestructible", "Lifelink", "Menace", "Reach", "Shadow", "Trample", "Vigilance");
|
||||
private static Map<String, CounterKeywordType> sMap = Maps.newHashMap();
|
||||
|
||||
|
||||
public static CounterKeywordType get(String s) {
|
||||
if (!sMap.containsKey(s)) {
|
||||
sMap.put(s, new CounterKeywordType(s));
|
||||
}
|
||||
return sMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return getKeywordDescription();
|
||||
}
|
||||
|
||||
public String getCounterOnCardDisplayName() {
|
||||
return getKeywordDescription();
|
||||
}
|
||||
|
||||
private String getKeywordDescription() {
|
||||
if (keyword.startsWith("Hexproof:")) {
|
||||
final String[] k = keyword.split(":");
|
||||
return "Hexproof from " + k[2];
|
||||
}
|
||||
if (keyword.startsWith("Trample:")) {
|
||||
return "Trample over Planeswalkers";
|
||||
}
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public boolean is(CounterEnumType eType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isKeywordCounter() {
|
||||
if (keyword.startsWith("Hexproof:")) {
|
||||
return true;
|
||||
}
|
||||
if (keyword.startsWith("Trample:")) {
|
||||
return true;
|
||||
}
|
||||
return keywordCounter.contains(keyword);
|
||||
}
|
||||
|
||||
|
||||
public int getRed() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
public int getGreen() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
public int getBlue() {
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
@@ -1,141 +1,31 @@
|
||||
package forge.game.card;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Ordering;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CounterType implements Comparable<CounterType>, Serializable {
|
||||
private static final long serialVersionUID = -7575835723159144478L;
|
||||
|
||||
private CounterEnumType eVal = null;
|
||||
private String sVal = null;
|
||||
|
||||
// Rule 122.1b
|
||||
static ImmutableList<String> keywordCounter = ImmutableList.of(
|
||||
"Flying", "First Strike", "Double Strike", "Deathtouch", "Decayed", "Exalted", "Haste", "Hexproof",
|
||||
"Indestructible", "Lifelink", "Menace", "Reach", "Shadow", "Trample", "Vigilance");
|
||||
|
||||
private static Map<CounterEnumType, CounterType> eMap = Maps.newEnumMap(CounterEnumType.class);
|
||||
private static Map<String, CounterType> sMap = Maps.newHashMap();
|
||||
|
||||
private CounterType(CounterEnumType e, String s) {
|
||||
this.eVal = e;
|
||||
this.sVal = s;
|
||||
}
|
||||
|
||||
public static CounterType get(CounterEnumType e) {
|
||||
if (!eMap.containsKey(e)) {
|
||||
eMap.put(e, new CounterType(e, null));
|
||||
}
|
||||
return eMap.get(e);
|
||||
}
|
||||
|
||||
public static CounterType get(String s) {
|
||||
if (!sMap.containsKey(s)) {
|
||||
sMap.put(s, new CounterType(null, s));
|
||||
}
|
||||
return sMap.get(s);
|
||||
}
|
||||
public interface CounterType extends Serializable {
|
||||
|
||||
public static CounterType getType(String name) {
|
||||
if ("Any".equalsIgnoreCase(name)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return get(CounterEnumType.getType(name));
|
||||
return CounterEnumType.getType(name);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
return get(name);
|
||||
return CounterKeywordType.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(eVal, sVal);
|
||||
}
|
||||
public String getCounterOnCardDisplayName();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
CounterType rhs = (CounterType) obj;
|
||||
return new EqualsBuilder()
|
||||
.append(eVal, rhs.eVal)
|
||||
.append(sVal, rhs.sVal)
|
||||
.isEquals();
|
||||
}
|
||||
public boolean is(CounterEnumType eType);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return eVal != null ? eVal.toString() : sVal;
|
||||
}
|
||||
public boolean isKeywordCounter();
|
||||
|
||||
public String getName() {
|
||||
return eVal != null ? eVal.getName() : getKeywordDescription();
|
||||
}
|
||||
public int getRed();
|
||||
|
||||
public String getCounterOnCardDisplayName() {
|
||||
return eVal != null ? eVal.getCounterOnCardDisplayName() : getKeywordDescription();
|
||||
}
|
||||
public int getGreen();
|
||||
|
||||
private String getKeywordDescription() {
|
||||
if (sVal.startsWith("Hexproof:")) {
|
||||
final String[] k = sVal.split(":");
|
||||
return "Hexproof from " + k[2];
|
||||
}
|
||||
if (sVal.startsWith("Trample:")) {
|
||||
return "Trample over Planeswalkers";
|
||||
}
|
||||
return sVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CounterType o) {
|
||||
return ComparisonChain.start()
|
||||
.compare(eVal, o.eVal, Ordering.natural().nullsLast())
|
||||
.compare(sVal, o.sVal, Ordering.natural().nullsLast())
|
||||
.result();
|
||||
}
|
||||
|
||||
public boolean is(CounterEnumType eType) {
|
||||
return eVal == eType;
|
||||
}
|
||||
|
||||
public boolean isKeywordCounter() {
|
||||
if (eVal != null) {
|
||||
return false;
|
||||
}
|
||||
if (sVal.startsWith("Hexproof:")) {
|
||||
return true;
|
||||
}
|
||||
if (sVal.startsWith("Trample:")) {
|
||||
return true;
|
||||
}
|
||||
return keywordCounter.contains(sVal);
|
||||
}
|
||||
|
||||
public int getRed() {
|
||||
return eVal != null ? eVal.getRed() : 255;
|
||||
}
|
||||
|
||||
public int getGreen() {
|
||||
return eVal != null ? eVal.getGreen() : 255;
|
||||
}
|
||||
|
||||
public int getBlue() {
|
||||
return eVal != null ? eVal.getBlue() : 255;
|
||||
}
|
||||
public int getBlue();
|
||||
}
|
||||
|
||||
@@ -997,9 +997,9 @@ public class Cost implements Serializable {
|
||||
Integer counters = otherAmount - part.convertAmount();
|
||||
// the cost can turn positive if multiple Carth raise it
|
||||
if (counters < 0) {
|
||||
costParts.add(new CostPutCounter(String.valueOf(counters *-1), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription()));
|
||||
costParts.add(new CostPutCounter(String.valueOf(counters *-1), CounterEnumType.LOYALTY, part.getType(), part.getTypeDescription()));
|
||||
} else {
|
||||
costParts.add(new CostRemoveCounter(String.valueOf(counters), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription(), Lists.newArrayList(ZoneType.Battlefield) , false));
|
||||
costParts.add(new CostRemoveCounter(String.valueOf(counters), CounterEnumType.LOYALTY, part.getType(), part.getTypeDescription(), Lists.newArrayList(ZoneType.Battlefield) , false));
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
|
||||
@@ -22,7 +22,6 @@ import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
@@ -81,7 +80,7 @@ public class CostUntap extends CostPart {
|
||||
public final boolean canPay(final SpellAbility ability, final Player payer, final boolean effect) {
|
||||
final Card source = ability.getHostCard();
|
||||
return source.isTapped() && !source.isAbilitySick() &&
|
||||
(source.getCounters(CounterEnumType.STUN) == 0 || source.canRemoveCounters(CounterType.get(CounterEnumType.STUN)));
|
||||
(source.getCounters(CounterEnumType.STUN) == 0 || source.canRemoveCounters(CounterEnumType.STUN));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,7 +86,7 @@ public class CostUntapType extends CostPartWithList {
|
||||
if (!canUntapSource) {
|
||||
typeList.remove(source);
|
||||
}
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterType.get(CounterEnumType.STUN)));
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterEnumType.STUN));
|
||||
|
||||
final int amount = this.getAbilityAmount(ability);
|
||||
return (typeList.size() != 0) && (typeList.size() >= amount);
|
||||
|
||||
@@ -944,10 +944,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
getGame().fireEvent(new GameEventPlayerCounters(this, null, 0, 0));
|
||||
}
|
||||
|
||||
public void setCounters(final CounterEnumType counterType, final Integer num, Player source, boolean fireEvents) {
|
||||
this.setCounters(CounterType.get(counterType), num, source, fireEvents);
|
||||
}
|
||||
|
||||
public void setCounters(final CounterType counterType, final Integer num, Player source, boolean fireEvents) {
|
||||
int old = getCounters(counterType);
|
||||
setCounters(counterType, num);
|
||||
@@ -973,7 +969,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
getGame().fireEvent(new GameEventPlayerCounters(this, null, 0, 0));
|
||||
|
||||
// create Radiation Effect for GameState
|
||||
if (counters.getOrDefault(CounterType.get(CounterEnumType.RAD), 0) > 0) {
|
||||
if (counters.getOrDefault(CounterEnumType.RAD, 0) > 0) {
|
||||
this.createRadiationEffect(null);
|
||||
} else {
|
||||
this.removeRadiationEffect();
|
||||
|
||||
@@ -7,7 +7,6 @@ import forge.game.CardTraitBase;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -57,14 +56,6 @@ public final class PlayerPredicates {
|
||||
public static Predicate<Player> hasCounter(final CounterType type, final int n) {
|
||||
return p -> p.getCounters(type) >= n;
|
||||
}
|
||||
|
||||
public static Predicate<Player> hasCounter(final CounterEnumType type) {
|
||||
return hasCounter(CounterType.get(type), 1);
|
||||
}
|
||||
|
||||
public static Predicate<Player> hasCounter(final CounterEnumType type, final int n) {
|
||||
return hasCounter(CounterType.get(type), n);
|
||||
}
|
||||
|
||||
public static Predicate<Player> hasKeyword(final String keyword) {
|
||||
return p -> p.hasKeyword(keyword);
|
||||
|
||||
@@ -12,7 +12,6 @@ import forge.card.mana.ManaAtom;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -192,9 +191,6 @@ public class PlayerView extends GameEntityView {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public int getCounters(CounterEnumType counterType) {
|
||||
return getCounters(CounterType.get(counterType));
|
||||
}
|
||||
void updateCounters(Player p) {
|
||||
set(TrackableProperty.Counters, p.getCounters());
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
|
||||
@Override
|
||||
public CounterType chooseCounterType(List<CounterType> options, SpellAbility sa, String prompt, Map<String, Object> params) {
|
||||
return Iterables.getFirst(options, CounterType.get(CounterEnumType.P1P1));
|
||||
return Iterables.getFirst(options, CounterEnumType.P1P1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1393,7 +1393,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
public PaymentDecision visit(final CostUntapType cost) {
|
||||
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"),
|
||||
player, source, ability);
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterType.get(CounterEnumType.STUN)));
|
||||
typeList = CardLists.filter(typeList, CardPredicates.TAPPED, c -> c.getCounters(CounterEnumType.STUN) == 0 || c.canRemoveCounters(CounterEnumType.STUN));
|
||||
int c = cost.getAbilityAmount(ability);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList, ability);
|
||||
inp.setCancelAllowed(true);
|
||||
|
||||
@@ -425,7 +425,7 @@ public class HumanPlay {
|
||||
}
|
||||
}
|
||||
else if (part instanceof CostPayEnergy) {
|
||||
CounterType counterType = CounterType.get(CounterEnumType.ENERGY);
|
||||
CounterType counterType = CounterEnumType.ENERGY;
|
||||
int amount = part.getAbilityAmount(sourceAbility);
|
||||
|
||||
if (!mandatory && !p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantSpendNTargetTypeCounter", String.valueOf(amount), counterType.getName()), sourceAbility)) {
|
||||
|
||||
@@ -285,7 +285,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
// maindeck and max sideboard sizes
|
||||
// No longer need 1:1 sideboarding in non-limited formats
|
||||
List<PaperCard> resp = getGui().sideboard(sideboard, main, message);
|
||||
newMain = ObjectUtils.defaultIfNull(resp, main.toFlatList());
|
||||
newMain = ObjectUtils.getIfNull(resp, main.toFlatList());
|
||||
} while (conform && (newMain.size() < deckMinSize || combinedDeckSize - newMain.size() > sbMax));
|
||||
|
||||
return newMain;
|
||||
@@ -2700,7 +2700,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
final Card card = gameCacheCounters.get(cv);
|
||||
|
||||
final ImmutableList<CounterType> counters = subtract ? ImmutableList.copyOf(card.getCounters().keySet())
|
||||
: ImmutableList.copyOf(Collections2.transform(CounterEnumType.values, CounterType::get));
|
||||
: ImmutableList.copyOf(CounterEnumType.values);
|
||||
|
||||
final CounterType counter = getGui().oneOrNone(localizer.getMessage("lblWhichTypeofCounter"), counters);
|
||||
if (counter == null) {
|
||||
|
||||
Reference in New Issue
Block a user