From 800a9b6854afb2a3b3aa5317f4095a4882e955b4 Mon Sep 17 00:00:00 2001 From: swordshine Date: Wed, 8 Jan 2014 03:54:03 +0000 Subject: [PATCH] - Added Storage Matrix --- .gitattributes | 1 + .../res/cardsfolder/s/storage_matrix.txt | 9 +++ .../src/main/java/forge/ai/ComputerUtil.java | 17 +++++ .../src/main/java/forge/game/phase/Untap.java | 65 ++++++++++++------- .../gui/player/PlayerControllerHuman.java | 4 +- 5 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 forge-gui/res/cardsfolder/s/storage_matrix.txt diff --git a/.gitattributes b/.gitattributes index 3fb112aae90..2255ade4937 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11269,6 +11269,7 @@ forge-gui/res/cardsfolder/s/stony_silence.txt -text forge-gui/res/cardsfolder/s/stonybrook_angler.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/stonybrook_banneret.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/stonybrook_schoolmaster.txt svneol=native#text/plain +forge-gui/res/cardsfolder/s/storage_matrix.txt -text forge-gui/res/cardsfolder/s/storm_cauldron.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/storm_crow.txt svneol=native#text/plain forge-gui/res/cardsfolder/s/storm_elemental.txt svneol=native#text/plain diff --git a/forge-gui/res/cardsfolder/s/storage_matrix.txt b/forge-gui/res/cardsfolder/s/storage_matrix.txt new file mode 100644 index 00000000000..477ece33e0a --- /dev/null +++ b/forge-gui/res/cardsfolder/s/storage_matrix.txt @@ -0,0 +1,9 @@ +Name:Storage Matrix +ManaCost:3 +Types:Artifact +S:Mode$ Continuous | Affected$ Player | AddKeyword$ OnlyUntapChosen:Artifact,Creature,Land | CheckSVar$ X | SVarCompare$ EQ1 | Description$ As long as CARDNAME is untapped, each player chooses artifact, creature, or land during his or her untap step. That player can untap only permanents of the chosen type this step. +SVar:X:Count$Valid Card.Self+untapped +SVar:RemAIDeck:True +SVar:RemRandomDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/storage_matrix.jpg +Oracle:As long as Storage Matrix is untapped, each player chooses artifact, creature, or land during his or her untap step. That player can untap only permanents of the chosen type this step. diff --git a/forge-gui/src/main/java/forge/ai/ComputerUtil.java b/forge-gui/src/main/java/forge/ai/ComputerUtil.java index 006e9506f4d..56b6c031944 100644 --- a/forge-gui/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-gui/src/main/java/forge/ai/ComputerUtil.java @@ -31,6 +31,7 @@ import com.google.common.collect.Iterables; import forge.card.CardType; import forge.card.MagicColor; +import forge.card.CardType.Constant; import forge.error.BugReporter; import forge.game.Game; import forge.game.GameObject; @@ -1628,6 +1629,22 @@ public class ComputerUtil { // based on whether it needs a creature or land, // otherwise, lib search for most common type left // then, reveal chosenType to Human + if (game.getPhaseHandler().is(PhaseType.UNTAP) && logic == null) { // Storage Matrix + double amount = 0; + for (String type : Constant.CARD_TYPES) { + if (!invalidTypes.contains(type)) { + List list = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(type), Presets.TAPPED); + double i = type.equals("Creature") ? list.size() * 1.5 : list.size(); + if (i > amount) { + amount = i; + chosen = type; + } + } + } + } + if (StringUtils.isEmpty(chosen)) { + chosen = "Creature"; + } } else if (kindOfType.equals("Creature")) { Player opp = ai.getOpponent(); if (logic != null ) { diff --git a/forge-gui/src/main/java/forge/game/phase/Untap.java b/forge-gui/src/main/java/forge/game/phase/Untap.java index 545c240e990..8699109b1e1 100644 --- a/forge-gui/src/main/java/forge/game/phase/Untap.java +++ b/forge-gui/src/main/java/forge/game/phase/Untap.java @@ -18,6 +18,7 @@ package forge.game.phase; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -26,6 +27,7 @@ import java.util.Map.Entry; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import forge.card.CardType.Constant; import forge.game.Game; import forge.game.GameEntity; import forge.game.ability.ApiType; @@ -132,8 +134,10 @@ public class Untap extends Phase { for (final Card c : bounceList) { game.getAction().moveToHand(c); } + list.removeAll(bounceList); final Map restrictUntap = new HashMap(); + boolean hasChosen = false; for (String kw : player.getKeywords()) { if (kw.startsWith("UntapAdjust")) { String[] parse = kw.split(":"); @@ -142,7 +146,16 @@ public class Untap extends Phase { restrictUntap.put(parse[1], Integer.parseInt(parse[2])); } } + if (kw.startsWith("OnlyUntapChosen") && !hasChosen) { + List validTypes = Arrays.asList(kw.split(":")[1].split(",")); + List invalidTypes = new ArrayList(Constant.CARD_TYPES); + invalidTypes.removeAll(validTypes); + final String chosen = player.getController().chooseSomeType("Card", new SpellAbility.EmptySa(ApiType.ChooseType, null, player), validTypes, invalidTypes); + list = CardLists.getType(list,chosen); + hasChosen = true; + } } + final List untapList = new ArrayList(list); final String[] restrict = restrictUntap.keySet().toArray(new String[restrictUntap.keySet().size()]); list = CardLists.filter(list, new Predicate() { @Override @@ -158,27 +171,7 @@ public class Untap extends Phase { }); for (final Card c : list) { - if (c.hasKeyword("You may choose not to untap CARDNAME during your untap step.")) { - if (c.isTapped()) { - String prompt = "Untap " + c.getName() + "?"; - boolean defaultChoice = true; - if (c.getGainControlTargets().size() > 0) { - final List targets = c.getGainControlTargets(); - prompt += "\r\n" + c + " is controlling: "; - for (final Card target : targets) { - prompt += target; - if (target.isInPlay()) { - defaultChoice = false; - } - } - } - boolean untap = c.getController().getController().chooseBinary(new SpellAbility.EmptySa(c, c.getController()), prompt, BinaryChoiceType.UntapOrLeaveTapped, defaultChoice); - if (untap) - c.untap(); - } - } else { - c.untap(); - } + optionalUntap(c); } // other players untapping during your untap phase @@ -193,8 +186,7 @@ public class Untap extends Phase { // end other players untapping during your untap phase List restrictUntapped = new ArrayList(); - // TODO : update for Storage Matrix - List cardList = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), tappedCanUntap); + List cardList = CardLists.filter(untapList, tappedCanUntap); cardList = CardLists.getValidCards(cardList, restrict, player, null); while (!cardList.isEmpty()) { @@ -218,7 +210,7 @@ public class Untap extends Phase { } } for (Card c : restrictUntapped) { - c.untap(); + optionalUntap(c); } // Remove temporary keywords @@ -234,6 +226,31 @@ public class Untap extends Phase { game.getStack().chooseOrderOfSimultaneousStackEntryAll(); } // end doUntap + private static void optionalUntap(final Card c) { + if (c.hasKeyword("You may choose not to untap CARDNAME during your untap step.")) { + if (c.isTapped()) { + String prompt = "Untap " + c.getName() + "?"; + boolean defaultChoice = true; + if (c.getGainControlTargets().size() > 0) { + final List targets = c.getGainControlTargets(); + prompt += "\r\n" + c + " is controlling: "; + for (final Card target : targets) { + prompt += target; + if (target.isInPlay()) { + defaultChoice = false; + } + } + } + boolean untap = c.getController().getController().chooseBinary(new SpellAbility.EmptySa(c, c.getController()), prompt, BinaryChoiceType.UntapOrLeaveTapped, defaultChoice); + if (untap) { + c.untap(); + } + } + } else { + c.untap(); + } + } + private static void doPhasing(final Player turn) { // Needs to include phased out cards final List list = CardLists.filter(turn.getCardsIncludePhasingIn(ZoneType.Battlefield), new Predicate() { diff --git a/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java index 314d9afa8cc..f3c2ad22683 100644 --- a/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java @@ -826,12 +826,12 @@ public class PlayerControllerHuman extends PlayerController { @Override public void notifyOfValue(SpellAbility sa, GameObject realtedTarget, String value) { String message = formatNotificationMessage(sa, realtedTarget, value); - GuiDialog.message(message, sa.getSourceCard().getName()); + GuiDialog.message(message, sa.getSourceCard() == null ? "" : sa.getSourceCard().getName()); } // These are not much related to PlayerController private String formatNotificationMessage(SpellAbility sa, GameObject target, String value) { - if (sa.getApi() == null) { + if (sa.getApi() == null || sa.getSourceCard() == null) { return ("Result: " + value); } switch(sa.getApi()) {