From f760d39e7e2c714a9f7dbd55a9652da9bd69c39b Mon Sep 17 00:00:00 2001 From: Hellfish Date: Tue, 2 Apr 2013 19:13:44 +0000 Subject: [PATCH] *Added support for Partial Paris Mulligan. --- .gitattributes | 1 + .../forge/control/input/InputControl.java | 4 +- .../input/InputPartialParisMulligan.java | 234 ++++++++++++++++++ 3 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/main/java/forge/control/input/InputPartialParisMulligan.java diff --git a/.gitattributes b/.gitattributes index 161b4226c87..0e721e172b4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13842,6 +13842,7 @@ src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain src/main/java/forge/control/input/InputControl.java svneol=native#text/plain src/main/java/forge/control/input/InputLockUI.java -text src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain +src/main/java/forge/control/input/InputPartialParisMulligan.java -text src/main/java/forge/control/input/InputPassPriority.java svneol=native#text/plain src/main/java/forge/control/input/InputPayManaBase.java -text src/main/java/forge/control/input/InputPayManaExecuteCommands.java svneol=native#text/plain diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index cba5c1c743e..1dc92439be2 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -116,8 +116,10 @@ public class InputControl extends MyObservable implements java.io.Serializable { */ public final Input getActualInput(GameState game) { if ( !game.hasMulliganned() ) + { return new InputMulligan(Singletons.getModel().getMatch(), Singletons.getControl().getPlayer()); - + //return new InputPartialParisMulligan(Singletons.getModel().getMatch(), Singletons.getControl().getPlayer()); + } final PhaseHandler handler = game.getPhaseHandler(); final PhaseType phase = handler.getPhase(); final Player playerTurn = handler.getPlayerTurn(); diff --git a/src/main/java/forge/control/input/InputPartialParisMulligan.java b/src/main/java/forge/control/input/InputPartialParisMulligan.java new file mode 100644 index 00000000000..b8e5802bbd9 --- /dev/null +++ b/src/main/java/forge/control/input/InputPartialParisMulligan.java @@ -0,0 +1,234 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.control.input; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.Iterables; + +import forge.Card; +import forge.CardPredicates; +import forge.FThreads; +import forge.card.ability.AbilityFactory; +import forge.card.spellability.SpellAbility; +import forge.game.GameAction; +import forge.game.GameState; +import forge.game.GameType; +import forge.game.MatchController; +import forge.game.ai.ComputerUtil; +import forge.game.player.AIPlayer; +import forge.game.player.Player; +import forge.game.zone.Zone; +import forge.game.zone.ZoneType; +import forge.gui.GuiDialog; +import forge.gui.framework.SDisplayUtil; +import forge.gui.match.CMatchUI; +import forge.gui.match.nonsingleton.VField; +import forge.gui.match.views.VMessage; +import forge.view.ButtonUtil; + /** + *

+ * InputMulligan class. + *

