mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
confirmAction - added a enum parameter for cases when no API is avaliable
ChooseTypeEffect - moved choose logic into ComputerUtil
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14267,6 +14267,7 @@ src/main/java/forge/game/player/LobbyPlayerAi.java -text
|
|||||||
src/main/java/forge/game/player/LobbyPlayerHuman.java -text
|
src/main/java/forge/game/player/LobbyPlayerHuman.java -text
|
||||||
src/main/java/forge/game/player/LobbyPlayerRemote.java -text
|
src/main/java/forge/game/player/LobbyPlayerRemote.java -text
|
||||||
src/main/java/forge/game/player/Player.java svneol=native#text/plain
|
src/main/java/forge/game/player/Player.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/game/player/PlayerActionConfirmMode.java -text
|
||||||
src/main/java/forge/game/player/PlayerController.java -text
|
src/main/java/forge/game/player/PlayerController.java -text
|
||||||
src/main/java/forge/game/player/PlayerControllerAi.java -text
|
src/main/java/forge/game/player/PlayerControllerAi.java -text
|
||||||
src/main/java/forge/game/player/PlayerControllerHuman.java -text
|
src/main/java/forge/game/player/PlayerControllerHuman.java -text
|
||||||
|
|||||||
@@ -4,21 +4,13 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
|
||||||
import forge.CardPredicates;
|
|
||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.GameState;
|
|
||||||
import forge.game.ai.ComputerUtilCard;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
|
|
||||||
public class ChooseTypeEffect extends SpellAbilityEffect {
|
public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
@@ -38,12 +30,9 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
|||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card card = sa.getSourceCard();
|
final Card card = sa.getSourceCard();
|
||||||
final String type = sa.getParam("Type");
|
final String type = sa.getParam("Type");
|
||||||
final ArrayList<String> invalidTypes = new ArrayList<String>();
|
final List<String> invalidTypes = sa.hasParam("InvalidTypes") ? Arrays.asList(sa.getParam("InvalidTypes").split(",")) : new ArrayList<String>();
|
||||||
if (sa.hasParam("InvalidTypes")) {
|
|
||||||
invalidTypes.addAll(Arrays.asList(sa.getParam("InvalidTypes").split(",")));
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArrayList<String> validTypes = new ArrayList<String>();
|
final List<String> validTypes = new ArrayList<String>();
|
||||||
if (sa.hasParam("ValidTypes")) {
|
if (sa.hasParam("ValidTypes")) {
|
||||||
validTypes.addAll(Arrays.asList(sa.getParam("ValidTypes").split(",")));
|
validTypes.addAll(Arrays.asList(sa.getParam("ValidTypes").split(",")));
|
||||||
}
|
}
|
||||||
@@ -52,174 +41,25 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
|||||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||||
|
|
||||||
for (final Player p : tgtPlayers) {
|
for (final Player p : tgtPlayers) {
|
||||||
final GameState game = p.getGame();
|
|
||||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||||
|
|
||||||
if (type.equals("Card")) {
|
if (type.equals("Card")) {
|
||||||
if (validTypes.isEmpty()) {
|
if (validTypes.isEmpty()) validTypes.addAll(Constant.CardTypes.CARD_TYPES);
|
||||||
validTypes.addAll(Constant.CardTypes.CARD_TYPES);
|
|
||||||
}
|
|
||||||
boolean valid = false;
|
|
||||||
while (!valid) {
|
|
||||||
if (p.isHuman()) {
|
|
||||||
final Object o = GuiChoose.one("Choose a card type", validTypes);
|
|
||||||
if (null == o) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String choice = (String) o;
|
|
||||||
if (CardType.isACardType(choice) && !invalidTypes.contains(choice)) {
|
|
||||||
valid = true;
|
|
||||||
card.setChosenType(choice);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
// computer will need to choose a type
|
|
||||||
// based on whether it needs a creature or land,
|
|
||||||
// otherwise, lib search for most common type left
|
|
||||||
// then, reveal chosenType to Human
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type.equals("Creature")) {
|
} else if (type.equals("Creature")) {
|
||||||
String chosenType = "";
|
if (validTypes.isEmpty()) validTypes.addAll(CardType.getCreatureTypes());
|
||||||
boolean valid = false;
|
|
||||||
while (!valid) {
|
|
||||||
if (p.isHuman()) {
|
|
||||||
final ArrayList<String> validChoices = CardType.getCreatureTypes();
|
|
||||||
for (final String s : invalidTypes) {
|
|
||||||
validChoices.remove(s);
|
|
||||||
}
|
|
||||||
chosenType = GuiChoose.one("Choose a creature type", validChoices);
|
|
||||||
} else {
|
|
||||||
Player ai = p;
|
|
||||||
Player opp = ai.getOpponent();
|
|
||||||
String chosen = "";
|
|
||||||
if (sa.hasParam("AILogic")) {
|
|
||||||
final String logic = sa.getParam("AILogic");
|
|
||||||
if (logic.equals("MostProminentOnBattlefield")) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(game.getCardsIn(ZoneType.Battlefield));
|
|
||||||
}
|
|
||||||
else if (logic.equals("MostProminentComputerControls")) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
|
||||||
}
|
|
||||||
else if (logic.equals("MostProminentHumanControls")) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), opp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
|
||||||
}
|
|
||||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
|
||||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
|
||||||
chosen = "Sliver";
|
|
||||||
}
|
|
||||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
|
||||||
chosenType = chosen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CardType.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) {
|
|
||||||
valid = true;
|
|
||||||
card.setChosenType(chosenType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type.equals("Basic Land")) {
|
} else if (type.equals("Basic Land")) {
|
||||||
boolean valid = false;
|
if (validTypes.isEmpty()) validTypes.addAll(CardType.getBasicTypes());
|
||||||
while (!valid) {
|
|
||||||
if (p.isHuman()) {
|
|
||||||
final String choice = GuiChoose.one("Choose a basic land type", CardType.getBasicTypes());
|
|
||||||
if (null == choice) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (CardType.isABasicLandType(choice) && !invalidTypes.contains(choice)) {
|
|
||||||
valid = true;
|
|
||||||
card.setChosenType(choice);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Player ai = p;
|
|
||||||
String chosen = "";
|
|
||||||
if (sa.hasParam("AILogic")) {
|
|
||||||
final String logic = sa.getParam("AILogic");
|
|
||||||
if (logic.equals("MostNeededType")) {
|
|
||||||
// Choose a type that is in the deck, but not in hand or on the battlefield
|
|
||||||
final ArrayList<String> basics = new ArrayList<String>();
|
|
||||||
basics.addAll(Constant.CardTypes.BASIC_TYPES);
|
|
||||||
List<Card> presentCards = ai.getCardsIn(ZoneType.Battlefield);
|
|
||||||
presentCards.addAll(ai.getCardsIn(ZoneType.Hand));
|
|
||||||
List<Card> possibleCards = ai.getAllCards();
|
|
||||||
|
|
||||||
for (String b : basics) {
|
|
||||||
if(!Iterables.any(presentCards, CardPredicates.isType(b)) && Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
|
||||||
chosen = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chosen.equals("")) {
|
|
||||||
for (String b : basics) {
|
|
||||||
if(Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
|
||||||
chosen = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (logic.equals("ChosenLandwalk")) {
|
|
||||||
final List<Card> lands = p.getOpponent().getLandsInPlay();
|
|
||||||
for (Card c : lands) {
|
|
||||||
for (String t : c.getType()) {
|
|
||||||
if (!invalidTypes.contains(t)
|
|
||||||
&& CardType.isABasicLandType(t)) {
|
|
||||||
chosen = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CardType.isABasicLandType(chosen) || invalidTypes.contains(chosen)) {
|
|
||||||
chosen = "Island";
|
|
||||||
}
|
|
||||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
|
||||||
card.setChosenType(chosen);
|
|
||||||
valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type.equals("Land")) {
|
} else if (type.equals("Land")) {
|
||||||
boolean valid = false;
|
if (validTypes.isEmpty()) validTypes.addAll(CardType.getLandTypes());
|
||||||
while (!valid) {
|
|
||||||
if (p.isHuman()) {
|
|
||||||
final String choice = GuiChoose
|
|
||||||
.one("Choose a land type", CardType.getLandTypes());
|
|
||||||
if (null == choice) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!invalidTypes.contains(choice)) {
|
|
||||||
valid = true;
|
|
||||||
card.setChosenType(choice);
|
|
||||||
}
|
|
||||||
} else {//AI
|
|
||||||
String choice = null;
|
|
||||||
if (sa.hasParam("AILogic")) {
|
|
||||||
final String logic = sa.getParam("AILogic");
|
|
||||||
if (logic.equals("ChosenLandwalk")) {
|
|
||||||
final List<Card> lands = p.getOpponent().getLandsInPlay();
|
|
||||||
for (Card c : lands) {
|
|
||||||
for (String t : c.getType()) {
|
|
||||||
if (!invalidTypes.contains(t)
|
|
||||||
&& CardType.getLandTypes().contains(t)) {
|
|
||||||
choice = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
card.setChosenType(choice != null ? choice :"Island");
|
|
||||||
valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end if-else if
|
} // end if-else if
|
||||||
|
|
||||||
|
if( !validTypes.isEmpty()) {
|
||||||
|
for (final String s : invalidTypes) {
|
||||||
|
validTypes.remove(s);
|
||||||
|
}
|
||||||
|
String choice = p.getController().chooseSomeType(type, sa.getParam("AILogic"), validTypes, invalidTypes);
|
||||||
|
card.setChosenType(choice);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
|
|
||||||
if (mode.equals("Random")) {
|
if (mode.equals("Random")) {
|
||||||
String message = "Would you like to discard " + numCards + " random card(s)?";
|
String message = "Would you like to discard " + numCards + " random card(s)?";
|
||||||
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, mode, message);
|
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message);
|
||||||
|
|
||||||
if (runDiscard) {
|
if (runDiscard) {
|
||||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import forge.game.GameState;
|
|||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
@@ -699,15 +700,18 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
@SuppressWarnings("incomplete-switch")
|
||||||
|
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
ApiType api = sa.getApi();
|
ApiType api = sa.getApi();
|
||||||
|
|
||||||
|
// Abilities without api may also use this routine, However they should provide a unique mode value
|
||||||
if ( null == api ) {
|
if ( null == api ) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
if( mode != null ) switch (mode) {
|
||||||
}
|
case BraidOfFire: return true;
|
||||||
|
}
|
||||||
switch(api) {
|
} else switch(api) {
|
||||||
case Discard:
|
case Discard:
|
||||||
if ( mode.startsWith("Random") ) { //
|
if ( mode == PlayerActionConfirmMode.Random ) { //
|
||||||
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -718,7 +722,7 @@ public class AiController {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
String exMsg = String.format("AI confirmAction does not know what to decide about %s with %s mode.", api, mode);
|
String exMsg = String.format("AI confirmAction does not know what to decide about %s API with %s mode.", api, mode);
|
||||||
throw new InvalidParameterException(exMsg);
|
throw new InvalidParameterException(exMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,18 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
|
import forge.Constant;
|
||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.CardUtil;
|
import forge.CardUtil;
|
||||||
|
import forge.card.CardType;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
@@ -658,6 +662,12 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
// Precondition it wants: remaining are reverse-sorted by CMC
|
// Precondition it wants: remaining are reverse-sorted by CMC
|
||||||
private static Card chooseCardToSacrifice(final List<Card> remaining, final Player ai, final boolean destroy) {
|
private static Card chooseCardToSacrifice(final List<Card> remaining, final Player ai, final boolean destroy) {
|
||||||
|
// If somehow ("Drop of Honey") they suggest to destroy opponent's card - use the chance!
|
||||||
|
for(Card c : remaining) { // first compare is fast, second is precise
|
||||||
|
if (c.getController() != ai && ai.getOpponents().contains(c.getController()) )
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
if (destroy) {
|
if (destroy) {
|
||||||
final List<Card> indestructibles = CardLists.getKeyword(remaining, "Indestructible");
|
final List<Card> indestructibles = CardLists.getKeyword(remaining, "Indestructible");
|
||||||
if (!indestructibles.isEmpty()) {
|
if (!indestructibles.isEmpty()) {
|
||||||
@@ -1420,4 +1430,99 @@ public class ComputerUtil {
|
|||||||
// no special options for human or remote friends
|
// no special options for human or remote friends
|
||||||
return getCardsToDiscardFromOpponent(aiChooser, p, sa, validCards, min, max);
|
return getCardsToDiscardFromOpponent(aiChooser, p, sa, validCards, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String chooseSomeType(Player ai, String kindOfType, String logic, List<String> invalidTypes) {
|
||||||
|
final GameState game = ai.getGame();
|
||||||
|
String chosen = "";
|
||||||
|
if( kindOfType.equals("Card")) {
|
||||||
|
// TODO
|
||||||
|
// computer will need to choose a type
|
||||||
|
// based on whether it needs a creature or land,
|
||||||
|
// otherwise, lib search for most common type left
|
||||||
|
// then, reveal chosenType to Human
|
||||||
|
} else if (kindOfType.equals("Creature")) {
|
||||||
|
Player opp = ai.getOpponent();
|
||||||
|
if (logic != null ) {
|
||||||
|
if (logic.equals("MostProminentOnBattlefield")) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(game.getCardsIn(ZoneType.Battlefield));
|
||||||
|
}
|
||||||
|
else if (logic.equals("MostProminentComputerControls")) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||||
|
}
|
||||||
|
else if (logic.equals("MostProminentHumanControls")) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||||
|
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), opp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||||
|
}
|
||||||
|
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||||
|
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
|
chosen = "Sliver";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ( kindOfType.equals("Basic Land")) {
|
||||||
|
if (logic != null) {
|
||||||
|
if (logic.equals("MostNeededType")) {
|
||||||
|
// Choose a type that is in the deck, but not in hand or on the battlefield
|
||||||
|
final ArrayList<String> basics = new ArrayList<String>();
|
||||||
|
basics.addAll(Constant.CardTypes.BASIC_TYPES);
|
||||||
|
List<Card> presentCards = ai.getCardsIn(ZoneType.Battlefield);
|
||||||
|
presentCards.addAll(ai.getCardsIn(ZoneType.Hand));
|
||||||
|
List<Card> possibleCards = ai.getAllCards();
|
||||||
|
|
||||||
|
for (String b : basics) {
|
||||||
|
if(!Iterables.any(presentCards, CardPredicates.isType(b)) && Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||||
|
chosen = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chosen.equals("")) {
|
||||||
|
for (String b : basics) {
|
||||||
|
if(Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||||
|
chosen = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (logic.equals("ChosenLandwalk")) {
|
||||||
|
for (Card c : ai.getOpponent().getLandsInPlay()) {
|
||||||
|
for (String t : c.getType()) {
|
||||||
|
if (!invalidTypes.contains(t) && CardType.isABasicLandType(t)) {
|
||||||
|
chosen = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CardType.isABasicLandType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
|
chosen = "Island";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if( kindOfType.equals("Land") ) {
|
||||||
|
if (logic != null) {
|
||||||
|
if (logic.equals("ChosenLandwalk")) {
|
||||||
|
for (Card c : ai.getOpponent().getLandsInPlay()) {
|
||||||
|
for (String t : c.getType()) {
|
||||||
|
if (!invalidTypes.contains(t) && CardType.isALandType(t)) {
|
||||||
|
chosen = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( StringUtils.isEmpty(chosen))
|
||||||
|
chosen = "Island";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||||
|
return chosen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import forge.game.ai.ComputerUtilCost;
|
|||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.player.HumanPlay;
|
import forge.game.player.HumanPlay;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.zone.PlayerZone;
|
import forge.game.zone.PlayerZone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -133,9 +134,7 @@ public class Upkeep extends Phase {
|
|||||||
Map<String, String> produced = new HashMap<String, String>();
|
Map<String, String> produced = new HashMap<String, String>();
|
||||||
produced.put("Produced", rs.toString());
|
produced.put("Produced", rs.toString());
|
||||||
final AbilityManaPart abMana = new AbilityManaPart(c, produced);
|
final AbilityManaPart abMana = new AbilityManaPart(c, produced);
|
||||||
if (player.isComputer()) {
|
if( player.getController().confirmAction(this, PlayerActionConfirmMode.BraidOfFire, sb.toString())) {
|
||||||
abMana.produceMana(this);
|
|
||||||
} else if (GuiDialog.confirm(c, sb.toString())) {
|
|
||||||
abMana.produceMana(this);
|
abMana.produceMana(this);
|
||||||
} else {
|
} else {
|
||||||
game.getAction().sacrifice(c, null);
|
game.getAction().sacrifice(c, null);
|
||||||
@@ -493,48 +492,17 @@ public class Upkeep extends Phase {
|
|||||||
final List<Card> creatures = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
final List<Card> creatures = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
||||||
if (creatures.size() > 0) {
|
if (creatures.size() > 0) {
|
||||||
CardLists.sortByPowerAsc(creatures);
|
CardLists.sortByPowerAsc(creatures);
|
||||||
|
final List<Card> lowest = new ArrayList<Card>();
|
||||||
final int power = creatures.get(0).getNetAttack();
|
final int power = creatures.get(0).getNetAttack();
|
||||||
if (player.isHuman()) {
|
for(Card c : creatures) {
|
||||||
InputSelectCards inp = new InputSelectCardsFromList(1,1,this.getLowestPowerList(creatures));
|
if (c.getNetAttack() > power) break;
|
||||||
inp.setMessage("Select creature with power: " + power + " to sacrifice.");
|
lowest.add(c);
|
||||||
FThreads.setInputAndWait(inp);
|
|
||||||
if(!inp.hasCancelled())
|
|
||||||
game.getAction().destroyNoRegeneration(inp.getSelected().get(0), this);
|
|
||||||
|
|
||||||
} else { // computer
|
|
||||||
final Card compyTarget = this.getCompyCardToDestroy(creatures);
|
|
||||||
game.getAction().destroyNoRegeneration(compyTarget, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Card> toSac = player.getController().choosePermanentsToSacrifice(lowest, "Select creature with power: " + power + " to destroy.", 1, this, true, false);
|
||||||
|
game.getAction().destroyNoRegeneration(toSac.get(0), this);
|
||||||
}
|
}
|
||||||
} // resolve
|
} // resolve
|
||||||
|
|
||||||
private List<Card> getLowestPowerList(final List<Card> original) {
|
|
||||||
final List<Card> lowestPower = new ArrayList<Card>();
|
|
||||||
final int power = original.get(0).getNetAttack();
|
|
||||||
int i = 0;
|
|
||||||
while ((i < original.size()) && (original.get(i).getNetAttack() == power)) {
|
|
||||||
lowestPower.add(original.get(i));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return lowestPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Card getCompyCardToDestroy(final List<Card> original) {
|
|
||||||
final List<Card> options = this.getLowestPowerList(original);
|
|
||||||
final List<Card> humanCreatures = CardLists.filter(options, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.getController().isHuman();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (humanCreatures.isEmpty()) {
|
|
||||||
CardLists.shuffle(options);
|
|
||||||
return options.get(0);
|
|
||||||
} else {
|
|
||||||
CardLists.shuffle(humanCreatures);
|
|
||||||
return humanCreatures.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}; // Ability
|
}; // Ability
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|||||||
11
src/main/java/forge/game/player/PlayerActionConfirmMode.java
Normal file
11
src/main/java/forge/game/player/PlayerActionConfirmMode.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package forge.game.player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by PlayerController.confirmAction - to avoid a lot of hardcoded strings for mode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum PlayerActionConfirmMode {
|
||||||
|
Random,
|
||||||
|
BraidOfFire,
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package forge.game.player;
|
package forge.game.player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -35,11 +34,11 @@ public abstract class PlayerController {
|
|||||||
private PhaseType autoPassUntil = null;
|
private PhaseType autoPassUntil = null;
|
||||||
private final Input autoPassPriorityInput;
|
private final Input autoPassPriorityInput;
|
||||||
protected final Player player;
|
protected final Player player;
|
||||||
|
|
||||||
public PlayerController(GameState game0, Player p) {
|
public PlayerController(GameState game0, Player p) {
|
||||||
game = game0;
|
game = game0;
|
||||||
player = p;
|
player = p;
|
||||||
autoPassPriorityInput = new InputAutoPassPriority(getPlayer());
|
autoPassPriorityInput = new InputAutoPassPriority(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Input getDefaultInput();
|
public abstract Input getDefaultInput();
|
||||||
@@ -66,6 +65,16 @@ public abstract class PlayerController {
|
|||||||
return false; // human has it's overload
|
return false; // human has it's overload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
*/
|
||||||
|
public void passPriority() {
|
||||||
|
PhaseHandler handler = game.getPhaseHandler();
|
||||||
|
|
||||||
|
if ( handler.getPriorityPlayer() == player )
|
||||||
|
game.getPhaseHandler().passPriority();
|
||||||
|
}
|
||||||
|
|
||||||
// Triggers preliminary choice: ask, decline or play
|
// Triggers preliminary choice: ask, decline or play
|
||||||
private Map<Integer, Boolean> triggersAlwaysAccept = new HashMap<Integer, Boolean>();
|
private Map<Integer, Boolean> triggersAlwaysAccept = new HashMap<Integer, Boolean>();
|
||||||
|
|
||||||
@@ -84,16 +93,6 @@ public abstract class PlayerController {
|
|||||||
*/
|
*/
|
||||||
public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities);
|
public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities);
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
*/
|
|
||||||
public void passPriority() {
|
|
||||||
PhaseHandler handler = game.getPhaseHandler();
|
|
||||||
|
|
||||||
if ( handler.getPriorityPlayer() == getPlayer() )
|
|
||||||
game.getPhaseHandler().passPriority();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @param c
|
* @param c
|
||||||
@@ -101,11 +100,8 @@ public abstract class PlayerController {
|
|||||||
public abstract void playFromSuspend(Card c);
|
public abstract void playFromSuspend(Card c);
|
||||||
public abstract boolean playCascade(Card cascadedCard, Card sourceCard);
|
public abstract boolean playCascade(Card cascadedCard, Card sourceCard);
|
||||||
public abstract void playSpellAbilityForFree(SpellAbility copySA);
|
public abstract void playSpellAbilityForFree(SpellAbility copySA);
|
||||||
/**
|
|
||||||
* @return the player
|
|
||||||
*/
|
|
||||||
protected final Player getPlayer(){ return player; }
|
|
||||||
|
|
||||||
|
|
||||||
public abstract Deck sideboard(final Deck deck, GameType gameType);
|
public abstract Deck sideboard(final Deck deck, GameType gameType);
|
||||||
|
|
||||||
@@ -118,7 +114,7 @@ public abstract class PlayerController {
|
|||||||
|
|
||||||
public Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); }
|
public Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); }
|
||||||
public abstract Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title, boolean isOptional);
|
public abstract Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title, boolean isOptional);
|
||||||
public abstract boolean confirmAction(SpellAbility sa, String mode, String message);
|
public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message);
|
||||||
public abstract boolean getWillPlayOnFirstTurn(String message);
|
public abstract boolean getWillPlayOnFirstTurn(String message);
|
||||||
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
||||||
|
|
||||||
@@ -139,4 +135,6 @@ public abstract class PlayerController {
|
|||||||
public abstract List<Card> chooseCardsToDelve(int colorLessAmount, List<Card> grave);
|
public abstract List<Card> chooseCardsToDelve(int colorLessAmount, List<Card> grave);
|
||||||
public abstract List<Card> chooseCardsToDiscardUnlessType(int min, List<Card> hand, String param, SpellAbility sa);
|
public abstract List<Card> chooseCardsToDiscardUnlessType(int min, List<Card> hand, String param, SpellAbility sa);
|
||||||
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
||||||
|
|
||||||
|
public abstract String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,22 +46,32 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
private final AiController brains;
|
private final AiController brains;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final Input getDefaultInput() {
|
|
||||||
return defaultInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerControllerAi(GameState game, Player p) {
|
public PlayerControllerAi(GameState game, Player p) {
|
||||||
super(game, p);
|
super(game, p);
|
||||||
|
|
||||||
brains = new AiController(p, game);
|
brains = new AiController(p, game);
|
||||||
|
|
||||||
defaultInput = new AiInputCommon(brains);
|
defaultInput = new AiInputCommon(brains);
|
||||||
blockInput = new AiInputBlock(getPlayer());
|
blockInput = new AiInputBlock(player);
|
||||||
cleanupInput = getDefaultInput();
|
cleanupInput = getDefaultInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Input getDefaultInput() {
|
||||||
|
return defaultInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Input to use when player has to declare blockers */
|
||||||
|
public Input getBlockInput() {
|
||||||
|
return blockInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cleanupInput
|
||||||
|
*/
|
||||||
|
public Input getCleanupInput() {
|
||||||
|
return cleanupInput;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses GUI to learn which spell the player (human in our case) would like to play
|
* Uses GUI to learn which spell the player (human in our case) would like to play
|
||||||
*/
|
*/
|
||||||
@@ -75,19 +85,6 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Input to use when player has to declare blockers */
|
|
||||||
public Input getBlockInput() {
|
|
||||||
return blockInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the cleanupInput
|
|
||||||
*/
|
|
||||||
public Input getCleanupInput() {
|
|
||||||
return cleanupInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @param c
|
* @param c
|
||||||
@@ -123,11 +120,11 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
if (copySA instanceof Spell) {
|
if (copySA instanceof Spell) {
|
||||||
Spell spell = (Spell) copySA;
|
Spell spell = (Spell) copySA;
|
||||||
if (spell.canPlayFromEffectAI(true, true)) {
|
if (spell.canPlayFromEffectAI(true, true)) {
|
||||||
ComputerUtil.playStackFree(getPlayer(), copySA);
|
ComputerUtil.playStackFree(player, copySA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
copySA.canPlayAI();
|
copySA.canPlayAI();
|
||||||
ComputerUtil.playStackFree(getPlayer(), copySA);
|
ComputerUtil.playStackFree(player, copySA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +156,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
return getAi().confirmAction(sa, mode, message);
|
return getAi().confirmAction(sa, mode, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +212,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min, int max) {
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min, int max) {
|
||||||
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
boolean isTargetFriendly = !p.isOpponentOf(player);
|
||||||
|
|
||||||
return isTargetFriendly
|
return isTargetFriendly
|
||||||
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max)
|
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max)
|
||||||
@@ -274,5 +271,13 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return manaChoices.get(0); // no brains used
|
return manaChoices.get(0); // no brains used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.player.PlayerController#ChooseSomeType(java.lang.String, java.util.List, java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes) {
|
||||||
|
return ComputerUtil.chooseSomeType(player, kindOfType, aiLogic, invalidTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,18 +50,30 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
private final Input blockInput;
|
private final Input blockInput;
|
||||||
private final Input cleanupInput;
|
private final Input cleanupInput;
|
||||||
|
|
||||||
public final Input getDefaultInput() {
|
|
||||||
return defaultInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerControllerHuman(GameState game0, Player p) {
|
public PlayerControllerHuman(GameState game0, Player p) {
|
||||||
super(game0, p);
|
super(game0, p);
|
||||||
defaultInput = new InputPassPriority(player);
|
defaultInput = new InputPassPriority(player);
|
||||||
blockInput = new InputBlock(getPlayer(), game0);
|
blockInput = new InputBlock(player, game0);
|
||||||
cleanupInput = new InputCleanup(getPlayer());
|
cleanupInput = new InputCleanup(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public final Input getDefaultInput() {
|
||||||
|
return defaultInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Input to use when player has to declare blockers */
|
||||||
|
public Input getBlockInput() {
|
||||||
|
return blockInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cleanupInput
|
||||||
|
*/
|
||||||
|
public Input getCleanupInput() {
|
||||||
|
return cleanupInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
||||||
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
||||||
}
|
}
|
||||||
@@ -79,18 +91,6 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Input to use when player has to declare blockers */
|
|
||||||
public Input getBlockInput() {
|
|
||||||
return blockInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the cleanupInput
|
|
||||||
*/
|
|
||||||
public Input getCleanupInput() {
|
|
||||||
return cleanupInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @param c
|
* @param c
|
||||||
@@ -260,7 +260,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
* @see forge.game.player.PlayerController#confirmAction(forge.card.spellability.SpellAbility, java.lang.String, java.lang.String)
|
* @see forge.game.player.PlayerController#confirmAction(forge.card.spellability.SpellAbility, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
return GuiDialog.confirm(sa.getSourceCard(), message);
|
return GuiDialog.confirm(sa.getSourceCard(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +334,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int min, int max) {
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int min, int max) {
|
||||||
if ( p != getPlayer() ) {
|
if ( p != player ) {
|
||||||
int cntToKeepInHand = min == 0 ? -1 : valid.size() - min;
|
int cntToKeepInHand = min == 0 ? -1 : valid.size() - min;
|
||||||
return GuiChoose.order("Choose cards to Discard", "Discarded", cntToKeepInHand, valid, null, null);
|
return GuiChoose.order("Choose cards to Discard", "Discarded", cntToKeepInHand, valid, null, null);
|
||||||
}
|
}
|
||||||
@@ -450,4 +450,12 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return manaChoices.get(Integer.parseInt(idx)-1);
|
return manaChoices.get(Integer.parseInt(idx)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.player.PlayerController#chooseSomeType(java.lang.String, java.lang.String, java.util.List, java.util.List, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes) {
|
||||||
|
return GuiChoose.one("Choose a " + kindOfType.toLowerCase() + " type", validTypes);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ import javax.swing.border.EmptyBorder;
|
|||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import forge.CardUtil;
|
import forge.CardUtil;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.spellability.SpellAbilityStackInstance;
|
import forge.card.spellability.SpellAbilityStackInstance;
|
||||||
import forge.control.FControl;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerController;
|
import forge.game.player.PlayerController;
|
||||||
import forge.game.zone.MagicStack;
|
import forge.game.zone.MagicStack;
|
||||||
|
|||||||
Reference in New Issue
Block a user