mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
- Added a more conservative version of AILogic PayEnergy for PutCounter AI that only pays energy if the creature is in combat (attacking/blocking) or if there's more energy available than the most expensive energy cost of a permanent SA on the battlefield requires plus whatever the PutCounter SA requires.
- Set this logic for Longtusk Cub and Bristling Hydra. - TODO: maybe somehow teach the AI to pay energy if it can save the creature from lethal damage from a spell?
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* refundPaidCost.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user