mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
CountersMultiply: add new API type for double counters on cards
remove it from RepeatEachAi add more AI logic into it. it does support Strive Spell
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -68,6 +68,7 @@ forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java -text
|
|||||||
forge-ai/src/main/java/forge/ai/ability/CounterAi.java -text
|
forge-ai/src/main/java/forge/ai/ability/CounterAi.java -text
|
||||||
forge-ai/src/main/java/forge/ai/ability/CountersAi.java svneol=native#text/plain
|
forge-ai/src/main/java/forge/ai/ability/CountersAi.java svneol=native#text/plain
|
||||||
forge-ai/src/main/java/forge/ai/ability/CountersMoveAi.java -text
|
forge-ai/src/main/java/forge/ai/ability/CountersMoveAi.java -text
|
||||||
|
forge-ai/src/main/java/forge/ai/ability/CountersMultiplyAi.java -text svneol=unset#text/plain
|
||||||
forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java -text
|
forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java -text
|
||||||
forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java -text
|
forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java -text
|
||||||
forge-ai/src/main/java/forge/ai/ability/CountersPutAllAi.java -text
|
forge-ai/src/main/java/forge/ai/ability/CountersPutAllAi.java -text
|
||||||
@@ -369,6 +370,7 @@ forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java -te
|
|||||||
forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java -text
|
||||||
forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java -text
|
||||||
forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java -text
|
||||||
|
forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java -text svneol=unset#text/plain
|
||||||
forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java -text
|
||||||
forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java -text
|
||||||
forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java -text
|
forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java -text
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import forge.game.phase.PhaseHandler;
|
|||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
|
||||||
import forge.game.staticability.StaticAbility;
|
import forge.game.staticability.StaticAbility;
|
||||||
import forge.game.zone.MagicStack;
|
import forge.game.zone.MagicStack;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -1381,9 +1380,8 @@ public class ComputerUtilCard {
|
|||||||
public static boolean canPumpAgainstRemoval(Player ai, SpellAbility sa) {
|
public static boolean canPumpAgainstRemoval(Player ai, SpellAbility sa) {
|
||||||
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
|
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
|
||||||
final CardCollection threatenedTargets = new CardCollection();
|
final CardCollection threatenedTargets = new CardCollection();
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
|
||||||
|
|
||||||
if (tgt == null) {
|
if (!sa.usesTargeting()) {
|
||||||
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||||
for (final Card card : cards) {
|
for (final Card card : cards) {
|
||||||
if (objects.contains(card)) {
|
if (objects.contains(card)) {
|
||||||
@@ -1393,9 +1391,8 @@ public class ComputerUtilCard {
|
|||||||
// For pumps without targeting restrictions, just return immediately until this is fleshed out.
|
// For pumps without targeting restrictions, just return immediately until this is fleshed out.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
CardCollection targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
|
||||||
|
|
||||||
CardCollection targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
|
|
||||||
targetables = CardLists.getTargetableCards(targetables, sa);
|
|
||||||
targetables = ComputerUtil.getSafeTargets(ai, sa, targetables);
|
targetables = ComputerUtil.getSafeTargets(ai, sa, targetables);
|
||||||
for (final Card c : targetables) {
|
for (final Card c : targetables) {
|
||||||
if (objects.contains(c)) {
|
if (objects.contains(c)) {
|
||||||
@@ -1405,13 +1402,14 @@ public class ComputerUtilCard {
|
|||||||
if (!threatenedTargets.isEmpty()) {
|
if (!threatenedTargets.isEmpty()) {
|
||||||
ComputerUtilCard.sortByEvaluateCreature(threatenedTargets);
|
ComputerUtilCard.sortByEvaluateCreature(threatenedTargets);
|
||||||
for (Card c : threatenedTargets) {
|
for (Card c : threatenedTargets) {
|
||||||
sa.getTargets().add(c);
|
if (sa.canAddMoreTarget()) {
|
||||||
if (sa.getTargets().getNumTargeted() >= tgt.getMaxTargets(sa.getHostCard(), sa)) {
|
sa.getTargets().add(c);
|
||||||
break;
|
if (!sa.canAddMoreTarget()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa.getTargets().getNumTargeted() > tgt.getMaxTargets(sa.getHostCard(), sa)
|
if (!sa.isTargetNumberValid()) {
|
||||||
|| sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ public enum SpellApiToAi {
|
|||||||
.put(ApiType.Mill, MillAi.class)
|
.put(ApiType.Mill, MillAi.class)
|
||||||
.put(ApiType.MoveCounter, CountersMoveAi.class)
|
.put(ApiType.MoveCounter, CountersMoveAi.class)
|
||||||
.put(ApiType.MultiplePiles, CannotPlayAi.class)
|
.put(ApiType.MultiplePiles, CannotPlayAi.class)
|
||||||
|
.put(ApiType.MultiplyCounter, CountersMultiplyAi.class)
|
||||||
.put(ApiType.MustAttack, MustAttackAi.class)
|
.put(ApiType.MustAttack, MustAttackAi.class)
|
||||||
.put(ApiType.MustBlock, MustBlockAi.class)
|
.put(ApiType.MustBlock, MustBlockAi.class)
|
||||||
.put(ApiType.NameCard, ChooseCardNameAi.class)
|
.put(ApiType.NameCard, ChooseCardNameAi.class)
|
||||||
|
|||||||
212
forge-ai/src/main/java/forge/ai/ability/CountersMultiplyAi.java
Normal file
212
forge-ai/src/main/java/forge/ai/ability/CountersMultiplyAi.java
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
package forge.ai.ability;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import forge.ai.ComputerUtil;
|
||||||
|
import forge.ai.ComputerUtilCost;
|
||||||
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityUtils;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
|
import forge.game.card.CounterType;
|
||||||
|
import forge.game.phase.PhaseHandler;
|
||||||
|
import forge.game.phase.PhaseType;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
|
public class CountersMultiplyAi extends SpellAbilityAi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
|
||||||
|
final CounterType counterType = getCounterType(sa);
|
||||||
|
|
||||||
|
if (!sa.usesTargeting()) {
|
||||||
|
// defined are mostly Self or Creatures you control
|
||||||
|
CardCollection list = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||||
|
|
||||||
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Card c) {
|
||||||
|
if (!c.hasCounters()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counterType != null) {
|
||||||
|
if (c.getCounters(counterType) <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!c.canReceiveCounters(counterType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Map.Entry<CounterType, Integer> e : c.getCounters().entrySet()) {
|
||||||
|
// has negative counter it would double
|
||||||
|
if (ComputerUtil.isNegativeCounter(e.getKey(), c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return setTargets(ai, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.checkApiLogic(ai, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkPhaseRestrictions(final Player ai, final SpellAbility sa, final PhaseHandler ph) {
|
||||||
|
final CounterType counterType = getCounterType(sa);
|
||||||
|
|
||||||
|
if (!CounterType.P1P1.equals(counterType) && counterType != null) {
|
||||||
|
if (!sa.hasParam("ActivationPhases")) {
|
||||||
|
// Don't use non P1P1/M1M1 counters before main 2 if possible
|
||||||
|
if (ph.getPhase().isBefore(PhaseType.MAIN2) && !ComputerUtil.castSpellInMain1(ai, sa)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ph.isPlayerTurn(ai) && !isSorcerySpeed(sa)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ComputerUtil.waitForBlocking(sa)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
|
if (sa.usesTargeting() && !setTargets(ai, sa) && !mandatory) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CounterType getCounterType(SpellAbility sa) {
|
||||||
|
if (sa.hasParam("CounterType")) {
|
||||||
|
try {
|
||||||
|
return AbilityUtils.getCounterType(sa.getParam("CounterType"), sa);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Counter type doesn't match, nor does an SVar exist with the type name.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setTargets(Player ai, SpellAbility sa) {
|
||||||
|
final CounterType counterType = getCounterType(sa);
|
||||||
|
|
||||||
|
final Game game = ai.getGame();
|
||||||
|
|
||||||
|
CardCollection list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
||||||
|
|
||||||
|
// pre filter targetable cards with counters and can receive one of
|
||||||
|
// them
|
||||||
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Card c) {
|
||||||
|
if (!c.hasCounters()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counterType != null) {
|
||||||
|
if (c.getCounters(counterType) <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!c.canReceiveCounters(counterType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
CardCollection aiList = CardLists.filterControlledBy(list, ai);
|
||||||
|
if (!aiList.isEmpty()) {
|
||||||
|
// counter type list to check
|
||||||
|
// first loyalty, then P1P!, then Charge Counter
|
||||||
|
List<CounterType> typeList = Lists.newArrayList(CounterType.LOYALTY, CounterType.P1P1, CounterType.CHARGE);
|
||||||
|
for (CounterType type : typeList) {
|
||||||
|
// enough targets
|
||||||
|
if (!sa.canAddMoreTarget()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counterType == null || counterType == type) {
|
||||||
|
addTargetsByCounterType(ai, sa, aiList, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardCollection oppList = CardLists.filterControlledBy(list, ai.getOpponents());
|
||||||
|
if (!oppList.isEmpty()) {
|
||||||
|
// not enough targets
|
||||||
|
if (sa.canAddMoreTarget()) {
|
||||||
|
final CounterType type = CounterType.M1M1;
|
||||||
|
if (counterType == null || counterType == type) {
|
||||||
|
addTargetsByCounterType(ai, sa, oppList, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// targeting does failed
|
||||||
|
if (!sa.isTargetNumberValid()) {
|
||||||
|
sa.resetTargets();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTargetsByCounterType(final Player ai, final SpellAbility sa, final CardCollection list,
|
||||||
|
final CounterType type) {
|
||||||
|
|
||||||
|
CardCollection newList = CardLists.filter(list, CardPredicates.hasCounter(type));
|
||||||
|
if (newList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newList.sort(Collections.reverseOrder(CardPredicates.compareByCounterType(type)));
|
||||||
|
while (sa.canAddMoreTarget()) {
|
||||||
|
if (newList.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Card c = newList.remove(0);
|
||||||
|
sa.getTargets().add(c);
|
||||||
|
|
||||||
|
// check if Spell with Strive is still playable
|
||||||
|
if (sa.isSpell() && sa.getHostCard().hasStartOfKeyword("Strive")) {
|
||||||
|
// if not remove target again and break list
|
||||||
|
if (!ComputerUtilCost.canPayCost(sa, ai)) {
|
||||||
|
sa.getTargets().remove(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package forge.ai.ability;
|
package forge.ai.ability;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
import forge.ai.ComputerUtilCard;
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
@@ -14,8 +15,6 @@ import forge.game.player.Player;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class RepeatEachAi extends SpellAbilityAi {
|
public class RepeatEachAi extends SpellAbilityAi {
|
||||||
|
|
||||||
@@ -38,21 +37,6 @@ public class RepeatEachAi extends SpellAbilityAi {
|
|||||||
if (compTokenCreats.size() <= humTokenCreats.size()) {
|
if (compTokenCreats.size() <= humTokenCreats.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if ("DoubleCounters".equals(logic)) {
|
|
||||||
// TODO Improve this logic, double Planeswalker counters first, then +1/+1 on Useful creatures
|
|
||||||
// Then Charge Counters, then -1/-1 on Opposing Creatures
|
|
||||||
CardCollection perms = new CardCollection(aiPlayer.getCardsIn(ZoneType.Battlefield));
|
|
||||||
perms = CardLists.filter(CardLists.getTargetableCards(perms, sa), new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.hasCounters();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (perms.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CardLists.shuffle(perms);
|
|
||||||
sa.setTargetCard(perms.get(0));
|
|
||||||
} else if ("RemoveAllCounters".equals(logic)) {
|
} else if ("RemoveAllCounters".equals(logic)) {
|
||||||
// Break Dark Depths
|
// Break Dark Depths
|
||||||
CardCollectionView depthsList = aiPlayer.getCardsIn(ZoneType.Battlefield, "Dark Depths");
|
CardCollectionView depthsList = aiPlayer.getCardsIn(ZoneType.Battlefield, "Dark Depths");
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public enum ApiType {
|
|||||||
Mill (MillEffect.class),
|
Mill (MillEffect.class),
|
||||||
MoveCounter (CountersMoveEffect.class),
|
MoveCounter (CountersMoveEffect.class),
|
||||||
MultiplePiles (MultiplePilesEffect.class),
|
MultiplePiles (MultiplePilesEffect.class),
|
||||||
|
MultiplyCounter (CountersMultiplyEffect.class),
|
||||||
MustAttack (MustAttackEffect.class),
|
MustAttack (MustAttackEffect.class),
|
||||||
MustBlock (MustBlockEffect.class),
|
MustBlock (MustBlockEffect.class),
|
||||||
NameCard (ChooseCardNameEffect.class),
|
NameCard (ChooseCardNameEffect.class),
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityUtils;
|
||||||
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CounterType;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.util.Lang;
|
||||||
|
|
||||||
|
public class CountersMultiplyEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
final CounterType counterType = getCounterType(sa);
|
||||||
|
|
||||||
|
sb.append("Double the number of ");
|
||||||
|
|
||||||
|
if (counterType != null) {
|
||||||
|
sb.append(counterType.getName());
|
||||||
|
sb.append(" counters");
|
||||||
|
} else {
|
||||||
|
sb.append("each kind of counter");
|
||||||
|
}
|
||||||
|
sb.append(" on ");
|
||||||
|
|
||||||
|
sb.append(Lang.joinHomogenous(getTargetCards(sa)));
|
||||||
|
|
||||||
|
sb.append(".");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void resolve(SpellAbility sa) {
|
||||||
|
|
||||||
|
final CounterType counterType = getCounterType(sa);
|
||||||
|
final int n = Integer.valueOf(sa.getParamOrDefault("Multiplier", "2")) - 1;
|
||||||
|
|
||||||
|
for (final Card tgtCard : getTargetCards(sa)) {
|
||||||
|
if (counterType != null) {
|
||||||
|
tgtCard.addCounter(counterType, tgtCard.getCounters(counterType) * n, false);
|
||||||
|
} else {
|
||||||
|
for (Map.Entry<CounterType, Integer> e : tgtCard.getCounters().entrySet()) {
|
||||||
|
tgtCard.addCounter(e.getKey(), e.getValue() * n, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private CounterType getCounterType(SpellAbility sa) {
|
||||||
|
if (sa.hasParam("CounterType")) {
|
||||||
|
try {
|
||||||
|
return AbilityUtils.getCounterType(sa.getParam("CounterType"), sa);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Counter type doesn't match, nor does an SVar exist with the type name.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user