diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java index 0f6a962a706..0cd99b202bb 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java @@ -152,6 +152,7 @@ public void initialize() { lstControls.add(Pair.of(view.getCbTokensInSeparateRow(), FPref.UI_TOKENS_IN_SEPARATE_ROW)); lstControls.add(Pair.of(view.getCbSeparateCombatStacks(), FPref.UI_SEPARATE_COMBAT_STACKS)); lstControls.add(Pair.of(view.getCbManaLostPrompt(), FPref.UI_MANA_LOST_PROMPT)); + lstControls.add(Pair.of(view.getCbAutoCallCoinFlip(), FPref.UI_AUTO_CALL_COIN_FLIP)); lstControls.add(Pair.of(view.getCbEscapeEndsTurn(), FPref.UI_ALLOW_ESC_TO_END_TURN)); lstControls.add(Pair.of(view.getCbDetailedPaymentDesc(), FPref.UI_DETAILED_SPELLDESC_IN_PROMPT)); lstControls.add(Pair.of(view.getCbGrayText(), FPref.UI_GRAY_INACTIVE_TEXT)); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java index 2334d3dec27..fec2174c7f9 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java @@ -76,6 +76,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final JCheckBox cbManaBurn = new OptionsCheckBox(localizer.getMessage("cbManaBurn")); private final JCheckBox cbOrderCombatants = new OptionsCheckBox(localizer.getMessage("cbOrderCombatants")); private final JCheckBox cbManaLostPrompt = new OptionsCheckBox(localizer.getMessage("cbManaLostPrompt")); + private final JCheckBox cbAutoCallCoinFlip = new OptionsCheckBox(localizer.getMessage("cbAutoCallCoinFlip")); private final JCheckBox cbDevMode = new OptionsCheckBox(localizer.getMessage("cbDevMode")); private final JCheckBox cbLoadCardsLazily = new OptionsCheckBox(localizer.getMessage("cbLoadCardsLazily")); private final JCheckBox cbLoadArchivedFormats = new OptionsCheckBox(localizer.getMessage("cbLoadArchivedFormats")); @@ -249,6 +250,9 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbManaLostPrompt, titleConstraints); pnlPrefs.add(new NoteLabel(localizer.getMessage("nlManaLostPrompt")), descriptionConstraints); + pnlPrefs.add(cbAutoCallCoinFlip, titleConstraints); + pnlPrefs.add(new NoteLabel(localizer.getMessage("nlAutoCallCoinFlip")), descriptionConstraints); + pnlPrefs.add(cbpStackAdditions, comboBoxConstraints); pnlPrefs.add(new NoteLabel(localizer.getMessage("nlpStackAdditions")), descriptionConstraints); @@ -1075,6 +1079,10 @@ public final JCheckBox getCbManaLostPrompt() { return cbManaLostPrompt; } + public final JCheckBox getCbAutoCallCoinFlip() { + return cbAutoCallCoinFlip; + } + public final JCheckBox getCbDetailedPaymentDesc() { return cbDetailedPaymentDesc; } diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index da48d102b29..67ef2001e99 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -94,6 +94,7 @@ cbEnableAICheats=Allow AI Cheating cbManaBurn=Mana Burn cbOrderCombatants=Order Combatants cbManaLostPrompt=Prompt Mana Pool Emptying +cbAutoCallCoinFlip=Auto-Call Coin Flips cbDevMode=Developer Mode cbLoadCardsLazily=Load Card Scripts Lazily cbLoadArchivedFormats=Load Archived Formats @@ -207,6 +208,7 @@ nlEnableAICheats=Allow the AI to cheat to gain advantage (for personalities that nlManaBurn=Play with mana burn (from pre-Magic 2010 rules). nlOrderCombatants=Play with legacy ordering combatants (rule from Magic 2010 to pre-Foundations). nlManaLostPrompt=When enabled, you get a warning if passing priority would cause you to lose mana in your mana pool. +nlAutoCallCoinFlip=Automatically call Heads on coin flips where only the win/lose outcome matters (e.g. Krark's Thumb). Disable to manually choose each call. nlEnforceDeckLegality=Enforces deck legality relevant to each environment (minimum deck sizes, max card count etc). nlpAiSideboardingMode=Choose the way the AI sideboards: Off (the AI doesn't sideboard), AI (the AI sideboards for itself, currently mostly random), Human For AI (the human player sideboards for the AI in Constructed formats). nlExperimentalRestore=EXPERIMENTAL - Stores a snapshot to be used for undoing spells or abilities diff --git a/forge-gui/src/main/java/forge/localinstance/properties/ForgePreferences.java b/forge-gui/src/main/java/forge/localinstance/properties/ForgePreferences.java index 538865f7772..dff5bf9f6fb 100644 --- a/forge-gui/src/main/java/forge/localinstance/properties/ForgePreferences.java +++ b/forge-gui/src/main/java/forge/localinstance/properties/ForgePreferences.java @@ -126,6 +126,7 @@ public enum FPref implements PreferencesStore.IPref { UI_ALLOW_ESC_TO_END_TURN ("false"), UI_ALT_PLAYERINFOLAYOUT ("false"), UI_ALT_PLAYERZONETABS ("false"), + UI_AUTO_CALL_COIN_FLIP ("true"), YIELD_INTERRUPT_ON_ATTACKERS ("true"), YIELD_INTERRUPT_ON_OPPONENT_SPELL ("true"), YIELD_INTERRUPT_ON_TARGETING ("false"), diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 0bbab57ea02..3ab20d6bb50 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -1853,6 +1853,9 @@ public boolean chooseBinary(final SpellAbility sa, final String question, final final List labels; switch (kindOfChoice) { case HeadsOrTails: + if (FModel.getPreferences().getPrefBoolean(FPref.UI_AUTO_CALL_COIN_FLIP)) { + return true; // Auto-call Heads — for win/lose flips the call is irrelevant (50/50) + } labels = ImmutableList.of(localizer.getMessage("lblHeads"), localizer.getMessage("lblTails")); break; case TapOrUntap: @@ -1888,6 +1891,12 @@ public boolean chooseBinary(final SpellAbility sa, final String question, final @Override public boolean chooseFlipResult(final SpellAbility sa, final Player flipper, final boolean call) { + // Krark's Thumb / Frenetic Efreet replacement effect: choose which of two flips to keep. + // For called flips (heads/tails was called), we already auto-called Heads above, so picking + // the matching result guarantees a "win". For NoCall flips, the player still chooses. + if (call && FModel.getPreferences().getPrefBoolean(FPref.UI_AUTO_CALL_COIN_FLIP)) { + return true; + } final List labelsSrc = call ? List.of(localizer.getMessage("lblHeads"), localizer.getMessage("lblTails")) : List.of(localizer.getMessage("lblWinTheFlip"), localizer.getMessage("lblLoseTheFlip")); return getGui().one(sa.getHostCard().getDisplayName() + " - " + localizer.getMessage("lblChooseAResult"), labelsSrc).equals(labelsSrc.get(0));