mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
ChooseGenericEffectAi: add logic for Fabricate
in most cases it should prefer tokens if able
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -43,8 +48,12 @@ public class ChooseGenericEffectAi extends SpellAbilityAi {
|
||||
@Override
|
||||
public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List<SpellAbility> spells) {
|
||||
Card host = sa.getHostCard();
|
||||
final Game game = host.getGame();
|
||||
final Combat combat = game.getCombat();
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if ("Random".equals(logic)) {
|
||||
if (logic == null) {
|
||||
return spells.get(0);
|
||||
} else if ("Random".equals(logic)) {
|
||||
return Aggregates.random(spells);
|
||||
} else if ("Phasing".equals(logic)) { // Teferi's Realm : keep aggressive
|
||||
List<SpellAbility> filtered = Lists.newArrayList(Iterables.filter(spells, new Predicate<SpellAbility>() {
|
||||
@@ -191,6 +200,57 @@ public class ChooseGenericEffectAi extends SpellAbilityAi {
|
||||
}
|
||||
// if unsure, random?
|
||||
return Aggregates.random(spells);
|
||||
} else if (logic.startsWith("Fabricate")) {
|
||||
final int n = Integer.valueOf(logic.substring("Fabricate".length()));
|
||||
SpellAbility counterSA = spells.get(0), tokenSA = spells.get(1);
|
||||
|
||||
// check for something which might prevent the counters to be placed on host
|
||||
if (!host.canReceiveCounters(CounterType.P1P1)) {
|
||||
return tokenSA;
|
||||
}
|
||||
|
||||
// if host would leave the play or if host is useless, create tokens
|
||||
if (host.hasSVar("EndOfTurnLeavePlay") || isUselessCreature(player, host)) {
|
||||
return tokenSA;
|
||||
}
|
||||
|
||||
// need a copy for one with extra +1/+1 counter boost,
|
||||
// without causing triggers to run
|
||||
final Card copy = CardUtil.getLKICopy(host);
|
||||
copy.setCounters(CounterType.P1P1, copy.getCounters(CounterType.P1P1) + n);
|
||||
copy.setZone(host.getZone());
|
||||
|
||||
// if host would put into the battlefield attacking
|
||||
if (combat != null && combat.isAttacking(host)) {
|
||||
final Player defender = combat.getDefenderPlayerByAttacker(host);
|
||||
if (!ComputerUtilCard.canBeBlockedProfitably(defender, copy)) {
|
||||
return counterSA;
|
||||
}
|
||||
return tokenSA;
|
||||
}
|
||||
|
||||
// TODO check for trigger to turn token ETB into +1/+1 counter for host
|
||||
// TODO check for trigger to turn token ETB into damage or life loss for opponent
|
||||
// in this cases Token might be prefered even if they would not survive
|
||||
final Card tokenCard = TokenAi.spawnToken(player, tokenSA, true);
|
||||
|
||||
// Token would not survive
|
||||
if (tokenCard.getNetToughness() < 1) {
|
||||
return counterSA;
|
||||
}
|
||||
|
||||
// evaluate Creature with +1/+1
|
||||
int evalCounter = ComputerUtilCard.evaluateCreature(copy);
|
||||
|
||||
final CardCollection tokenList = new CardCollection(host);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
tokenList.add(TokenAi.spawnToken(player, tokenSA));
|
||||
}
|
||||
|
||||
// evaluate Host with Tokens
|
||||
int evalToken = ComputerUtilCard.evaluateCreatureList(tokenList);
|
||||
|
||||
return evalToken >= evalCounter ? tokenSA : counterSA;
|
||||
}
|
||||
return spells.get(0); // return first choice if no logic found
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user