diff --git a/.gitattributes b/.gitattributes index 05756d092d8..0c84bf4a2aa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6326,6 +6326,7 @@ res/cardsfolder/m/man_o_war.txt svneol=native#text/plain res/cardsfolder/m/mana_bloom.txt -text res/cardsfolder/m/mana_breach.txt svneol=native#text/plain res/cardsfolder/m/mana_chains.txt -text +res/cardsfolder/m/mana_clash.txt -text res/cardsfolder/m/mana_crypt.txt svneol=native#text/plain res/cardsfolder/m/mana_cylix.txt svneol=native#text/plain res/cardsfolder/m/mana_drain.txt svneol=native#text/plain diff --git a/res/cardsfolder/m/mana_clash.txt b/res/cardsfolder/m/mana_clash.txt new file mode 100644 index 00000000000..a887d5ba3b9 --- /dev/null +++ b/res/cardsfolder/m/mana_clash.txt @@ -0,0 +1,21 @@ +Name:Mana Clash +ManaCost:R +Types:Sorcery +Text:no text +A:SP$ Repeat | Cost$ R | ValidTgts$ Opponent | RepeatCheckSVar$ RepeatCheck | RepeatSVarCompare$ GT0 | RepeatSubAbility$ ResetCheck | StackDescription$ SpellDescription | SpellDescription$ You and target opponent each flip a coin. CARDNAME deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip. +SVar:ResetCheck:DB$ StoreSVar | SVar$ RepeatCheck | Type$ Number | Expression$ 0 | SubAbility$ RepeatClash +SVar:RepeatClash:DB$ RepeatEach | RepeatPlayers$ TargetedAndYou | RepeatSubAbility$ FlipClash | SubAbility$ ClashDamage +SVar:FlipClash:DB$ FlipACoin | Flipper$ Remembered | NoCall$ True | TailsSubAbility$ ClashTails | RememberResult$ True +SVar:ClashTails:DB$ StoreSVar | SVar$ RepeatCheck | Type$ CountSVar | Expression$ RepeatCheck/Plus.1 +SVar:ClashDamage:DB$ DamageAll | ValidPlayers$ FlippedTails | NumDmg$ 1 | SubAbility$ ResetFlips +SVar:ResetFlips:DB$ Cleanup | ClearCoinFlips$ True +SVar:RepeatCheck:Number$ 0 +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/mana_clash.jpg +Oracle:You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip. +SetInfo:8ED Rare +SetInfo:7ED Rare +SetInfo:DRK Rare +SetInfo:9ED Rare +SetInfo:5ED Rare +SetInfo:4ED Rare \ No newline at end of file diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 164696aa6ba..8bb91d18158 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -125,6 +125,7 @@ public class Card extends GameEntity implements Comparable { private final ArrayList encodedCards = new ArrayList(); private Card championedCard = null; private final List devouredCards = new ArrayList(); + private Map flipResult = new TreeMap(); private Map receivedDamageFromThisTurn = new TreeMap(); private Map dealtDamageToThisTurn = new TreeMap(); @@ -759,6 +760,39 @@ public class Card extends GameEntity implements Comparable { this.encodedCards.clear(); } + /** + *

+ * addFlipResult. + *

