diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 68bf94ac97f..9cefd9aa315 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -17,33 +17,17 @@ */ package forge.ai; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import forge.game.staticability.StaticAbility; -import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked; -import org.apache.commons.lang3.tuple.Pair; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - import forge.ai.ability.AnimateAi; import forge.card.CardTypeView; import forge.game.GameEntity; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.ProtectEffect; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; -import forge.game.card.CardUtil; -import forge.game.card.CounterEnumType; +import forge.game.card.*; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.combat.GlobalAttackRestrictions; @@ -53,6 +37,8 @@ import forge.game.player.Player; import forge.game.player.PlayerCollection; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityPredicates; +import forge.game.staticability.StaticAbility; +import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.zone.Zone; @@ -62,6 +48,12 @@ import forge.util.Expressions; import forge.util.MyRandom; import forge.util.collect.FCollection; import forge.util.collect.FCollectionView; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; /** @@ -135,6 +127,8 @@ public class AiAttackController { public static List getOpponentCreatures(final Player defender) { List defenders = defender.getCreaturesInPlay(); + int totalMana = ComputerUtilMana.getAvailableManaEstimate(defender, true); + int manaReserved = 0; // for paying the cost to transform Predicate canAnimate = new Predicate() { @Override public boolean apply(Card c) { @@ -142,14 +136,33 @@ public class AiAttackController { } }; for (Card c : CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), canAnimate)) { - if (c.isToken() && c.getCopiedPermanent() == null) { + /* TODO: is the commented out code still necessary for anything? + if (c.isToken() && c.getCopiedPermanent() == null && !c.canTransform(null)) { continue; } + */ for (SpellAbility sa : Iterables.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.Animate))) { if (ComputerUtilCost.canPayCost(sa, defender, false) && sa.getRestrictions().checkOtherRestrictions(c, sa, defender)) { Card animatedCopy = AnimateAi.becomeAnimated(c, sa); - defenders.add(animatedCopy); + int saCMC = sa.getPayCosts() != null && sa.getPayCosts().hasManaCost() ? + sa.getPayCosts().getTotalMana().getCMC() : 0; // FIXME: imprecise, only works 100% for colorless mana + if (totalMana - manaReserved >= saCMC) { + manaReserved += saCMC; + defenders.add(animatedCopy); + } + } + } + // Transform (e.g. Incubator tokens) + for (SpellAbility sa : Iterables.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.SetState))) { + Card transformedCopy = ComputerUtilCombat.canTransform(c); + if (transformedCopy.isCreature()) { + int saCMC = sa.getPayCosts() != null && sa.getPayCosts().hasManaCost() ? + sa.getPayCosts().getTotalMana().getCMC() : 0; // FIXME: imprecise, only works 100% for colorless mana + if (totalMana - manaReserved >= saCMC) { + manaReserved += saCMC; + defenders.add(transformedCopy); + } } } } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 69ceee83ac3..4487a23b27c 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -2307,7 +2307,7 @@ public class ComputerUtilCombat { * @param original original creature * @return transform creature if possible, original creature otherwise */ - private final static Card canTransform(Card original) { + public final static Card canTransform(Card original) { if (original.isTransformable() && !original.isInAlternateState()) { for (SpellAbility sa : original.getSpellAbilities()) { if (sa.getApi() == ApiType.SetState && ComputerUtilCost.canPayCost(sa, original.getController(), false)) {