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..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,8 +60,13 @@ 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 ("ChosenAsTgt".equals(sa.getParam("AILogic")) && sa.getRootAbility().getTargetCard() != null) { + if (fighter1List.isEmpty()) { + fighter1List.add(sa.getRootAbility().getTargetCard()); + } + } if (fighter1List.isEmpty()) { - return true; + return true; // FIXME: shouldn't this return "false" if nothing found? } Card fighter1 = fighter1List.get(0); for (Card humanCreature : humCreatures) { @@ -214,14 +219,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 +236,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 +246,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 +295,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-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index 7b84b004902..f16a582797a 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -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 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.) 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. 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