From 9b1ed633f5076a44925a4a12c678c42730a40859 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 8 Jun 2019 07:08:59 +0300 Subject: [PATCH 1/2] - Fix and improve AI for Band Together and Courage in Crisis --- .../ai/ability/CountersProliferateAi.java | 6 ++- .../main/java/forge/ai/ability/FightAi.java | 41 ++++++++++++++----- forge-gui/res/cardsfolder/b/band_together.txt | 4 +- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java index af4624a0770..f108106dce3 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersProliferateAi.java @@ -105,7 +105,11 @@ public class CountersProliferateAi extends SpellAbilityAi { */ @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { - return canPlayAI(ai, sa); + if ("Always".equals(sa.getParam("AILogic"))) { + return true; + } + + return checkApiLogic(ai, sa); } /* diff --git a/forge-ai/src/main/java/forge/ai/ability/FightAi.java b/forge-ai/src/main/java/forge/ai/ability/FightAi.java index 3a1ad5b5528..7ee327e61c0 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -3,16 +3,14 @@ package forge.ai.ability; import forge.ai.*; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardLists; +import forge.game.card.*; import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; +import forge.util.Aggregates; import forge.util.MyRandom; import java.util.List; @@ -192,13 +190,36 @@ public class FightAi extends SpellAbilityAi { toughness += bonus; } if ("PowerDmg".equals(sa.getParam("AILogic"))) { - if (FightAi.canKill(aiCreature, humanCreature, power)) { - sa.getTargets().add(aiCreature); - if (!isChandrasIgnition) { - tgtFight.resetTargets(); - tgtFight.getTargets().add(humanCreature); + if ("2".equals(sa.getParam("TargetMax"))) { + // Band Together, uses up to two targets to deal damage to a single target + // TODO: Generalize this so that other TargetMax values can be properly accounted for + CardCollection aiCreaturesByPower = new CardCollection(aiCreatures); + CardLists.sortByPowerDesc(aiCreaturesByPower); + Card maxPower = aiCreaturesByPower.getFirst(); + if (maxPower != null && maxPower != aiCreature) { + power += maxPower.getNetPower(); // potential bonus from adding a second target + } + if (FightAi.canKill(aiCreature, humanCreature, power)) { + sa.getTargets().add(aiCreature); + if (maxPower != null) { + sa.getTargets().add(maxPower); + } + if (!isChandrasIgnition) { + tgtFight.resetTargets(); + tgtFight.getTargets().add(humanCreature); + } + return true; + } + } else { + // Other cards that use AILogic PowerDmg and a single target + if (FightAi.canKill(aiCreature, humanCreature, power)) { + sa.getTargets().add(aiCreature); + if (!isChandrasIgnition) { + tgtFight.resetTargets(); + tgtFight.getTargets().add(humanCreature); + } + return true; } - return true; } } else { if (FightAi.shouldFight(aiCreature, humanCreature, power, toughness)) { diff --git a/forge-gui/res/cardsfolder/b/band_together.txt b/forge-gui/res/cardsfolder/b/band_together.txt index f1dd68a179f..be270e51b83 100644 --- a/forge-gui/res/cardsfolder/b/band_together.txt +++ b/forge-gui/res/cardsfolder/b/band_together.txt @@ -1,7 +1,7 @@ Name:Band Together ManaCost:2 G Types:Instant -A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | AILogic$ PowerDamage | SubAbility$ SoulsDamage | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ None | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature. -SVar:SoulsDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | NumDmg$ X | References$ X | TargetUnique$ True | DamageSource$ ParentTarget | AILogic$ PowerDamage +A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | AILogic$ PowerDmg | SubAbility$ SoulsDamage | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ None | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature. +SVar:SoulsDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | NumDmg$ X | References$ X | TargetUnique$ True | DamageSource$ ParentTarget SVar:X:ParentTargeted$CardPower Oracle:Up to two target creatures you control each deal damage equal to their power to another target creature. From 1383549ea6b0fe87d9a79c005c0632fe02993c06 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 8 Jun 2019 07:10:32 +0300 Subject: [PATCH 2/2] - Fix imports --- forge-ai/src/main/java/forge/ai/ability/FightAi.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/FightAi.java b/forge-ai/src/main/java/forge/ai/ability/FightAi.java index 7ee327e61c0..c5f623866a9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -3,14 +3,16 @@ package forge.ai.ability; import forge.ai.*; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; -import forge.game.card.*; +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.card.CardCollectionView; +import forge.game.card.CardLists; import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; -import forge.util.Aggregates; import forge.util.MyRandom; import java.util.List; @@ -30,7 +32,7 @@ public class FightAi extends SpellAbilityAi { protected boolean checkApiLogic(final Player ai, final SpellAbility sa) { sa.resetTargets(); final Card source = sa.getHostCard(); - + // everything is defined or targeted above, can't do anything there? if (sa.hasParam("Defined") && !sa.usesTargeting()) { // TODO extend Logic for cards like Arena or Grothama @@ -117,7 +119,7 @@ public class FightAi extends SpellAbilityAi { if (!mandatory) { return false; } - + //try to make a good trade or no trade final Card source = sa.getHostCard(); List humCreatures = ai.getOpponents().getCreaturesInPlay(); @@ -246,7 +248,7 @@ public class FightAi extends SpellAbilityAi { for (Trigger t : aiCreature.getTriggers()) { if (t.getMode() == TriggerType.SpellCast) { final Map params = t.getMapParams(); - if ("Card.Self".equals(params.get("TargetsValid")) && "You".equals(params.get("ValidActivatingPlayer")) + if ("Card.Self".equals(params.get("TargetsValid")) && "You".equals(params.get("ValidActivatingPlayer")) && params.containsKey("Execute")) { SpellAbility heroic = AbilityFactory.getAbility(aiCreature.getSVar(params.get("Execute")),aiCreature); if ("Self".equals(heroic.getParam("Defined")) && "P1P1".equals(heroic.getParam("CounterType"))) {