+ * + * @param flipper The Player who flipped the coin. + * @param result The result of the coin flip as a String. + */ + public final void addFlipResult(final Player flipper, final String result) { + this.flipResult.put(flipper, result); + } + + /** + *

+ * getFlipResult. + *

+ * + * @param flipper The Player who flipped the coin. + * @return a String result - Heads or Tails. + */ + public final String getFlipResult(final Player flipper) { + return this.flipResult.get(flipper); + } + + /** + *

+ * clearFlipResult. + *

+ */ + public final void clearFlipResult() { + this.flipResult.clear(); + } + /** *

* Setter for the field championedCard. diff --git a/src/main/java/forge/card/ability/AbilityUtils.java b/src/main/java/forge/card/ability/AbilityUtils.java index 72dc909e1af..85ffcff32c3 100644 --- a/src/main/java/forge/card/ability/AbilityUtils.java +++ b/src/main/java/forge/card/ability/AbilityUtils.java @@ -705,6 +705,12 @@ public class AbilityUtils { players.add(p); } } + } else if (defined.equals("TargetedAndYou")) { + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + players.addAll(saTargeting.getTarget().getTargetPlayers()); + players.add(sa.getActivatingPlayer()); + } } else if (defined.equals("Remembered")) { for (final Object rem : card.getRemembered()) { if (rem instanceof Player) { @@ -861,6 +867,14 @@ public class AbilityUtils { if (!players.contains(p)) { players.add(p); } + } else if (defined.startsWith("Flipped")) { + for (Player p : Singletons.getModel().getGame().getPlayers()) { + if (null != sa.getSourceCard().getFlipResult(p)) { + if (sa.getSourceCard().getFlipResult(p).equals(defined.substring(7))) { + players.add(p); + } + } + } } else if (defined.equals("You")) { players.add(sa.getActivatingPlayer()); } else if (defined.equals("Each")) { diff --git a/src/main/java/forge/card/ability/effects/CleanUpEffect.java b/src/main/java/forge/card/ability/effects/CleanUpEffect.java index e53bb72624d..52248b3f296 100644 --- a/src/main/java/forge/card/ability/effects/CleanUpEffect.java +++ b/src/main/java/forge/card/ability/effects/CleanUpEffect.java @@ -37,6 +37,9 @@ public class CleanUpEffect extends SpellAbilityEffect { if (sa.hasParam("ClearTriggered")) { Singletons.getModel().getGame().getTriggerHandler().clearDelayedTrigger(source); } + if (sa.hasParam("ClearCoinFlips")) { + source.clearFlipResult(); + } } } diff --git a/src/main/java/forge/card/ability/effects/FlipCoinEffect.java b/src/main/java/forge/card/ability/effects/FlipCoinEffect.java index 17ba22029df..6f19338beea 100644 --- a/src/main/java/forge/card/ability/effects/FlipCoinEffect.java +++ b/src/main/java/forge/card/ability/effects/FlipCoinEffect.java @@ -37,7 +37,12 @@ public class FlipCoinEffect extends SpellAbilityEffect { final Card host = sa.getSourceCard(); final Player player = host.getController(); - final List caller = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Caller"), sa); + final List playersToFlip = AbilityUtils.getDefinedPlayers(host, sa.getParam("Flipper"), sa); + if (playersToFlip.isEmpty()) { + playersToFlip.add(sa.getActivatingPlayer()); + } + + final List caller = AbilityUtils.getDefinedPlayers(host, sa.getParam("Caller"), sa); if (caller.isEmpty()) { caller.add(player); } @@ -45,62 +50,64 @@ public class FlipCoinEffect extends SpellAbilityEffect { final boolean noCall = sa.hasParam("NoCall"); boolean victory = false; if (!noCall) { - victory = GuiDialog.flipCoin(caller.get(0), sa.getSourceCard()); + victory = GuiDialog.flipCoin(caller.get(0), host); } // Run triggers // HashMap runParams = new HashMap(); // runParams.put("Player", player); - if (sa.getParam("RememberAll") != null) { - host.addRemembered(host); - } + final boolean rememberResult = sa.hasParam("RememberResult"); - if (noCall) { - final boolean resultIsHeads = FlipCoinEffect.flipCoin(sa.getSourceCard()); + for (final Player flipper : playersToFlip) { + if (noCall) { + final boolean resultIsHeads = FlipCoinEffect.flipCoinNoCall(sa.getSourceCard(), flipper); + if (rememberResult) { + host.addFlipResult(flipper, resultIsHeads ? "Heads" : "Tails"); + } - System.out.println("Flipped coin result:" + (resultIsHeads ? " Heads" : " Tails")); - if (resultIsHeads) { - if (sa.hasParam("HeadsSubAbility")) { - final SpellAbility heads = AbilityFactory.getAbility(host.getSVar(sa.getParam("HeadsSubAbility")), host); - heads.setActivatingPlayer(player); - ((AbilitySub) heads).setParent(sa); + if (resultIsHeads) { + if (sa.hasParam("HeadsSubAbility")) { + final SpellAbility heads = AbilityFactory.getAbility(host.getSVar(sa.getParam("HeadsSubAbility")), host); + heads.setActivatingPlayer(player); + ((AbilitySub) heads).setParent(sa); - AbilityUtils.resolve(heads, false); + AbilityUtils.resolve(heads, false); + } + } else { + if (sa.hasParam("TailsSubAbility")) { + final SpellAbility tails = AbilityFactory.getAbility(host.getSVar(sa.getParam("TailsSubAbility")), host); + tails.setActivatingPlayer(player); + ((AbilitySub) tails).setParent(sa); + + AbilityUtils.resolve(tails, false); + } } } else { - if (sa.hasParam("TailsSubAbility")) { - final SpellAbility tails = AbilityFactory.getAbility(host.getSVar(sa.getParam("TailsSubAbility")), host); - tails.setActivatingPlayer(player); - ((AbilitySub) tails).setParent(sa); + if (victory) { + if (sa.getParam("RememberWinner") != null) { + host.addRemembered(host); + } + if (sa.hasParam("WinSubAbility")) { + final SpellAbility win = AbilityFactory.getAbility(host.getSVar(sa.getParam("WinSubAbility")), host); + win.setActivatingPlayer(player); + ((AbilitySub) win).setParent(sa); - AbilityUtils.resolve(tails, false); - } - } - } else { - if (victory) { - if (sa.getParam("RememberWinner") != null) { - host.addRemembered(host); - } - if (sa.hasParam("WinSubAbility")) { - final SpellAbility win = AbilityFactory.getAbility(host.getSVar(sa.getParam("WinSubAbility")), host); - win.setActivatingPlayer(player); - ((AbilitySub) win).setParent(sa); + AbilityUtils.resolve(win, false); + } + // runParams.put("Won","True"); + } else { + if (sa.getParam("RememberLoser") != null) { + host.addRemembered(host); + } + if (sa.hasParam("LoseSubAbility")) { + final SpellAbility lose = AbilityFactory.getAbility(host.getSVar(sa.getParam("LoseSubAbility")), host); + lose.setActivatingPlayer(player); + ((AbilitySub) lose).setParent(sa); - AbilityUtils.resolve(win, false); + AbilityUtils.resolve(lose, false); + } + // runParams.put("Won","False"); } - // runParams.put("Won","True"); - } else { - if (sa.getParam("RememberLoser") != null) { - host.addRemembered(host); - } - if (sa.hasParam("LoseSubAbility")) { - final SpellAbility lose = AbilityFactory.getAbility(host.getSVar(sa.getParam("LoseSubAbility")), host); - lose.setActivatingPlayer(player); - ((AbilitySub) lose).setParent(sa); - - AbilityUtils.resolve(lose, false); - } - // runParams.put("Won","False"); } } @@ -109,25 +116,26 @@ public class FlipCoinEffect extends SpellAbilityEffect { /** *

- * flipACoin without call. + * flipCoinNoCall Flip a coin without any call. *

* - * @param source - * a {@link forge.Card} object. + * @param source the source card. + * @param flipper the player flipping the coin. * @return a boolean. */ - private static boolean flipCoin(final Card source) { + public static boolean flipCoinNoCall(final Card source, final Player flipper) { final boolean resultIsHeads = MyRandom.getRandom().nextBoolean(); - + Singletons.getModel().getGame().getEvents().post(new FlipCoinEvent()); final StringBuilder msgTitle = new StringBuilder(); msgTitle.append(source); msgTitle.append(" Flip result:"); final StringBuilder result = new StringBuilder(); - result.append("Flip comes up"); + result.append(flipper.getName()); + result.append("'s flip comes up"); result.append(resultIsHeads ? " heads." : " tails."); JOptionPane.showMessageDialog(null, result, msgTitle.toString(), JOptionPane.PLAIN_MESSAGE); - + return resultIsHeads; }