diff --git a/.gitattributes b/.gitattributes index 082f4e43c12..c11242b1d10 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5962,6 +5962,7 @@ res/cardsfolder/k/krark_clan_ironworks.txt svneol=native#text/plain res/cardsfolder/k/krark_clan_ogre.txt svneol=native#text/plain res/cardsfolder/k/krark_clan_shaman.txt svneol=native#text/plain res/cardsfolder/k/krark_clan_stoker.txt svneol=native#text/plain +res/cardsfolder/k/krarks_thumb.txt -text res/cardsfolder/k/krasis_incubation.txt -text res/cardsfolder/k/kraul_warrior.txt -text res/cardsfolder/k/krenko_mob_boss.txt -text @@ -14318,7 +14319,7 @@ src/main/java/forge/card/trigger/TriggerDevoured.java -text src/main/java/forge/card/trigger/TriggerDiscarded.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerDrawn.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerEvolved.java -text -src/main/java/forge/card/trigger/TriggerFlipped.java -text +src/main/java/forge/card/trigger/TriggerFlippedCoin.java -text src/main/java/forge/card/trigger/TriggerHandler.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerLandPlayed.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerLifeGained.java svneol=native#text/plain diff --git a/res/cardsfolder/c/chance_encounter.txt b/res/cardsfolder/c/chance_encounter.txt index 5dd3ed7c070..15b9d73b1b6 100644 --- a/res/cardsfolder/c/chance_encounter.txt +++ b/res/cardsfolder/c/chance_encounter.txt @@ -1,7 +1,7 @@ Name:Chance Encounter ManaCost:2 R R Types:Enchantment -T:Mode$ Flipped | ValidPlayer$ You | ValidResult$ Win | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you win a coin flip, put a luck counter on CARDNAME. +T:Mode$ FlippedCoin | ValidPlayer$ You | ValidResult$ Win | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you win a coin flip, put a luck counter on CARDNAME. SVar:TrigPutCounter:AB$ PutCounter | Cost$ 0 | CounterType$ LUCK | CounterNum$ 1 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.Self+counters_GE10_LUCK | Execute$ TrigWin | TriggerDescription$ At the beginning of your upkeep, if CARDNAME has ten or more luck counters on it, you win the game. SVar:TrigWin:AB$ WinsGame | Cost$ 0 | Defined$ You diff --git a/res/cardsfolder/k/krarks_thumb.txt b/res/cardsfolder/k/krarks_thumb.txt new file mode 100644 index 00000000000..8afe6de5839 --- /dev/null +++ b/res/cardsfolder/k/krarks_thumb.txt @@ -0,0 +1,6 @@ +Name:Krark's Thumb +ManaCost:2 +Types:Legendary Artifact +S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would flip a coin, instead flip two coins and ignore one. | Description$ If you would flip a coin, instead flip two coins and ignore one. +SVar:Picture:http://www.wizards.com/global/images/magic/general/krarks_thumb.jpg +Oracle:If you would flip a coin, instead flip two coins and ignore one. diff --git a/src/main/java/forge/card/ability/effects/FlipCoinEffect.java b/src/main/java/forge/card/ability/effects/FlipCoinEffect.java index e01a33f23d4..d7264b14d5c 100644 --- a/src/main/java/forge/card/ability/effects/FlipCoinEffect.java +++ b/src/main/java/forge/card/ability/effects/FlipCoinEffect.java @@ -2,7 +2,6 @@ package forge.card.ability.effects; import java.util.HashMap; import java.util.List; - import forge.Card; import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityUtils; @@ -12,6 +11,7 @@ import forge.card.spellability.SpellAbility; import forge.card.trigger.TriggerType; import forge.game.event.GameEventFlipCoin; import forge.game.player.Player; +import forge.gui.GuiChoose; import forge.gui.GuiDialog; import forge.util.MyRandom; @@ -38,6 +38,7 @@ public class FlipCoinEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getSourceCard(); final Player player = host.getController(); + int flipMultiplier = 1; // For multiple copies of Krark's Thumb final List playersToFlip = AbilityUtils.getDefinedPlayers(host, sa.getParam("Flipper"), sa); if (playersToFlip.isEmpty()) { @@ -52,20 +53,22 @@ public class FlipCoinEffect extends SpellAbilityEffect { final boolean noCall = sa.hasParam("NoCall"); boolean victory = false; if (!noCall) { - victory = GuiDialog.flipCoin(caller.get(0), host); + flipMultiplier = getFilpMultiplier(caller.get(0)); + victory = flipCoinCall(caller.get(0), host, flipMultiplier); } // Run triggers HashMap runParams = new HashMap(); runParams.put("Player", caller.get(0)); runParams.put("Result", (Boolean) victory); - player.getGame().getTriggerHandler().runTrigger(TriggerType.Flipped, runParams, false); + player.getGame().getTriggerHandler().runTrigger(TriggerType.FlippedCoin, runParams, false); final boolean rememberResult = sa.hasParam("RememberResult"); for (final Player flipper : playersToFlip) { if (noCall) { - final boolean resultIsHeads = FlipCoinEffect.flipCoinNoCall(sa.getSourceCard(), flipper); + flipMultiplier = getFilpMultiplier(flipper); + final boolean resultIsHeads = FlipCoinEffect.flipCoinNoCall(sa.getSourceCard(), flipper, flipMultiplier); if (rememberResult) { host.addFlipResult(flipper, resultIsHeads ? "Heads" : "Tails"); } @@ -126,19 +129,79 @@ public class FlipCoinEffect extends SpellAbilityEffect { * * @param source the source card. * @param flipper the player flipping the coin. + * @param multiplier * @return a boolean. */ - public static boolean flipCoinNoCall(final Card source, final Player flipper) { - final boolean resultIsHeads = MyRandom.getRandom().nextBoolean(); + public static boolean flipCoinNoCall(final Card source, final Player flipper, final int multiplier) { + String[] results = new String[multiplier]; + String result; + for (int i = 0; i < multiplier; i++) { + final boolean resultIsHeads = MyRandom.getRandom().nextBoolean(); + flipper.getGame().fireEvent(new GameEventFlipCoin()); + results[i] = resultIsHeads ? " heads." : " tails."; + } + if (multiplier == 1) { + result = results[0]; + } else { + result = flipper.getController().chooseFilpResult(source, flipper, results, false); + } + final StringBuilder sb = new StringBuilder(); + sb.append(flipper.getName()); + sb.append("'s flip comes up"); + sb.append(result); + GuiDialog.message(sb.toString(), source + " Flip result:"); + return result.equals(" heads."); + } - flipper.getGame().fireEvent(new GameEventFlipCoin()); - final StringBuilder result = new StringBuilder(); - result.append(flipper.getName()); - result.append("'s flip comes up"); - result.append(resultIsHeads ? " heads." : " tails."); - GuiDialog.message(result.toString(), source + " Flip result:"); + /** + *