+ * + * @author Forge + * @version $Id: InputMulligan.java 20698 2013-04-01 09:56:12Z Max mtg $ + */ +public class InputPartialParisMulligan extends InputBase { + /** Constant serialVersionUID=-8112954303001155622L. */ + private static final long serialVersionUID = -8112954303001155622L; + + private final MatchController match; + + private final List lastExiled = new ArrayList(); + + public InputPartialParisMulligan(MatchController match0, Player humanPlayer) { + super(humanPlayer); + match = match0; + } + + /** {@inheritDoc} */ + @Override + public final void showMessage() { + ButtonUtil.setButtonText("Done", "Exile"); + ButtonUtil.enableOnlyOk(); + + GameState game = match.getCurrentGame(); + Player startingPlayer = game.getPhaseHandler().getPlayerTurn(); + + StringBuilder sb = new StringBuilder(); + sb.append(startingPlayer.getName()).append(" is going first. "); + + if (!startingPlayer.equals(player)) { + sb.append("You are going ").append(game.getOrdinalPosition(player, startingPlayer)).append(". "); + } + + sb.append("Do you want to Mulligan?"); + showMessage(sb.toString()); + } + + /** {@inheritDoc} */ + @Override + public final void selectButtonOK() { + this.end(); + } + + /** {@inheritDoc} */ + @Override + public final void selectButtonCancel() { + for(Card c : lastExiled) + { + match.getCurrentGame().action.exile(c); + } + + player.drawCards(lastExiled.size()-1); + lastExiled.clear(); + + if (player.getCardsIn(ZoneType.Hand).isEmpty()) { + this.end(); + } else { + ButtonUtil.enableAllFocusOk(); + } + } + + final void end() { + + final GameState game = match.getCurrentGame(); + + // Computer mulligan + //TODO: How should AI approach Partial Paris? + /* + for (Player p : game.getPlayers()) { + if (!(p instanceof AIPlayer)) { + continue; + } + AIPlayer ai = (AIPlayer) p; + while (ComputerUtil.wantMulligan(ai)) { + ai.doMulligan(); + } + }*/ + + // Human Leylines & Chancellors + ButtonUtil.reset(); + + final GameAction ga = game.getAction(); + for (Player p : game.getPlayers()) { + final List openingHand = new ArrayList(p.getCardsIn(ZoneType.Hand)); + + for (final Card c : openingHand) { + if (p.isHuman()) { + for (String kw : c.getKeyword()) { + if (kw.startsWith("MayEffectFromOpeningHand")) { + final String effName = kw.split(":")[1]; + + final SpellAbility effect = AbilityFactory.getAbility(c.getSVar(effName), c); + if (GuiDialog.confirm(c, "Use " + c +"'s ability?")) { + // If we ever let the AI memorize cards in the players + // hand, this would be a place to do so. + game.getActionPlay().playSpellAbilityNoStack(p, effect); + } + } + } + if (c.getName().startsWith("Leyline of")) { + if (GuiDialog.confirm(c, "Use " + c + "'s ability?")) { + ga.moveToPlay(c); + } + } + } else { // Computer Leylines & Chancellors + if (!c.getName().startsWith("Leyline of")) { + for (String kw : c.getKeyword()) { + if (kw.startsWith("MayEffectFromOpeningHand")) { + final String effName = kw.split(":")[1]; + + final SpellAbility effect = AbilityFactory.getAbility(c.getSVar(effName), c); + + // Is there a better way for the AI to decide this? + if (effect.doTrigger(false, (AIPlayer)p)) { + GuiDialog.message("Computer reveals " + c.getName() + "(" + c.getUniqueNumber() + ")."); + ComputerUtil.playNoStack((AIPlayer)p, effect, game); + } + } + } + } + if (c.getName().startsWith("Leyline of") + && !(c.getName().startsWith("Leyline of Singularity") + && (Iterables.any(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Leyline of Singularity"))))) { + ga.moveToPlay(c); + //ga.checkStateEffects(); + } + } + } + } + + ga.checkStateEffects(); + + Player next = game.getPhaseHandler().getPlayerTurn(); + + if(game.getType() == GameType.Planechase) + { + next.initPlane(); + } + + //Set Field shown to current player. + VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(next); + SDisplayUtil.showTab(nextField); + + game.setMulliganned(true); + FThreads.invokeInNewThread( new Runnable() { + @Override + public void run() { + match.getInput().clearInput(); + } + }); + } + + @Override + public void selectCard(Card c0) { + if(lastExiled.contains(c0)) + { + lastExiled.remove(c0); + c0.setUsedToPay(false); + return; + } + + Zone z0 = match.getCurrentGame().getZoneOf(c0); + if (c0.getName().equals("Serum Powder") && z0.is(ZoneType.Hand)) { + if (GuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) { + List hand = new ArrayList(c0.getController().getCardsIn(ZoneType.Hand)); + for (Card c : hand) { + match.getCurrentGame().getAction().exile(c); + } + c0.getController().drawCards(hand.size()); + } + else + { + lastExiled.add(c0); + c0.setUsedToPay(true); + } + } else { + lastExiled.add(c0); + c0.setUsedToPay(true); + } + + if(lastExiled.size() > 0) + ButtonUtil.enableAllFocusOk(); + else + ButtonUtil.enableOnlyOk(); + } +}