From 40af8ba07103f3fc26480ef2d155d90519d2cd7e Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Mon, 4 Oct 2021 23:03:37 +0300 Subject: [PATCH 1/6] - Attempt to fix FightAi for Back for More. --- forge-ai/src/main/java/forge/ai/ability/FightAi.java | 6 +++++- forge-gui/res/cardsfolder/b/back_for_more.txt | 2 +- 2 files changed, 6 insertions(+), 2 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 a20997c9efe..528d101fd05 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -61,7 +61,11 @@ public class FightAi extends SpellAbilityAi { if (sa.hasParam("Defined")) { CardCollection fighter1List = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); if (fighter1List.isEmpty()) { - return true; + if ("ChosenAsTgt".equals(sa.getParam("AILogic"))) { + fighter1List.add(sa.getRootAbility().getTargetCard()); + } else { + return true; // FIXME: shouldn't this return "false" if nothing found? + } } Card fighter1 = fighter1List.get(0); for (Card humanCreature : humCreatures) { diff --git a/forge-gui/res/cardsfolder/b/back_for_more.txt b/forge-gui/res/cardsfolder/b/back_for_more.txt index efcae18b7a5..087b5eb9d7f 100755 --- a/forge-gui/res/cardsfolder/b/back_for_more.txt +++ b/forge-gui/res/cardsfolder/b/back_for_more.txt @@ -3,6 +3,6 @@ ManaCost:4 B G Types:Instant A:SP$ ChangeZone | Cost$ 4 B G | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | SubAbility$ DBImmediateTrigger | StackDescription$ SpellDescription | SpellDescription$ Return target creature card from your graveyard to the battlefield. When you do, it fights up to one target creature you don't control. (Each deals damage equal to its power to the other.) SVar:DBImmediateTrigger:DB$ ImmediateTrigger | RememberObjects$ Targeted | Execute$ DBFight | Secondary$ True | TriggerDescription$ When you do, it fights up to one target creature you don't control. (Each deals damage equal to its power to the other.) -SVar:DBFight:DB$ Fight | Defined$ DelayTriggerRemembered | ValidTgts$ Creature.YouDontCtrl | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose up to one target creature you don't control | StackDescription$ None +SVar:DBFight:DB$ Fight | Defined$ DelayTriggerRemembered | ValidTgts$ Creature.YouDontCtrl | TargetMin$ 0 | TargetMax$ 1 | AILogic$ ChosenAsTgt | TgtPrompt$ Choose up to one target creature you don't control | StackDescription$ None DeckHas:Ability$Graveyard Oracle:Return target creature card from your graveyard to the battlefield. When you do, it fights up to one target creature you don't control. (Each deals damage equal to its power to the other.) From fe60e5ef31355a529ad6d2a5172cb359cb4a6d41 Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Mon, 4 Oct 2021 23:04:11 +0300 Subject: [PATCH 2/6] - Attempt to fix FightAi for Back for More, part 2. --- forge-ai/src/main/java/forge/ai/ability/FightAi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 528d101fd05..c13235f7ce1 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -61,7 +61,7 @@ public class FightAi extends SpellAbilityAi { if (sa.hasParam("Defined")) { CardCollection fighter1List = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); if (fighter1List.isEmpty()) { - if ("ChosenAsTgt".equals(sa.getParam("AILogic"))) { + if ("ChosenAsTgt".equals(sa.getParam("AILogic")) && sa.getRootAbility().getTargetCard() != null) { fighter1List.add(sa.getRootAbility().getTargetCard()); } else { return true; // FIXME: shouldn't this return "false" if nothing found? From 2435111048f48e238fd5026ef0470c0cd36e964a Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Mon, 4 Oct 2021 23:03:03 +0200 Subject: [PATCH 3/6] Fix Combo Attack --- .../src/main/java/forge/ai/ability/FightAi.java | 17 +++++++++-------- .../src/main/java/forge/ai/ability/PumpAi.java | 2 +- forge-gui/res/cardsfolder/b/band_together.txt | 2 +- forge-gui/res/cardsfolder/c/combo_attack.txt | 2 +- 4 files changed, 12 insertions(+), 11 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 a20997c9efe..6fdc01ec346 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -214,14 +214,15 @@ public class FightAi extends SpellAbilityAi { CardCollection aiCreaturesByPower = new CardCollection(aiCreatures); CardLists.sortByPowerDesc(aiCreaturesByPower); Card maxPower = aiCreaturesByPower.getFirst(); - if (maxPower != null && maxPower != aiCreature) { + if (maxPower != aiCreature) { power += maxPower.getNetPower(); // potential bonus from adding a second target } - if (FightAi.canKill(aiCreature, humanCreature, power)) { + else if ("2".equals(sa.getParam("TargetMin"))) { + continue; + } + if (canKill(aiCreature, humanCreature, power)) { sa.getTargets().add(aiCreature); - if (maxPower != null) { - sa.getTargets().add(maxPower); - } + sa.getTargets().add(maxPower); if (!isChandrasIgnition) { tgtFight.resetTargets(); tgtFight.getTargets().add(humanCreature); @@ -230,7 +231,7 @@ public class FightAi extends SpellAbilityAi { } } else { // Other cards that use AILogic PowerDmg and a single target - if (FightAi.canKill(aiCreature, humanCreature, power)) { + if (canKill(aiCreature, humanCreature, power)) { sa.getTargets().add(aiCreature); if (!isChandrasIgnition) { tgtFight.resetTargets(); @@ -240,7 +241,7 @@ public class FightAi extends SpellAbilityAi { } } } else { - if (FightAi.shouldFight(aiCreature, humanCreature, power, toughness)) { + if (shouldFight(aiCreature, humanCreature, power, toughness)) { if ("Time to Feed".equals(sourceName)) { // flip targets final Card tmp = aiCreature; aiCreature = humanCreature; @@ -289,7 +290,7 @@ public class FightAi extends SpellAbilityAi { if (!canKill(opponent, fighter, -pumpDefense)) { // can survive return true; } else { - if (MyRandom.getRandom().nextInt(20)<(opponent.getCMC() - fighter.getCMC())) { // trade + if (MyRandom.getRandom().nextInt(20) < (opponent.getCMC() - fighter.getCMC())) { // trade return true; } } diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java index f8b5aa71862..3822c65bcd5 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -559,7 +559,7 @@ public class PumpAi extends PumpAiBase { list = CardLists.filter(list, Predicates.or(CardPredicates.Presets.CREATURES, new Predicate() { @Override public boolean apply(Card card) { - for (SpellAbility sa: card.getSpellAbilities()) { + for (SpellAbility sa : card.getSpellAbilities()) { if (sa.isAbility()) { return true; } diff --git a/forge-gui/res/cardsfolder/b/band_together.txt b/forge-gui/res/cardsfolder/b/band_together.txt index dc022f0f9c4..bccc9118373 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 | ImprintCards$ Targeted | AILogic$ PowerDmg | SubAbility$ DBPump | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ SpellDescription | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature. +A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | ImprintCards$ ThisTargetedCard | AILogic$ PowerDmg | SubAbility$ DBPump | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ SpellDescription | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature. SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | RememberObjects$ ThisTargetedCard | IsCurse$ True | SubAbility$ DBEachDamage | StackDescription$ None SVar:DBEachDamage:DB$ EachDamage | ValidCards$ Creature.IsImprinted | NumDmg$ X | DamageDesc$ damage equal to its power | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ None #NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded. diff --git a/forge-gui/res/cardsfolder/c/combo_attack.txt b/forge-gui/res/cardsfolder/c/combo_attack.txt index fcbb494d0ae..5c93f311137 100644 --- a/forge-gui/res/cardsfolder/c/combo_attack.txt +++ b/forge-gui/res/cardsfolder/c/combo_attack.txt @@ -1,7 +1,7 @@ Name:Combo Attack ManaCost:2 G Types:Sorcery -A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YourTeamCtrl | TgtPrompt$ Select two target creatures your team controls | ImprintCards$ Targeted | TargetMin$ 2 | TargetMax$ 2 | AILogic$ PowerDmg | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ Two target creatures your team controls each deal damage equal to their power to target creature. +A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YourTeamCtrl | TgtPrompt$ Select two target creatures your team controls | ImprintCards$ ThisTargetedCard | TargetMin$ 2 | TargetMax$ 2 | AILogic$ PowerDmg | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ Two target creatures your team controls each deal damage equal to their power to target creature. SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | RememberObjects$ ThisTargetedCard | IsCurse$ True | SubAbility$ DBEachDamage | StackDescription$ None SVar:DBEachDamage:DB$ EachDamage | ValidCards$ Creature.IsImprinted | NumDmg$ X | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ None #NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded. From baff2a548617ea807d5285da65589dbb87a5f09c Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Tue, 5 Oct 2021 07:04:43 +0300 Subject: [PATCH 4/6] - Minor change to the code. --- forge-ai/src/main/java/forge/ai/ability/FightAi.java | 9 +++++---- forge-gui-mobile-dev/src/forge/app/Main.java | 8 +++++--- 2 files changed, 10 insertions(+), 7 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 b509f31a87c..e065c168cf6 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -60,13 +60,14 @@ public class FightAi extends SpellAbilityAi { // assumes the triggered card belongs to the ai if (sa.hasParam("Defined")) { CardCollection fighter1List = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); - if (fighter1List.isEmpty()) { - if ("ChosenAsTgt".equals(sa.getParam("AILogic")) && sa.getRootAbility().getTargetCard() != null) { + if ("ChosenAsTgt".equals(sa.getParam("AILogic")) && sa.getRootAbility().getTargetCard() != null) { + if (fighter1List.isEmpty()) { fighter1List.add(sa.getRootAbility().getTargetCard()); - } else { - return true; // FIXME: shouldn't this return "false" if nothing found? } } + if (fighter1List.isEmpty()) { + return true; // FIXME: shouldn't this return "false" if nothing found? + } Card fighter1 = fighter1List.get(0); for (Card humanCreature : humCreatures) { if (ComputerUtilCombat.getDamageToKill(humanCreature) <= fighter1.getNetPower() diff --git a/forge-gui-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index 7b84b004902..e0050660afd 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -55,12 +55,12 @@ public class Main { } // Set this to "true" to make the mobile game port run as a full-screen desktop application - boolean desktopMode = cmd.hasOption("fullscreen"); + boolean desktopMode = true;//cmd.hasOption("fullscreen"); // Set this to the location where you want the mobile game port to look for assets when working as a full-screen desktop application // (uncomment the bottom version and comment the top one to load the res folder from the current folder the .jar is in if you would // like to make the game load from a desktop game folder configuration). - String desktopModeAssetsDir = "../forge-gui/"; - //String desktopModeAssetsDir = "./"; + //String desktopModeAssetsDir = "../forge-gui/"; + String desktopModeAssetsDir = "./"; // Assets directory used when the game fully emulates smartphone/tablet mode (desktopMode = false), useful when debugging from IDE String assetsDir = AssetsDownloader.SHARE_DESKTOP_ASSETS ? "../forge-gui/" : "testAssets/"; @@ -154,12 +154,14 @@ public class Main { public void restart() { if (RestartUtil.prepareForRestart()) { Gdx.app.exit(); + System.exit(0); } } @Override public void exit() { Gdx.app.exit(); //can just use Gdx.app.exit for desktop + System.exit(0); } @Override From 94d8342279632fe74848fb69feb2bda7132ec618 Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Tue, 5 Oct 2021 07:06:31 +0300 Subject: [PATCH 5/6] - Remove unintended commit. --- forge-gui-mobile-dev/src/forge/app/Main.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/forge-gui-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index e0050660afd..f16a582797a 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -55,12 +55,12 @@ public class Main { } // Set this to "true" to make the mobile game port run as a full-screen desktop application - boolean desktopMode = true;//cmd.hasOption("fullscreen"); + boolean desktopMode = cmd.hasOption("fullscreen"); // Set this to the location where you want the mobile game port to look for assets when working as a full-screen desktop application // (uncomment the bottom version and comment the top one to load the res folder from the current folder the .jar is in if you would // like to make the game load from a desktop game folder configuration). - //String desktopModeAssetsDir = "../forge-gui/"; - String desktopModeAssetsDir = "./"; + String desktopModeAssetsDir = "../forge-gui/"; + //String desktopModeAssetsDir = "./"; // Assets directory used when the game fully emulates smartphone/tablet mode (desktopMode = false), useful when debugging from IDE String assetsDir = AssetsDownloader.SHARE_DESKTOP_ASSETS ? "../forge-gui/" : "testAssets/"; From d444c7ec82510d82ec53c67eb1f8b21afbeff3ef Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Tue, 5 Oct 2021 07:54:28 +0300 Subject: [PATCH 6/6] - Added puzzle PS_MID1. --- forge-gui/res/puzzle/PS_MID1.pzl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 forge-gui/res/puzzle/PS_MID1.pzl diff --git a/forge-gui/res/puzzle/PS_MID1.pzl b/forge-gui/res/puzzle/PS_MID1.pzl new file mode 100644 index 00000000000..721142301cb --- /dev/null +++ b/forge-gui/res/puzzle/PS_MID1.pzl @@ -0,0 +1,20 @@ +[metadata] +Name:Possibility Storm - Innistrad: Midnight Hunt #01 +URL:https://i2.wp.com/www.possibilitystorm.com/wp-content/uploads/2021/09/184MID1.png +Goal:Win +Turns:1 +Difficulty:Rare +Description:Win this turn. Your opponent has 22 cards left in their library. Your solution must work regardless what those cards are. You have 20 cards left in your library, and you know that exactly 10 of them are creatures. +[state] +humanlife=5 +ailife=16 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Island;Maddening Cacophony;Tapping at the Window;Zulaport Duelist;Blood Pact +humanlibrary=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper;Gavony Trapper +humanbattlefield=Dreadhound;Koma's Faithful;Lord of the Forsaken;Ruin Crab;Necroblossom Snarl|NoETBTrigs;Necroblossom Snarl|NoETBTrigs;Vineglimmer Snarl|NoETBTrigs;Vineglimmer Snarl|NoETBTrigs;Shipwreck Marsh|NoETBTrigs;Shipwreck Marsh|NoETBTrigs +ailibrary=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt +aibattlefield=Cogwork Archivist +aiprecast=Starnheim Unleashed;Starnheim Unleashed +removesummoningsickness=true