+ * flipCoinCall. + *

+ * + * @param caller + * a {@link forge.game.player.Player} object. + * @param source + * a {@link forge.Card} object. + * @param multiplier + * @return a boolean. + */ + public static boolean flipCoinCall(final Player caller, final Card source, final int multiplier) { + String choice; + final String[] choices = { "heads", "tails" }; + String[] results = new String[multiplier]; + for (int i = 0; i < multiplier; i++) { + // Play the Flip A Coin sound + caller.getGame().fireEvent(new GameEventFlipCoin()); + final boolean flip = MyRandom.getRandom().nextBoolean(); + if (caller.isHuman()) { + choice = GuiChoose.one(source.getName() + " - Call coin flip", choices); + } else { + choice = choices[MyRandom.getRandom().nextInt(2)]; + } + final boolean winFlip = flip == choice.equals(choices[0]); + final String winMsg = winFlip ? " wins flip." : " loses flip."; + results[i] = winMsg; + } + String result; + if (multiplier == 1) { + result = results[0]; + } else { + result = caller.getController().chooseFilpResult(source, caller, results, true); + } + + GuiDialog.message(source.getName() + " - " + caller + result, source.getName()); + + return result.equals(" wins flip."); + } - return resultIsHeads; + public static int getFilpMultiplier(final Player flipper) { + int i = 0; + for (String kw : flipper.getKeywords()) { + if (kw.startsWith("If you would flip a coin")) { + i++; + } + } + return 1 << i; } } diff --git a/src/main/java/forge/card/trigger/TriggerFlipped.java b/src/main/java/forge/card/trigger/TriggerFlippedCoin.java similarity index 90% rename from src/main/java/forge/card/trigger/TriggerFlipped.java rename to src/main/java/forge/card/trigger/TriggerFlippedCoin.java index ac57460c27a..c6ba30806f6 100644 --- a/src/main/java/forge/card/trigger/TriggerFlipped.java +++ b/src/main/java/forge/card/trigger/TriggerFlippedCoin.java @@ -28,7 +28,7 @@ import forge.card.spellability.SpellAbility; * @author Forge * @version $Id: TriggerFlipped.java 17802 2012-10-31 08:05:14Z Max mtg $ */ -public class TriggerFlipped extends Trigger { +public class TriggerFlippedCoin extends Trigger { /** *

@@ -42,7 +42,7 @@ public class TriggerFlipped extends Trigger { * @param intrinsic * the intrinsic */ - public TriggerFlipped(final java.util.Map params, final Card host, final boolean intrinsic) { + public TriggerFlippedCoin(final java.util.Map params, final Card host, final boolean intrinsic) { super(params, host, intrinsic); } diff --git a/src/main/java/forge/card/trigger/TriggerType.java b/src/main/java/forge/card/trigger/TriggerType.java index 78cf9cd4854..20ea8da3434 100644 --- a/src/main/java/forge/card/trigger/TriggerType.java +++ b/src/main/java/forge/card/trigger/TriggerType.java @@ -21,7 +21,7 @@ public enum TriggerType { Clashed(TriggerClashed.class), PayCumulativeUpkeep(TriggerPayCumulativeUpkeep.class), - Flipped(TriggerFlipped.class), + FlippedCoin(TriggerFlippedCoin.class), Attached(TriggerAttached.class), Destroyed(TriggerDestroyed.class), Devoured(TriggerDevoured.class), diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index a1d93a8078d..4e2684bfefb 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -144,4 +144,6 @@ public abstract class PlayerController { public abstract int chooseNumber(SpellAbility sa, String title, int min, int max); + public abstract String chooseFilpResult(Card source, Player flipper, String[] results, boolean call); + } diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index b359423504e..7110b8c8980 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -34,6 +34,7 @@ import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCost; import forge.game.zone.ZoneType; import forge.util.Aggregates; +import forge.util.MyRandom; /** @@ -355,4 +356,26 @@ public class PlayerControllerAi extends PlayerController { public int chooseNumber(SpellAbility sa, String title, int min, int max) { return brains.chooseNumber(sa, title, min, max); } + + /* (non-Javadoc) + * @see forge.game.player.PlayerController#chooseFilpResult(forge.Card, forge.game.player.Player, java.lang.String[], boolean) + */ + @Override + public String chooseFilpResult(Card source, Player flipper, String[] results, boolean call) { + if (call) { + // Win if possible + String result = " loses flip."; + for (String s : results) { + if (s.equals(" wins flip.")) { + result = s; + break; + } + } + return result; + } else { + // heads or tails, AI doesn't know which is better now + int i = MyRandom.getRandom().nextInt(results.length); + return results[i]; + } + } } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index feefd8723e4..80d3c0a5e60 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -610,4 +610,13 @@ public class PlayerControllerHuman extends PlayerController { } return result; } + + + /* (non-Javadoc) + * @see forge.game.player.PlayerController#chooseFilpResult(forge.game.player.Player, java.lang.String[], boolean) + */ + @Override + public String chooseFilpResult(Card source, Player flipper, String[] results, boolean call) { + return GuiChoose.one(source.getName() + " - Choose a result", results); + } } diff --git a/src/main/java/forge/gui/GuiDialog.java b/src/main/java/forge/gui/GuiDialog.java index 26cfcab084f..c9d6ed28de2 100644 --- a/src/main/java/forge/gui/GuiDialog.java +++ b/src/main/java/forge/gui/GuiDialog.java @@ -80,37 +80,4 @@ public class GuiDialog { }); } - /** - *

- * flipACoin. - *

- * - * @param caller - * a {@link forge.game.player.Player} object. - * @param source - * a {@link forge.Card} object. - * @return a boolean. - */ - public static boolean flipCoin(final Player caller, final Card source) { - String choice; - final String[] choices = { "heads", "tails" }; - - final boolean flip = MyRandom.getRandom().nextBoolean(); - if (caller.isHuman()) { - choice = GuiChoose.one(source.getName() + " - Call coin flip", choices); - } else { - choice = choices[MyRandom.getRandom().nextInt(2)]; - } - - final boolean winFlip = flip == choice.equals(choices[0]); - final String winMsg = winFlip ? " wins flip." : " loses flip."; - - // Play the Flip A Coin sound - caller.getGame().fireEvent(new GameEventFlipCoin()); - - message(source.getName() + " - " + caller + winMsg, source.getName()); - - return winFlip; - } - }