diff --git a/.gitattributes b/.gitattributes index ccdf1f7247d..c6580cb3d8f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11077,6 +11077,7 @@ res/cardsfolder/t/temporal_manipulation.txt svneol=native#text/plain res/cardsfolder/t/temporal_mastery.txt -text res/cardsfolder/t/temporal_spring.txt svneol=native#text/plain res/cardsfolder/t/temporary_insanity.txt svneol=native#text/plain +res/cardsfolder/t/temporary_truce.txt -text res/cardsfolder/t/tempting_licid.txt -text res/cardsfolder/t/tempting_wurm.txt svneol=native#text/plain res/cardsfolder/t/tendo_ice_bridge.txt svneol=native#text/plain diff --git a/res/cardsfolder/t/temporary_truce.txt b/res/cardsfolder/t/temporary_truce.txt new file mode 100644 index 00000000000..c23efe4a495 --- /dev/null +++ b/res/cardsfolder/t/temporary_truce.txt @@ -0,0 +1,12 @@ +Name:Temporary Truce +ManaCost:1 W +Types:Sorcery +A:SP$ RepeatEach | Cost$ 1 W | RepeatPlayers$ Player | RepeatSubAbility$ DBDraw | SpellDescription$ Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life. +SVar:DBDraw:DB$ Draw | Defined$ Player.IsRemembered | Upto$ True | NumCards$ 2 | RememberDrawn$ True | SubAbility$ DBGainLife | AILogic$ GainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | References$ X,Y | Defined$ Player.IsRemembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +# Player is remembered here +SVar:Y:Count$RememberedSize/NMinus.3 +SVar:X:SVar$Y/Twice +SVar:Picture:http://www.wizards.com/global/images/magic/general/temporary_truce.jpg +Oracle:Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life. diff --git a/src/main/java/forge/card/ability/ai/DrawAi.java b/src/main/java/forge/card/ability/ai/DrawAi.java index c8693c5e800..5cb90206545 100644 --- a/src/main/java/forge/card/ability/ai/DrawAi.java +++ b/src/main/java/forge/card/ability/ai/DrawAi.java @@ -216,6 +216,7 @@ public class DrawAi extends SpellAbilityAi { } else { // Don't draw too many cards and then risk discarding cards // at EOT + // TODO: "NextUpkeep" is deprecated if (!(sa.hasParam("NextUpkeep") || (sa instanceof AbilitySub)) && !mandatory) { return false; } diff --git a/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java b/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java index d72690b5b20..a34f74e2452 100644 --- a/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java @@ -11,7 +11,6 @@ import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; import forge.game.player.Player; -import forge.gui.GuiChoose; import forge.gui.GuiDialog; public class ChooseNumberEffect extends SpellAbilityEffect { @@ -43,44 +42,22 @@ public class ChooseNumberEffect extends SpellAbilityEffect { final String sMax = sa.getParamOrDefault("Max", "99"); final int max = StringUtils.isNumeric(sMax) ? Integer.parseInt(sMax) : CardFactoryUtil.xCount(card, card.getSVar(sMax)); - final String[] choices = new String[max + 1]; - if (!random) { - // initialize the array - for (int i = min; i <= max; i++) { - choices[i] = Integer.toString(i); - } - } - final List tgtPlayers = getTargetPlayers(sa); final Target tgt = sa.getTarget(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { - if (p.isHuman()) { - int chosen; - if (random) { - final Random randomGen = new Random(); - chosen = randomGen.nextInt(max - min) + min; - final String message = "Randomly chosen number: " + chosen; - GuiDialog.message(message, card.toString()); - } else if (sa.hasParam("ListTitle")) { - final Object o = GuiChoose.one(sa.getParam("ListTitle"), choices); - if (null == o) { - return; - } - chosen = Integer.parseInt((String) o); - } else { - final Object o = GuiChoose.one("Choose a number", choices); - if (null == o) { - return; - } - chosen = Integer.parseInt((String) o); - } - card.setChosenNumber(chosen); - + int chosen; + if (random) { + final Random randomGen = new Random(); + chosen = randomGen.nextInt(max - min) + min; + final String message = "Randomly chosen number: " + chosen; + GuiDialog.message(message, card.toString()); } else { - // TODO - not implemented + String title = sa.hasParam("ListTitle") ? sa.getParam("ListTitle") : "Choose a number"; + chosen = p.getController().chooseNumber(sa, title, min, max); } + card.setChosenNumber(chosen); } } } diff --git a/src/main/java/forge/card/ability/effects/DrawEffect.java b/src/main/java/forge/card/ability/effects/DrawEffect.java index bf583a0d3d3..fbdd6f4a180 100644 --- a/src/main/java/forge/card/ability/effects/DrawEffect.java +++ b/src/main/java/forge/card/ability/effects/DrawEffect.java @@ -37,12 +37,13 @@ public class DrawEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { final Card source = sa.getSourceCard(); - int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumCards"), sa) : 1; + final int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumCards"), sa) : 1; final Target tgt = sa.getTarget(); final boolean optional = sa.hasParam("OptionalDecider"); + final boolean upto = sa.hasParam("Upto"); for (final Player p : getDefinedPlayersBeforeTargetOnes(sa)) { @@ -50,8 +51,12 @@ public class DrawEffect extends SpellAbilityEffect { if (optional && !p.getController().confirmAction(sa, null, "Do you want to draw " + Lang.nounWithAmount(numCards, " card") + "?")) continue; - //TODO: remove this deprecation exception - final List drawn = p.drawCards(numCards); + int actualNum = numCards; + if (upto) { + actualNum = p.getController().chooseNumber(sa, "Choose a number", 0, numCards); + } + + final List drawn = p.drawCards(actualNum); if (sa.hasParam("Reveal")) { p.getGame().getAction().reveal(drawn, p); } diff --git a/src/main/java/forge/game/ai/AiController.java b/src/main/java/forge/game/ai/AiController.java index 93ba058bef0..1434fff9b0f 100644 --- a/src/main/java/forge/game/ai/AiController.java +++ b/src/main/java/forge/game/ai/AiController.java @@ -855,5 +855,15 @@ public class AiController { return result; } + + public int chooseNumber(SpellAbility sa, String title, int min, int max) { + //TODO: AILogic + if ("GainLife".equals(sa.getParam("AILogic"))) { + if (player.getLife() < 5 || player.getCardsIn(ZoneType.Hand).size() >= player.getMaxHandSize()) { + return min; + } + } + return max; + } } diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 5f711e100cb..acb58126e56 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -142,4 +142,6 @@ public abstract class PlayerController { public abstract List chooseCardsToDiscardToMaximumHandSize(int numDiscard); public abstract boolean payManaOptional(Card card, Cost cost, String prompt, ManaPaymentPurpose purpose); + public abstract int chooseNumber(SpellAbility sa, String title, int min, int max); + } diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index 0f15e3fc222..4a35b54da85 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -350,4 +350,9 @@ public class PlayerControllerAi extends PlayerController { // AI would play everything. But limits to one copy of (Leyline of Singularity) and (Gemstone Caverns) return brains.chooseSaToActivateFromOpeningHand(usableFromOpeningHand); } + + @Override + public int chooseNumber(SpellAbility sa, String title, int min, int max) { + return brains.chooseNumber(sa, title, min, max); + } } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 124416c8933..e6e11983b25 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -269,6 +269,15 @@ public class PlayerControllerHuman extends PlayerController { return options.get(0); } + @Override + public int chooseNumber(SpellAbility sa, String title, int min, int max) { + final String[] choices = new String[max + 1]; + for (int i = min; i <= max; i++) { + choices[i] = Integer.toString(i); + } + return Integer.parseInt(GuiChoose.one(title, choices)); + } + @Override public Player chooseSinglePlayerForEffect(List options, SpellAbility sa, String title) { // Human is supposed to read the message and understand from it what to choose