diff --git a/.gitattributes b/.gitattributes index 1cc57be1426..1a505dbdeb8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -47,6 +47,7 @@ forge-ai/src/main/java/forge/ai/ability/ChooseCardAi.java -text forge-ai/src/main/java/forge/ai/ability/ChooseCardNameAi.java -text forge-ai/src/main/java/forge/ai/ability/ChooseColorAi.java -text forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java -text +forge-ai/src/main/java/forge/ai/ability/ChooseNumberAi.java -text forge-ai/src/main/java/forge/ai/ability/ChoosePlayerAi.java -text forge-ai/src/main/java/forge/ai/ability/ChooseSourceAi.java -text forge-ai/src/main/java/forge/ai/ability/ChooseTypeAi.java -text @@ -2507,6 +2508,7 @@ forge-gui/res/cardsfolder/c/cho_arrim_bruiser.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/cho_arrim_legate.txt -text forge-gui/res/cardsfolder/c/cho_manno_revolutionary.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/cho_mannos_blessing.txt -text +forge-gui/res/cardsfolder/c/choice_of_damnations.txt -text forge-gui/res/cardsfolder/c/choke.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/choking_fumes.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/choking_sands.txt svneol=native#text/plain diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index ecdd504f732..f7f2507a3d8 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1276,8 +1276,7 @@ public class AiController { } public int chooseNumber(SpellAbility sa, String title, int min, int max) { - //TODO: AILogic - final String logic = sa.getParam("AILogic"); + final String logic = sa.getParam("AILogic"); if ("GainLife".equals(logic)) { if (player.getLife() < 5 || player.getCardsIn(ZoneType.Hand).size() >= player.getMaxHandSize()) { return min; @@ -1287,12 +1286,17 @@ public class AiController { return min; } else if ("DigACard".equals(logic)) { - int random = MyRandom.getRandom().nextInt(Math.min(4, max)) + 1; - if (player.getLife() < random + 5) { - return min; - } else { - return random; - } + int random = MyRandom.getRandom().nextInt(Math.min(4, max)) + 1; + if (player.getLife() < random + 5) { + return min; + } else { + return random; + } + } + else if ("Damnation".equals(logic)) { + int chosenMax = player.getLife() - 1; + int cardsInPlay = player.getCardsIn(ZoneType.Battlefield).size(); + return Math.min(chosenMax, cardsInPlay); } return max; } diff --git a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java index 5818d3ee431..8976caaed69 100644 --- a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java @@ -30,7 +30,7 @@ public enum SpellApiToAi { apiToClass.put(ApiType.Charm, CharmAi.class); apiToClass.put(ApiType.ChooseCard, ChooseCardAi.class); apiToClass.put(ApiType.ChooseColor, ChooseColorAi.class); - apiToClass.put(ApiType.ChooseNumber, CannotPlayAi.class); + apiToClass.put(ApiType.ChooseNumber, ChooseNumberAi.class); apiToClass.put(ApiType.ChoosePlayer, ChoosePlayerAi.class); apiToClass.put(ApiType.ChooseSource, ChooseSourceAi.class); apiToClass.put(ApiType.ChooseType, ChooseTypeAi.class); diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseNumberAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseNumberAi.java new file mode 100644 index 00000000000..0e3ee3ec97e --- /dev/null +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseNumberAi.java @@ -0,0 +1,34 @@ +package forge.ai.ability; + +import forge.ai.SpellAbilityAi; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; +import forge.game.spellability.TargetRestrictions; +import forge.util.MyRandom; + +public class ChooseNumberAi extends SpellAbilityAi { + + @Override + protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { + if (!sa.hasParam("AILogic")) { + return false; + } + TargetRestrictions tgt = sa.getTargetRestrictions(); + if (tgt != null) { + sa.resetTargets(); + if (sa.canTarget(aiPlayer.getOpponent())) { + sa.getTargets().add(aiPlayer.getOpponent()); + } else { + return false; + } + } + boolean chance = MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); + return chance; + } + + @Override + protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { + return mandatory || canPlayAI(ai, sa); + } + +} diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java index f969f1e207b..89a99e02b86 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java @@ -56,6 +56,9 @@ public class ChooseNumberEffect extends SpellAbilityEffect { // don't notify here, because most scripts I've seen don't store that number in a long term } card.setChosenNumber(chosen); + if (sa.hasParam("Notify")) { + p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + chosen, p); + } } } } diff --git a/forge-gui/res/cardsfolder/c/choice_of_damnations.txt b/forge-gui/res/cardsfolder/c/choice_of_damnations.txt new file mode 100644 index 00000000000..a4baefd2a98 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/choice_of_damnations.txt @@ -0,0 +1,14 @@ +Name:Choice of Damnations +ManaCost:5 B +Types:Sorcery Arcane +A:SP$ ChooseNumber | Cost$ 5 B | ValidTgts$ Opponent | AILogic$ Damnation | Notify$ True | SubAbility$ DBChoice | SpellDescription$ Target opponent chooses a number. You may have that player lose that much life. If you don't, that player sacrifices all but that many permanents. +SVar:DBChoice:DB$ GenericChoice | Choices$ DBLoseLife,DBSac +SVar:DBLoseLife:DB$ LoseLife | Defined$ ParentTarget | LifeAmount$ X | References$ X | SpellDescription$ That player lose that much life. +SVar:DBSac:DB$ Sacrifice | Defined$ ParentTarget | SacValid$ Permanent | Amount$ Y | References$ X,Y,Z,W | SpellDescription$ That player sacrifices all but that many permanents. +SVar:X:Count$ChosenNumber +SVar:Y:SVar$W/LimitMin.0 +SVar:W:SVar$Z/Minus.X +SVar:Z:Count$Valid Permanent.TargetedPlayerCtrl +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/choice_of_damnations.jpg +Oracle:Target opponent chooses a number. You may have that player lose that much life. If you don't, that player sacrifices all but that many permanents.