diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index 6730a6faec4..67a572a40fd 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -359,8 +359,12 @@ public class ComputerUtilCost { if (source.isCreature()) { // e.g. Sakura Tribe-Elder final boolean beforeNextTurn = ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN) && ai.getGame().getPhaseHandler().getNextTurn().equals(ai); - final boolean inDanger = ComputerUtil.predictThreatenedObjects(ai, sourceAbility, true).contains(source); - if (!(inDanger || beforeNextTurn)) { + final boolean creatureInDanger = ComputerUtil.predictCreatureWillDieThisTurn(ai, source, sourceAbility); + final int lifeThreshold = (((PlayerControllerAi) ai.getController()).getAi().getIntProperty(AiProps.AI_IN_DANGER_THRESHOLD)); + final boolean aiInDanger = ai.getLife() <= lifeThreshold && ai.canLoseLife() && !ai.cantLoseForZeroOrLessLife(); + if (creatureInDanger) { + return true; + } else if (aiInDanger || !beforeNextTurn) { return false; } } diff --git a/forge-ai/src/main/java/forge/ai/ability/BranchAi.java b/forge-ai/src/main/java/forge/ai/ability/BranchAi.java index ec33370223b..0d63c224c88 100644 --- a/forge-ai/src/main/java/forge/ai/ability/BranchAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/BranchAi.java @@ -3,8 +3,15 @@ package forge.ai.ability; import java.util.Map; +import com.google.common.base.Predicate; +import forge.ai.ComputerUtilCard; import forge.ai.SpecialCardAi; import forge.ai.SpellAbilityAi; +import forge.game.GameEntity; +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.card.CardLists; +import forge.game.combat.Combat; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.spellability.SpellAbility; @@ -18,12 +25,39 @@ public class BranchAi extends SpellAbilityAi { final String aiLogic = sa.getParamOrDefault("AILogic", ""); if ("GrislySigil".equals(aiLogic)) { return SpecialCardAi.GrislySigil.consider(aiPlayer, sa); + } else if ("TgtAttacker".equals(aiLogic)) { + final Combat combat = aiPlayer.getGame().getCombat(); + if (combat == null || combat.getAttackingPlayer() != aiPlayer) { + return false; + } + + final CardCollection attackers = combat.getAttackers(); + final CardCollection attackingBattle = CardLists.filter(attackers, new Predicate() { + @Override + public boolean apply(Card card) { + final GameEntity def = combat.getDefenderByAttacker(combat.getBandOfAttacker(card)); + return def instanceof Card && ((Card)def).isBattle(); + } + }); + + if (!attackingBattle.isEmpty()) { + sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(attackingBattle)); + } else { + sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(attackers)); + } + + return sa.isTargetNumberValid(); } // TODO: expand for other cases where the AI is needed to make a decision on a branch return true; } + @Override + protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { + return canPlayAI(aiPlayer, sa) || mandatory; + } + @Override public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message, Map params) { return true; diff --git a/forge-gui/res/cardsfolder/r/rampaging_geoderm.txt b/forge-gui/res/cardsfolder/r/rampaging_geoderm.txt index dd055fea851..22b1d531231 100644 --- a/forge-gui/res/cardsfolder/r/rampaging_geoderm.txt +++ b/forge-gui/res/cardsfolder/r/rampaging_geoderm.txt @@ -5,7 +5,7 @@ PT:3/3 K:Trample K:Haste T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, target attacking creature gets +1/+1 until end of turn. If it's attacking a battle, put a +1/+1 counter on it instead. -SVar:TrigPump:DB$ Branch | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | BranchConditionSVar$ X | TrueSubAbility$ PutCounter | FalseSubAbility$ Pump +SVar:TrigPump:DB$ Branch | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | BranchConditionSVar$ X | TrueSubAbility$ PutCounter | FalseSubAbility$ Pump | AILogic$ TgtAttacker SVar:PutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ P1P1 SVar:Pump:DB$ Pump | Defined$ Targeted | NumAtt$ +1 | NumDef$ +1 SVar:X:Targeted$Valid Card.attackingBattle