diff --git a/forge-core/src/main/java/forge/card/CardFace.java b/forge-core/src/main/java/forge/card/CardFace.java index 4e3545ee620..6712b629d47 100644 --- a/forge-core/src/main/java/forge/card/CardFace.java +++ b/forge-core/src/main/java/forge/card/CardFace.java @@ -81,13 +81,13 @@ final class CardFace implements ICardFace { throw new RuntimeException("Card name is empty"); } // Here come setters to allow parser supply values - public void setType(CardType type0) { this.type = type0; } - public void setManaCost(ManaCost manaCost0) { this.manaCost = manaCost0; } - public void setColor(ColorSet color0) { this.color = color0; } - public void setOracleText(String text) { this.oracleText = text; } - public void setInitialLoyalty(int value) { this.initialLoyalty = value; } + void setType(CardType type0) { this.type = type0; } + void setManaCost(ManaCost manaCost0) { this.manaCost = manaCost0; } + void setColor(ColorSet color0) { this.color = color0; } + void setOracleText(String text) { this.oracleText = text; } + void setInitialLoyalty(int value) { this.initialLoyalty = value; } - public void setPtText(String value) { + void setPtText(String value) { final int slashPos = value.indexOf('/'); if (slashPos == -1) { throw new RuntimeException(String.format("Creature '%s' has bad p/t stats", this.getName())); @@ -99,16 +99,16 @@ final class CardFace implements ICardFace { } // Raw fields used for Card creation - public void setNonAbilityText(String value) { this.nonAbilityText = value; } - public void addKeyword(String value) { if (null == this.keywords) { this.keywords = new ArrayList(); } this.keywords.add(value); } - public void addAbility(String value) { if (null == this.abilities) { this.abilities = new ArrayList(); } this.abilities.add(value);} - public void addTrigger(String value) { if (null == this.triggers) { this.triggers = new ArrayList(); } this.triggers.add(value);} - public void addStaticAbility(String value) { if (null == this.staticAbilities) { this.staticAbilities = new ArrayList(); } this.staticAbilities.add(value);} - public void addReplacementEffect(String value) { if (null == this.replacements) { this.replacements = new ArrayList(); } this.replacements.add(value);} - public void addSVar(String key, String value) { if (null == this.variables) { this.variables = new TreeMap(String.CASE_INSENSITIVE_ORDER); } this.variables.put(key, value); } + void setNonAbilityText(String value) { this.nonAbilityText = value; } + void addKeyword(String value) { if (null == this.keywords) { this.keywords = new ArrayList(); } this.keywords.add(value); } + void addAbility(String value) { if (null == this.abilities) { this.abilities = new ArrayList(); } this.abilities.add(value);} + void addTrigger(String value) { if (null == this.triggers) { this.triggers = new ArrayList(); } this.triggers.add(value);} + void addStaticAbility(String value) { if (null == this.staticAbilities) { this.staticAbilities = new ArrayList(); } this.staticAbilities.add(value);} + void addReplacementEffect(String value) { if (null == this.replacements) { this.replacements = new ArrayList(); } this.replacements.add(value);} + void addSVar(String key, String value) { if (null == this.variables) { this.variables = new TreeMap(String.CASE_INSENSITIVE_ORDER); } this.variables.put(key, value); } - public void assignMissingFields() { // Most scripts do not specify color explicitly + void assignMissingFields() { // Most scripts do not specify color explicitly if ( null == oracleText ) { System.err.println(name + " has no Oracle text."); oracleText = ""; } if ( manaCost == null && color == null ) System.err.println(name + " has neither ManaCost nor Color"); if ( color == null ) color = ColorSet.fromManaCost(manaCost); diff --git a/forge-gui/src/main/java/forge/ai/ComputerUtilCard.java b/forge-gui/src/main/java/forge/ai/ComputerUtilCard.java index cc7827d323e..91fa2e7a086 100644 --- a/forge-gui/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-gui/src/main/java/forge/ai/ComputerUtilCard.java @@ -23,6 +23,7 @@ import forge.card.MagicColor; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; +import forge.game.Game; import forge.game.card.Card; import forge.game.card.CardFactoryUtil; import forge.game.card.CardLists; @@ -31,6 +32,7 @@ import forge.game.card.CardUtil; import forge.game.combat.Combat; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; @@ -826,5 +828,64 @@ public class ComputerUtilCard { return true; } }; + public static List chooseColor(SpellAbility sa, int min, int max, List colorChoices) { + List chosen = new ArrayList(); + Player ai = sa.getActivatingPlayer(); + final Game game = ai.getGame(); + Player opp = ai.getOpponent(); + if (sa.hasParam("AILogic")) { + final String logic = sa.getParam("AILogic"); + if (logic.equals("MostProminentInHumanDeck")) { + chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), opp), colorChoices)); + } else if (logic.equals("MostProminentInComputerDeck")) { + chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), ai), colorChoices)); + } else if (logic.equals("MostProminentDualInComputerDeck")) { + List prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai)); + chosen.add(prominence.get(0)); + chosen.add(prominence.get(1)); + } + else if (logic.equals("MostProminentInGame")) { + chosen.add(ComputerUtilCard.getMostProminentColor(game.getCardsInGame(), colorChoices)); + } + else if (logic.equals("MostProminentHumanCreatures")) { + List list = opp.getCreaturesInPlay(); + if (list.isEmpty()) { + list = CardLists.filter(CardLists.filterControlledBy(game.getCardsInGame(), opp), CardPredicates.Presets.CREATURES); + } + chosen.add(ComputerUtilCard.getMostProminentColor(list, colorChoices)); + } + else if (logic.equals("MostProminentComputerControls")) { + chosen.add(ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield), colorChoices)); + } + else if (logic.equals("MostProminentHumanControls")) { + chosen.add(ComputerUtilCard.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield), colorChoices)); + } + else if (logic.equals("MostProminentPermanent")) { + final List list = game.getCardsIn(ZoneType.Battlefield); + chosen.add(ComputerUtilCard.getMostProminentColor(list, colorChoices)); + } + else if (logic.equals("MostProminentAttackers") && game.getPhaseHandler().inCombat()) { + chosen.add(ComputerUtilCard.getMostProminentColor(game.getCombat().getAttackers(), colorChoices)); + } + else if (logic.equals("MostProminentKeywordInComputerDeck")) { + List list = ai.getAllCards(); + int m1 = 0; + String chosenColor = MagicColor.Constant.WHITE; + + for (final String c : MagicColor.Constant.ONLY_COLORS) { + final int cmp = CardLists.filter(list, CardPredicates.containsKeyword(c)).size(); + if (cmp > m1) { + m1 = cmp; + chosenColor = c; + } + } + chosen.add(chosenColor); + } + } + if (chosen.size() == 0) { + chosen.add(MagicColor.Constant.GREEN); + } + return chosen; + } } diff --git a/forge-gui/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-gui/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index b9a339eb115..2d1b3796032 100644 --- a/forge-gui/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-gui/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -8,7 +8,6 @@ import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import forge.Singletons; import forge.ai.ability.ChangeZoneAi; import forge.card.CardCharacteristicName; import forge.game.Game; @@ -31,7 +30,6 @@ import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.GuiDialog; -import forge.gui.input.InputSelectCardsFromList; import forge.util.Aggregates; import forge.util.Lang; @@ -759,19 +757,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } else { boolean mustChoose = sa.hasParam("Mandatory"); // card has to be on battlefield or in own hand - boolean canUseInputToSelectCard = origin.size() == 1 && ( origin.get(0) == ZoneType.Battlefield || origin.get(0) == ZoneType.Hand && player == decider); if (mustChoose && fetchList.size() == 1) { c = fetchList.get(0); - } else if( canUseInputToSelectCard ) { - InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, fetchList); - inp.setCancelAllowed(!mustChoose); - inp.setMessage(selectPrompt); - Singletons.getControl().getInputQueue().setInputAndWait(inp); - c = inp.hasCancelled() ? null : inp.getSelected().get(0); - } - else { - List chosen = GuiChoose.getChoices(selectPrompt, mustChoose ? 1 : 0, 1, fetchList); - c = chosen.isEmpty() ? null : chosen.get(0); + } else { + c = decider.getController().chooseSingleCardForEffect(fetchList, sa, selectPrompt, !mustChoose); } } @@ -808,7 +797,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (!list.isEmpty()) { Card attachedTo = null; if (list.size() > 1) { - attachedTo = GuiChoose.one(c + " - Select a card to attach to.", list); + attachedTo = decider.getController().chooseSingleCardForEffect(list, sa, c + " - Select a card to attach to."); } else { attachedTo = list.get(0); } diff --git a/forge-gui/src/main/java/forge/game/ability/effects/ChooseColorEffect.java b/forge-gui/src/main/java/forge/game/ability/effects/ChooseColorEffect.java index 0566542933d..0284621d660 100644 --- a/forge-gui/src/main/java/forge/game/ability/effects/ChooseColorEffect.java +++ b/forge-gui/src/main/java/forge/game/ability/effects/ChooseColorEffect.java @@ -4,18 +4,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import forge.ai.ComputerUtilCard; import forge.card.MagicColor; -import forge.game.Game; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; -import forge.game.zone.ZoneType; -import forge.gui.GuiChoose; +import forge.util.Lang; public class ChooseColorEffect extends SpellAbilityEffect { @@ -51,88 +46,17 @@ public class ChooseColorEffect extends SpellAbilityEffect { for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { - if (p.isHuman()) { - if (sa.hasParam("OrColors")) { - final List o = GuiChoose.getChoices("Choose a color or colors", 1, colorChoices.size(), colorChoices); - card.setChosenColor(new ArrayList(o)); - } else if (sa.hasParam("TwoColors")) { - final List o = GuiChoose.getChoices("Choose two colors", 2, 2, colorChoices); - card.setChosenColor(new ArrayList(o)); - } else { - final Object o = GuiChoose.one("Choose a color", colorChoices); - if (null == o) { - return; - } - final String choice = (String) o; - final ArrayList tmpColors = new ArrayList(); - tmpColors.add(choice); - card.setChosenColor(tmpColors); - } - } else { - List chosen = new ArrayList(); - Player ai = sa.getActivatingPlayer(); - final Game game = ai.getGame(); - Player opp = ai.getOpponent(); - if (sa.hasParam("AILogic")) { - final String logic = sa.getParam("AILogic"); - if (logic.equals("MostProminentInHumanDeck")) { - chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), - opp), colorChoices)); - } else if (logic.equals("MostProminentInComputerDeck")) { - chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), - ai), colorChoices)); - } else if (logic.equals("MostProminentDualInComputerDeck")) { - List prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai)); - chosen.add(prominence.get(0)); - chosen.add(prominence.get(1)); - } - else if (logic.equals("MostProminentInGame")) { - chosen.add(ComputerUtilCard.getMostProminentColor(game.getCardsInGame(), colorChoices)); - } - else if (logic.equals("MostProminentHumanCreatures")) { - List list = opp.getCreaturesInPlay(); - if (list.isEmpty()) { - list = CardLists.filter(CardLists.filterControlledBy(game.getCardsInGame(), opp), CardPredicates.Presets.CREATURES); - } - chosen.add(ComputerUtilCard.getMostProminentColor(list, colorChoices)); - } - else if (logic.equals("MostProminentComputerControls")) { - chosen.add(ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield), colorChoices)); - } - else if (logic.equals("MostProminentHumanControls")) { - chosen.add(ComputerUtilCard.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield), colorChoices)); - } - else if (logic.equals("MostProminentPermanent")) { - final List list = game.getCardsIn(ZoneType.Battlefield); - chosen.add(ComputerUtilCard.getMostProminentColor(list, colorChoices)); - } - else if (logic.equals("MostProminentAttackers") && game.getPhaseHandler().inCombat()) { - chosen.add(ComputerUtilCard.getMostProminentColor(game.getCombat().getAttackers(), colorChoices)); - } - else if (logic.equals("MostProminentKeywordInComputerDeck")) { - List list = ai.getAllCards(); - int max = 0; - String chosenColor = MagicColor.Constant.WHITE; - - for (final String c : MagicColor.Constant.ONLY_COLORS) { - final int cmp = CardLists.filter(list, CardPredicates.containsKeyword(c)).size(); - if (cmp > max) { - max = cmp; - chosenColor = c; - } - } - chosen.add(chosenColor); - } - } - if (chosen.size() == 0) { - chosen.add(MagicColor.Constant.GREEN); - } - GuiChoose.one("Computer picked: ", chosen); - final ArrayList colorTemp = new ArrayList(); - colorTemp.addAll(chosen); - card.setChosenColor(colorTemp); - } + List chosenColors; + int cntMin = sa.hasParam("TwoColors") ? 2 : 1; + int cntMax = sa.hasParam("TwoColors") ? 2 : sa.hasParam("OrColors") ? colorChoices.size() : 1; + String prompt = cntMax == 1 ? "Choose a color" : cntMin == 2 ? "Choose two colors" : "Choose a color or colors"; + chosenColors = p.getController().chooseColors(prompt, sa, 1, colorChoices.size(), colorChoices); + if(chosenColors.isEmpty()) + return; + card.setChosenColor(chosenColors); + p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + Lang.joinHomogenous(chosenColors), p); } + } } diff --git a/forge-gui/src/main/java/forge/game/player/PlayerController.java b/forge-gui/src/main/java/forge/game/player/PlayerController.java index 578aa512615..95e6a4a4528 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerController.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerController.java @@ -178,4 +178,5 @@ public abstract class PlayerController { public abstract String chooseHybridMana(String s); public abstract PaperCard chooseSinglePaperCard(SpellAbility sa, String message, Predicate cpp, String name); + public abstract List chooseColors(String message, SpellAbility sa, int min, int max, List options); } diff --git a/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java b/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java index e4adbe9d58d..b84e6de651a 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java @@ -510,4 +510,9 @@ public class PlayerControllerAi extends PlayerController { Predicate cpp, String name) { throw new UnsupportedOperationException("Should not be called for AI"); // or implement it if you know how } + + @Override + public List chooseColors(String message, SpellAbility sa, int min, int max, List options) { + return ComputerUtilCard.chooseColor(sa, min, max, options); + } } diff --git a/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java index 1a6b1be7bb6..7efca655a9a 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -742,7 +742,7 @@ public class PlayerControllerHuman extends PlayerController { String counterChoiceTitle = "Choose a counter type on " + cardWithCounter; final CounterType chosen = GuiChoose.one(counterChoiceTitle, cardWithCounter.getCounters().keySet()); - String putOrRemoveTitle = "Do what with counter " + chosen.getName() + "counter "; + String putOrRemoveTitle = "What to do with that '" + chosen.getName() + "' counter "; final String putString = "Put another " + chosen.getName() + " counter on " + cardWithCounter; final String removeString = "Remove a " + chosen.getName() + " counter from " + cardWithCounter; final String addOrRemove = GuiChoose.one(putOrRemoveTitle, new String[]{putString,removeString}); @@ -827,6 +827,11 @@ public class PlayerControllerHuman extends PlayerController { return chosen; } + @Override + public List chooseColors(String message, SpellAbility sa, int min, int max, List options) { + return GuiChoose.getChoices(message, min, max, options); + } + @Override public String chooseSingleColor(ImmutableList names) { return GuiChoose.one("Choose a color:", names); diff --git a/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 2a66cc2ac66..2380d725cc5 100644 --- a/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -449,4 +449,9 @@ public class PlayerControllerForTests extends PlayerController { public PaperCard chooseSinglePaperCard( SpellAbility sa, String message, Predicate cpp, String name ) { throw new IllegalStateException( "Erring on the side of caution here..." ); } + + @Override + public List chooseColors(String message, SpellAbility sa, int min, int max, List options) { + throw new UnsupportedOperationException("No idea how a test player controller would choose colors"); + } }