diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 4182811bf11..8e1626ee155 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -40,6 +40,8 @@ import forge.game.card.CardUtil; import forge.game.card.CounterType; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; +import forge.game.cost.CostPart; +import forge.game.cost.CostPayEnergy; import forge.game.keyword.Keyword; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -1587,4 +1589,28 @@ public class ComputerUtilCard { public static boolean isPresentOnBattlefield(final Game game, final String cardName) { return !CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals(cardName)).isEmpty(); } + + public static int getMaxSAEnergyCostOnBattlefield(final Player ai) { + // returns the maximum energy cost of an ability that permanents on the battlefield under AI's control have + CardCollectionView otb = ai.getCardsIn(ZoneType.Battlefield); + int maxEnergyCost = 0; + + for (Card c : otb) { + for (SpellAbility sa : c.getSpellAbilities()) { + if (sa.getPayCosts() == null) { + continue; + } + + CostPayEnergy energyCost = sa.getPayCosts().getCostEnergy(); + if (energyCost != null) { + int amount = energyCost.convertAmount(); + if (amount > maxEnergyCost) { + maxEnergyCost = amount; + } + } + } + } + + return maxEnergyCost; + } } diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index 278849ba399..b8018adc339 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -217,7 +217,18 @@ public class CountersPutAi extends SpellAbilityAi { } if ("PayEnergy".equals(sa.getParam("AILogic"))) { - return true; + return false; + } + + if ("PayEnergyConservatively".equals(sa.getParam("AILogic"))) { + if (ai.getGame().getCombat() != null && sa.getHostCard() != null) { + if (ai.getGame().getCombat().isAttacking(sa.getHostCard()) || ai.getGame().getCombat().isBlocking(sa.getHostCard())) { + return true; + } + } + if (ai.getCounters(CounterType.ENERGY) > ComputerUtilCard.getMaxSAEnergyCostOnBattlefield(ai) + sa.getPayCosts().getCostEnergy().convertAmount()) { + return true; + } } if (sa.getConditions() != null && !sa.getConditions().areMet(sa) && sa.getSubAbility() == null) { diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index 89a76dc7f86..c642bebc684 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -494,6 +494,15 @@ public class Cost { return null; } + public final CostPayEnergy getCostEnergy() { + for (final CostPart part : this.costParts) { + if (part instanceof CostPayEnergy) { + return (CostPayEnergy) part; + } + } + return null; + } + /** *
* refundPaidCost. diff --git a/forge-gui/res/cardsfolder/b/bristling_hydra.txt b/forge-gui/res/cardsfolder/b/bristling_hydra.txt index a8406e35cdd..7b4a6ad33d3 100644 --- a/forge-gui/res/cardsfolder/b/bristling_hydra.txt +++ b/forge-gui/res/cardsfolder/b/bristling_hydra.txt @@ -4,7 +4,7 @@ Types:Creature Hydra PT:4/3 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEnergy | TriggerDescription$ When CARDNAME enters the battlefield, you get {E}{E}{E} (three energy counters). SVar:TrigEnergy:DB$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3 -A:AB$ PutCounter | Cost$ PayEnergy<3> | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on CARDNAME. It gains hexproof until end of turn. +A:AB$ PutCounter | Cost$ PayEnergy<3> | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | AILogic$ PayEnergyConservatively | SpellDescription$ Put a +1/+1 counter on CARDNAME. It gains hexproof until end of turn. SVar:DBPump:DB$Pump | Defined$ Self | KW$ Hexproof SVar:Picture:http://www.wizards.com/global/images/magic/general/bristling_hydra.jpg Oracle:When Bristling Hydra enters the battlefield, you gain {E}{E}{E} (three energy counters).\nPay {E}{E}{E}: Put a +1/+1 counter on Bristling Hydra. It gains hexproof until end of turn. diff --git a/forge-gui/res/cardsfolder/l/longtusk_cub.txt b/forge-gui/res/cardsfolder/l/longtusk_cub.txt index f0da73c7a6e..df918234e7c 100644 --- a/forge-gui/res/cardsfolder/l/longtusk_cub.txt +++ b/forge-gui/res/cardsfolder/l/longtusk_cub.txt @@ -4,7 +4,7 @@ Types:Creature Cat PT:2/2 T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigEnergy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you get {E}{E} (two energy counters). SVar:TrigEnergy:DB$PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 2 -A:AB$ PutCounter | Cost$ PayEnergy<2> | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. +A:AB$ PutCounter | Cost$ PayEnergy<2> | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ PayEnergyConservatively | SpellDescription$ Put a +1/+1 counter on CARDNAME. DeckHints:Ability$Energy DeckHas:Ability$Counters SVar:Picture:http://www.wizards.com/global/images/magic/general/longtusk_cub.jpg