From c6bf9e3c6d67d173ed132cc948f56ef91cb78f7f Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Mon, 18 Oct 2021 10:21:28 +0200 Subject: [PATCH 1/3] Clean up --- forge-ai/src/main/java/forge/ai/ComputerUtil.java | 10 +++++----- forge-ai/src/main/java/forge/ai/ComputerUtilCard.java | 2 -- forge-ai/src/main/java/forge/ai/ability/GoadAi.java | 1 - .../src/main/java/forge/ai/ability/MustAttackAi.java | 1 - .../src/main/java/forge/ai/ability/MustBlockAi.java | 1 - .../java/forge/ai/ability/PermanentNoncreatureAi.java | 3 +-- .../src/main/java/forge/ai/ability/RestartGameAi.java | 5 ----- forge-gui/res/cardsfolder/b/bounding_wolf.txt | 2 +- 8 files changed, 7 insertions(+), 18 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index b5a129a85d2..87e20e84099 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -1910,11 +1910,7 @@ public class ComputerUtil { * @return true if the creature dies according to current board position. */ public static boolean predictCreatureWillDieThisTurn(final Player ai, final Card creature, final SpellAbility excludeSa) { - final Game game = creature.getGame(); - - // a creature will die as a result of combat - boolean willDieInCombat = game.getPhaseHandler().inCombat() - && ComputerUtilCombat.combatantWouldBeDestroyed(creature.getController(), creature, game.getCombat()); + final Game game = ai.getGame(); // a creature will [hopefully] die from a spell on stack boolean willDieFromSpell = false; @@ -1933,6 +1929,10 @@ public class ComputerUtil { } willDieFromSpell = !noStackCheck && predictThreatenedObjects(creature.getController(), excludeSa).contains(creature); + // a creature will die as a result of combat + boolean willDieInCombat = !willDieFromSpell && game.getPhaseHandler().inCombat() + && ComputerUtilCombat.combatantWouldBeDestroyed(creature.getController(), creature, game.getCombat()); + return willDieInCombat || willDieFromSpell; } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index ec4399f9a09..5604582d97e 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -750,7 +750,6 @@ public class ComputerUtilCard { for (final Entry entry : map.entrySet()) { final String type = entry.getKey(); - // Log.debug(type + " - " + entry.getValue()); if (max < entry.getValue()) { max = entry.getValue(); @@ -784,7 +783,6 @@ public class ComputerUtilCard { // TODO JAVA 8 use getOrDefault for (final Card c : list) { - // Changeling are all creature types, they are not interesting for // counting creature types if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) { diff --git a/forge-ai/src/main/java/forge/ai/ability/GoadAi.java b/forge-ai/src/main/java/forge/ai/ability/GoadAi.java index 74bb91e6b61..b2d8b30b9ef 100644 --- a/forge-ai/src/main/java/forge/ai/ability/GoadAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/GoadAi.java @@ -19,7 +19,6 @@ public class GoadAi extends SpellAbilityAi { @Override protected boolean checkApiLogic(final Player ai, final SpellAbility sa) { - final Card source = sa.getHostCard(); final Game game = source.getGame(); diff --git a/forge-ai/src/main/java/forge/ai/ability/MustAttackAi.java b/forge-ai/src/main/java/forge/ai/ability/MustAttackAi.java index 9916e09314a..000a25ded94 100644 --- a/forge-ai/src/main/java/forge/ai/ability/MustAttackAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/MustAttackAi.java @@ -25,7 +25,6 @@ public class MustAttackAi extends SpellAbilityAi { */ @Override protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - boolean chance; // TODO - implement AI diff --git a/forge-ai/src/main/java/forge/ai/ability/MustBlockAi.java b/forge-ai/src/main/java/forge/ai/ability/MustBlockAi.java index 36d271634d3..4e6a51dcfde 100644 --- a/forge-ai/src/main/java/forge/ai/ability/MustBlockAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/MustBlockAi.java @@ -160,7 +160,6 @@ public class MustBlockAi extends SpellAbilityAi { private List determineGoodBlockers(final Card attacker, final Player ai, Player defender, SpellAbility sa, final boolean onlyLethal, final boolean testTapped) { - List list = Lists.newArrayList(); list = CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); diff --git a/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java b/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java index be358b2b6ea..c9c2b049e7e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PermanentNoncreatureAi.java @@ -42,8 +42,7 @@ public class PermanentNoncreatureAi extends PermanentAi { CardCollection targets = CardLists.getTargetableCards(game.getCardsIn(origin), effectExile); if (sourceName.equals("Suspension Field") || sourceName.equals("Detention Sphere")) { - // existing "exile until leaves" enchantments only target - // opponent's permanents + // existing "exile until leaves" enchantments only target opponent's permanents // TODO: consider replacing the condition with host.hasSVar("OblivionRing") targets = CardLists.filterControlledBy(targets, ai.getOpponents()); } diff --git a/forge-ai/src/main/java/forge/ai/ability/RestartGameAi.java b/forge-ai/src/main/java/forge/ai/ability/RestartGameAi.java index f32afba4a81..ac35bf1d0c2 100644 --- a/forge-ai/src/main/java/forge/ai/ability/RestartGameAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/RestartGameAi.java @@ -38,9 +38,4 @@ public class RestartGameAi extends SpellAbilityAi { return false; } - @Override - protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - // This trigger AI is completely unused, but return true just in case - return true; - } } diff --git a/forge-gui/res/cardsfolder/b/bounding_wolf.txt b/forge-gui/res/cardsfolder/b/bounding_wolf.txt index f4004c4dc8c..c233e217d5f 100644 --- a/forge-gui/res/cardsfolder/b/bounding_wolf.txt +++ b/forge-gui/res/cardsfolder/b/bounding_wolf.txt @@ -1,6 +1,6 @@ Name:Bounding Wolf ManaCost:2 G -Types:Creature wolf +Types:Creature Wolf PT:3/2 K:Flash K:Reach From 501d5501dbea078be6511a2a5aee8adda7e36188 Mon Sep 17 00:00:00 2001 From: TRT <> Date: Mon, 18 Oct 2021 12:01:43 +0200 Subject: [PATCH 2/3] Fix Master of the Wild Hunt --- forge-gui/res/cardsfolder/m/master_of_the_wild_hunt.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/m/master_of_the_wild_hunt.txt b/forge-gui/res/cardsfolder/m/master_of_the_wild_hunt.txt index d2ea8534768..4a02842ee7a 100644 --- a/forge-gui/res/cardsfolder/m/master_of_the_wild_hunt.txt +++ b/forge-gui/res/cardsfolder/m/master_of_the_wild_hunt.txt @@ -8,7 +8,8 @@ A:AB$ DealDamage | Cost$ T | SubAbility$ TapWolves | ValidTgts$ Creature | NumDm SVar:TapWolves:DB$ TapAll | ValidCards$ Creature.Wolf+YouCtrl+untapped | RememberTapped$ True | SubAbility$ WildHuntDamage | StackDescription$ None SVar:WildHuntDamage:DB$ RepeatEach | RepeatSubAbility$ WolfStrike | UseImprinted$ True | RepeatCards$ Card.IsRemembered | DamageMap$ True | SubAbility$ HuntedDamage | StackDescription$ None SVar:WolfStrike:DB$ DealDamage | DamageSource$ Imprinted | NumDmg$ X | Defined$ ParentTarget | StackDescription$ None -SVar:HuntedDamage:DB$ DealDamage | DamageSource$ ParentTarget | NumDmg$ Y | DividerOnResolution$ ParentTargetedController | Defined$ Remembered | StackDescription$ None +SVar:HuntedDamage:DB$ DealDamage | DamageSource$ ParentTarget | NumDmg$ Y | DividerOnResolution$ ParentTargetedController | Defined$ Remembered | SubAbility$ DBDamageResolve | StackDescription$ None +SVar:DBDamageResolve:DB$ DamageResolve SVar:X:Imprinted$CardPower SVar:Y:Targeted$CardPower SVar:Picture:http://www.wizards.com/global/images/magic/general/master_of_the_wild_hunt.jpg From 5b72d1f682a01cf5f884f11448a0b069d5b1e722 Mon Sep 17 00:00:00 2001 From: TRT <> Date: Mon, 18 Oct 2021 15:26:09 +0200 Subject: [PATCH 3/3] Fix some more NPE related to gauntlets --- .../ability/effects/DamageDealEffect.java | 8 +---- .../home/gauntlet/CSubmenuGauntletBuild.java | 6 ++-- .../src/main/java/forge/deck/DeckgenUtil.java | 4 ++- .../gamemodes/gauntlet/GauntletUtil.java | 30 ++++++++++--------- .../gamemodes/tournament/TournamentUtil.java | 6 ++-- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 00b3d408f14..fc01ff79c7f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -197,13 +197,7 @@ public class DamageDealEffect extends DamageBaseEffect { return; } - CardCollection assigneeCards = new CardCollection(); - // Do we have a way of doing this in a better fashion? - for (GameObject obj : tgts) { - if (obj instanceof Card) { - assigneeCards.add((Card) obj); - } - } + CardCollection assigneeCards = new CardCollection(Iterables.filter(tgts, Card.class)); Player assigningPlayer = players.get(0); Map map = assigningPlayer.getController().assignCombatDamage(sourceLKI, assigneeCards, dmg, null, true); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java index 047b89af095..1bee7b3f346 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java @@ -122,8 +122,8 @@ public enum CSubmenuGauntletBuild implements ICDoc { } private void addDeck() { - final Deck deckToAdd = view.getLstLeft().getPlayer().getDeck(); - if ( null == deckToAdd ) { + final Deck deckToAdd = view.getLstLeft().getPlayer() != null ? view.getLstLeft().getPlayer().getDeck() : null; + if (null == deckToAdd) { return; } workingDecks.add(deckToAdd); @@ -145,7 +145,7 @@ public enum CSubmenuGauntletBuild implements ICDoc { private void deckUp() { final int oldIndex = view.getLstRight().getSelectedIndex(); - if (oldIndex == 0) { return; } + if (oldIndex <= 0) { return; } final Deck movingDeck = workingDecks.remove(oldIndex); workingDecks.add(oldIndex - 1, movingDeck); diff --git a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java index a83b31277da..013320d480b 100644 --- a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java +++ b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java @@ -144,7 +144,7 @@ public class DeckgenUtil { * @return */ public static Deck buildCardGenDeck(PaperCard card, PaperCard secondKeycard, GameFormat format, boolean isForAI){ - return buildLDACardGenDeck(card, format, isForAI); + return buildLDACardGenDeck(card, format, isForAI); } /** @@ -425,6 +425,8 @@ public class DeckgenUtil { /** @return {@link forge.deck.Deck} */ public static Deck getRandomCustomDeck() { final IStorage allDecks = FModel.getDecks().getConstructed(); + // in case user has not created any yet + if (allDecks.size() == 0) { return null; } final int rand = (int) (Math.floor(MyRandom.getRandom().nextDouble() * allDecks.size())); final String name = allDecks.getItemNames().toArray(new String[0])[rand]; return allDecks.get(name); diff --git a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java index 7a6a9e10326..504304f3a57 100644 --- a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java +++ b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java @@ -37,30 +37,32 @@ public class GauntletUtil { deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getStandard().getFilterPrinted(),true); break; case STANDARD_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),true); + break; case PIONEER_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getPioneer(),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getPioneer(),true); + break; case HISTORIC_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getHistoric(),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getHistoric(),true); + break; case MODERN_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(),true); + break; case LEGACY_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Legacy"),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Legacy"),true); + break; case VINTAGE_CARDGEN_DECK: - deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Vintage"),true); - break; + deck = DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Vintage"),true); + break; case MODERN_COLOR_DECK: deck = DeckgenUtil.getRandomColorDeck(FModel.getFormats().getModern().getFilterPrinted(),true); break; case CUSTOM_DECK: deck = DeckgenUtil.getRandomCustomDeck(); - eventNames.add(deck.getName()); - break; + if (deck != null) { // fall back to precon if none available + eventNames.add(deck.getName()); + break; + } case PRECONSTRUCTED_DECK: deck = DeckgenUtil.getRandomPreconDeck(); eventNames.add(deck.getName()); diff --git a/forge-gui/src/main/java/forge/gamemodes/tournament/TournamentUtil.java b/forge-gui/src/main/java/forge/gamemodes/tournament/TournamentUtil.java index 5ce8368abc7..666ceeae997 100644 --- a/forge-gui/src/main/java/forge/gamemodes/tournament/TournamentUtil.java +++ b/forge-gui/src/main/java/forge/gamemodes/tournament/TournamentUtil.java @@ -56,8 +56,10 @@ public class TournamentUtil { break; case CUSTOM_DECK: deck = DeckgenUtil.getRandomCustomDeck(); - eventNames.add(deck.getName()); - break; + if (deck != null) { // fall back to precon if none available + eventNames.add(deck.getName()); + break; + } case PRECONSTRUCTED_DECK: deck = DeckgenUtil.getRandomPreconDeck(); eventNames.add(deck.getName());