From 6205ebaeb964f613368042e3a1c863aaab9cd2c6 Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Tue, 7 Feb 2012 15:15:47 -0500 Subject: [PATCH] fixed Liliana Of The Veil npe when targeting tokens + added choose pile dialog --- .../main/java/mage/client/cards/CardArea.java | 153 ++++++++++++++++++ .../mage/client/dialog/PickPileDialog.java | 142 ++++++++++++++++ .../mage/client/dialog/ShowCardsDialog.java | 107 +++--------- .../main/java/mage/client/game/GamePanel.java | 41 ++--- .../client/remote/CallbackClientImpl.java | 7 + Mage.Common/src/mage/view/CardsView.java | 2 +- .../src/mage/view/GameClientMessage.java | 15 ++ .../java/mage/player/ai/ComputerPlayer.java | 6 + .../mage/player/ai/SimulatedPlayerMCTS.java | 63 ++++---- .../src/mage/player/human/HumanPlayer.java | 12 +- .../java/mage/server/game/GameController.java | 11 ++ .../java/mage/server/game/GameSession.java | 13 ++ .../mage/sets/innistrad/LilianaOfTheVeil.java | 96 ++++++----- Mage/src/mage/game/Game.java | 2 +- Mage/src/mage/game/GameImpl.java | 4 +- .../mage/game/events/PlayerQueryEvent.java | 31 +++- .../game/events/PlayerQueryEventSource.java | 4 + Mage/src/mage/players/Player.java | 1 + 18 files changed, 511 insertions(+), 199 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/cards/CardArea.java create mode 100644 Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java diff --git a/Mage.Client/src/main/java/mage/client/cards/CardArea.java b/Mage.Client/src/main/java/mage/client/cards/CardArea.java new file mode 100644 index 00000000000..4f3577f481d --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/cards/CardArea.java @@ -0,0 +1,153 @@ +/* +* Copyright 2012 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.client.cards; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.util.UUID; + +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import mage.cards.CardDimensions; +import mage.cards.MageCard; +import mage.client.plugins.impl.Plugins; +import mage.client.util.CardsViewUtil; +import mage.client.util.Config; +import mage.view.AbilityView; +import mage.view.CardView; +import mage.view.CardsView; +import mage.view.SimpleCardsView; + +public class CardArea extends JPanel { + + private boolean reloaded = false; + private javax.swing.JLayeredPane cardArea; + private javax.swing.JScrollPane scrollPane; + + /** + * Create the panel. + */ + public CardArea() { + setLayout(new BorderLayout(0, 0)); + + scrollPane = new JScrollPane(); + add(scrollPane, BorderLayout.CENTER); + + cardArea = new JLayeredPane(); + scrollPane.setViewportView(cardArea); + + } + + public void loadCards(SimpleCardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId) { + loadCards(CardsViewUtil.convertSimple(showCards), bigCard, dimension, gameId); + } + + public void loadCards(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId) { + this.reloaded = true; + cardArea.removeAll(); + if (showCards != null && showCards.size() < 10) + loadCardsFew(showCards, bigCard, gameId); + else + loadCardsMany(showCards, bigCard, gameId); + cardArea.revalidate(); + + this.revalidate(); + this.repaint(); + } + + public void loadCardsNarrow(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId) { + this.reloaded = true; + cardArea.removeAll(); + loadCardsMany(showCards, bigCard, gameId); + cardArea.revalidate(); + + this.revalidate(); + this.repaint(); + } + + private void loadCardsFew(CardsView showCards, BigCard bigCard, UUID gameId) { + Rectangle rectangle = new Rectangle(Config.dimensions.frameWidth, Config.dimensions.frameHeight); + Dimension dimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); + for (CardView card : showCards.values()) { + addCard(card, bigCard, gameId, rectangle, dimension); + rectangle.translate(Config.dimensions.frameWidth, 0); + } + cardArea.setPreferredSize(new Dimension(Config.dimensions.frameWidth * showCards.size(), Config.dimensions.frameHeight)); + } + + private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle, Dimension dimension) { + if (card instanceof AbilityView) { + CardView tmp = ((AbilityView) card).getSourceCard(); + tmp.overrideRules(card.getRules()); + tmp.setIsAbility(true); + tmp.overrideTargets(card.getTargets()); + tmp.setAbility(card); // cross-reference, required for ability picker + card = tmp; + } + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId, true); + cardImg.setBounds(rectangle); + cardArea.add(cardImg); + cardArea.moveToFront(cardImg); + cardImg.update(card); + cardImg.setCardBounds(rectangle.x, rectangle.y, Config.dimensions.frameWidth, Config.dimensions.frameHeight); + } + + private void loadCardsMany(CardsView showCards, BigCard bigCard, UUID gameId) { + int columns = 1; + if (showCards != null && showCards.size() > 0) { + Rectangle rectangle = new Rectangle(Config.dimensions.frameWidth, Config.dimensions.frameHeight); + Dimension dimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); + int count = 0; + for (CardView card : showCards.values()) { + addCard(card, bigCard, gameId, rectangle, dimension); + if (count >= 20) { + rectangle.translate(Config.dimensions.frameWidth, -400); + columns++; + count = 0; + } else { + rectangle.translate(0, 20); + count++; + } + } + } + cardArea.setPreferredSize(new Dimension(Config.dimensions.frameWidth * columns, Config.dimensions.frameHeight + 400)); + } + + public boolean isReloaded() { + return this.reloaded; + } + + public void clearReloaded() { + this.reloaded = false; + } + +} diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java new file mode 100644 index 00000000000..f8462fdfcb4 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java @@ -0,0 +1,142 @@ +/* +* Copyright 2012 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.client.dialog; + +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.UUID; + +import javax.swing.JButton; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import mage.cards.CardDimensions; +import mage.client.MageFrame; +import mage.client.cards.BigCard; +import mage.client.cards.CardArea; +import mage.client.util.SettingsManager; +import mage.client.util.gui.GuiDisplayUtil; +import mage.remote.Session; +import mage.view.CardsView; + +/** +* +* @author BetaSteward_at_googlemail.com +*/ +public class PickPileDialog extends MageDialog { + + private CardArea pile1; + private CardArea pile2; + + private boolean pickedPile1 = false; + + /** + * Create the frame. + */ + public PickPileDialog() { + getContentPane().setLayout(new BorderLayout(0, 0)); + + JPanel panel = new JPanel(); + getContentPane().add(panel, BorderLayout.WEST); + panel.setLayout(new BorderLayout(0, 0)); + + pile1 = new CardArea(); + panel.add(pile1, BorderLayout.CENTER); + + JButton btnChoosePile1 = new JButton("Pile 1"); + btnChoosePile1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + btnPile1ActionPerformed(e); + } + }); + panel.add(btnChoosePile1, BorderLayout.NORTH); + + JPanel panel_1 = new JPanel(); + getContentPane().add(panel_1, BorderLayout.EAST); + panel_1.setLayout(new BorderLayout(0, 0)); + + pile2 = new CardArea(); + panel_1.add(pile2, BorderLayout.CENTER); + + JButton btnChoosePile2 = new JButton("Pile 2"); + btnChoosePile2.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + btnPile2ActionPerformed(e); + } + }); + panel_1.add(btnChoosePile2, BorderLayout.NORTH); + } + + public void loadCards(String name, CardsView pile1, CardsView pile2, BigCard bigCard, CardDimensions dimension, UUID gameId) { + this.title = name; + this.pile1.loadCardsNarrow(pile1, bigCard, dimension, gameId); + this.pile2.loadCardsNarrow(pile2, bigCard, dimension, gameId); + + if (getParent() != MageFrame.getDesktop() /*|| this.isClosed*/) { + MageFrame.getDesktop().add(this, JLayeredPane.POPUP_LAYER); + } + pack(); + + this.revalidate(); + this.repaint(); + this.setModal(true); + this.setVisible(true); + +// SwingUtilities.invokeLater(new Runnable() { +// @Override +// public void run() { +// int width = PickPileDialog.this.getWidth(); +// int height = PickPileDialog.this.getWidth(); +// if (width > 0 && height > 0) { +// Point centered = SettingsManager.getInstance().getComponentPosition(width, height); +// PickPileDialog.this.setLocation(centered.x, centered.y); +// GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, PickPileDialog.this); +// } +// PickPileDialog.this.setVisible(true); +// } +// }); + } + + private void btnPile1ActionPerformed(java.awt.event.ActionEvent evt) { + pickedPile1 = true; + this.hideDialog(); + } + + private void btnPile2ActionPerformed(java.awt.event.ActionEvent evt) { + pickedPile1 = false; + this.hideDialog(); + } + + public boolean isPickedPile1() { + return this.pickedPile1; + } +} diff --git a/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java index 1424c891cb7..94bb449f600 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java @@ -34,24 +34,22 @@ package mage.client.dialog; -import mage.cards.CardDimensions; -import mage.cards.MageCard; -import mage.client.MageFrame; -import mage.client.cards.BigCard; -import mage.client.plugins.impl.Plugins; -import mage.client.util.Config; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; -import mage.view.AbilityView; -import mage.view.CardView; -import mage.view.CardsView; - -import javax.swing.*; -import java.awt.*; +import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.UUID; + +import javax.swing.JLayeredPane; +import javax.swing.SwingUtilities; + +import mage.cards.CardDimensions; +import mage.client.MageFrame; +import mage.client.cards.BigCard; +import mage.client.cards.CardArea; import mage.client.util.CardsViewUtil; +import mage.client.util.SettingsManager; +import mage.client.util.gui.GuiDisplayUtil; +import mage.view.CardsView; import mage.view.SimpleCardsView; /** @@ -76,12 +74,7 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { public void loadCards(String name, CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean modal) { this.reloaded = true; this.title = name; - cardArea.removeAll(); - if (showCards != null && showCards.size() < 10) - loadCardsFew(showCards, bigCard, gameId); - else - loadCardsMany(showCards, bigCard, gameId); - cardArea.revalidate(); + cardArea.loadCards(showCards, bigCard, dimension, gameId); if (getParent() != MageFrame.getDesktop() /*|| this.isClosed*/) { MageFrame.getDesktop().add(this, JLayeredPane.POPUP_LAYER); } @@ -106,55 +99,6 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { }); } - private void loadCardsFew(CardsView showCards, BigCard bigCard, UUID gameId) { - Rectangle rectangle = new Rectangle(Config.dimensions.frameWidth, Config.dimensions.frameHeight); - Dimension dimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); - for (CardView card : showCards.values()) { - addCard(card, bigCard, gameId, rectangle, dimension); - rectangle.translate(Config.dimensions.frameWidth, 0); - } - cardArea.setPreferredSize(new Dimension(Config.dimensions.frameWidth * showCards.size(), Config.dimensions.frameHeight)); - } - - private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle, Dimension dimension) { - if (card instanceof AbilityView) { - CardView tmp = ((AbilityView) card).getSourceCard(); - tmp.overrideRules(card.getRules()); - tmp.setIsAbility(true); - tmp.overrideTargets(card.getTargets()); - tmp.setAbility(card); // cross-reference, required for ability picker - card = tmp; - } - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId, true); - cardImg.setBounds(rectangle); - cardArea.add(cardImg); - cardArea.moveToFront(cardImg); - cardImg.update(card); - cardImg.addMouseListener(this); - cardImg.setCardBounds(rectangle.x, rectangle.y, Config.dimensions.frameWidth, Config.dimensions.frameHeight); - } - - private void loadCardsMany(CardsView showCards, BigCard bigCard, UUID gameId) { - int columns = 1; - if (showCards != null && showCards.size() > 0) { - Rectangle rectangle = new Rectangle(Config.dimensions.frameWidth, Config.dimensions.frameHeight); - Dimension dimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); - int count = 0; - for (CardView card : showCards.values()) { - addCard(card, bigCard, gameId, rectangle, dimension); - if (count >= 20) { - rectangle.translate(Config.dimensions.frameWidth, -400); - columns++; - count = 0; - } else { - rectangle.translate(0, 20); - count++; - } - } - } - cardArea.setPreferredSize(new Dimension(Config.dimensions.frameWidth * columns, Config.dimensions.frameHeight + 400)); - } - public boolean isReloaded() { return this.reloaded; } @@ -163,34 +107,19 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { this.reloaded = false; } - /** - * This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents private void initComponents() { - jScrollPane1 = new javax.swing.JScrollPane(); - cardArea = new javax.swing.JLayeredPane(); + cardArea = new CardArea(); setClosable(true); setResizable(true); getContentPane().setLayout(new java.awt.BorderLayout()); - - jScrollPane1.setViewportView(cardArea); - - getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER); + getContentPane().add(cardArea, java.awt.BorderLayout.CENTER); pack(); - }// //GEN-END:initComponents - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLayeredPane cardArea; - private javax.swing.JScrollPane jScrollPane1; - // End of variables declaration//GEN-END:variables + } + + private CardArea cardArea; @Override public void mouseClicked(MouseEvent e) { diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index 6054c11fc93..321c7a474d6 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -34,9 +34,23 @@ package mage.client.game; +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import javax.swing.*; +import javax.swing.border.LineBorder; import mage.Constants; import mage.client.MageFrame; import mage.client.chat.ChatPanel; +import mage.client.components.MageComponents; import mage.client.dialog.*; import mage.client.game.FeedbackPanel.FeedbackMode; import mage.client.plugins.impl.Plugins; @@ -47,20 +61,6 @@ import mage.remote.Session; import mage.view.*; import org.apache.log4j.Logger; -import javax.swing.*; -import javax.swing.border.LineBorder; -import java.awt.*; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.Serializable; -import java.util.*; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import mage.client.components.MageComponents; -import javax.swing.GroupLayout.Alignment; -import javax.swing.LayoutStyle.ComponentPlacement; /** * @@ -539,11 +539,6 @@ public class GamePanel extends javax.swing.JPanel { this.abilityPicker.show(choices, MageFrame.getDesktop().getMousePosition()); } -// public void revealCards(String name, CardsView cards) { -// ShowCardsDialog showCards = new ShowCardsDialog(); -// showCards.loadCards(name, cards, bigCard, Config.dimensions, gameId, false); -// } -// private ShowCardsDialog showCards(String title, CardsView cards, boolean required) { ShowCardsDialog showCards = new ShowCardsDialog(); showCards.loadCards(title, cards, bigCard, Config.dimensions, gameId, required); @@ -564,6 +559,12 @@ public class GamePanel extends javax.swing.JPanel { session.sendPlayerString(gameId, pickChoice.getChoice()); } + public void pickPile(String message, CardsView pile1, CardsView pile2) { + PickPileDialog pickPileDialog = new PickPileDialog(); + pickPileDialog.loadCards(message, pile1, pile2, bigCard, Config.dimensions, gameId); + session.sendPlayerBoolean(gameId, pickPileDialog.isPickedPile1()); + } + public Map getPlayers() { return players; } @@ -996,8 +997,8 @@ public class GamePanel extends javax.swing.JPanel { private JButton endOfTurn; private JButton prevStep; private JLabel endButtonTip; -} +} class ReplayTask extends SwingWorker> { private Session session; diff --git a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java index ed6b60f46bf..c4f30db2de2 100644 --- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java +++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java @@ -28,6 +28,7 @@ package mage.client.remote; +import java.util.List; import mage.cards.decks.Deck; import mage.client.MageFrame; import mage.client.chat.ChatPanel; @@ -173,6 +174,12 @@ public class CallbackClientImpl implements CallbackClient { if (panel != null) panel.pickAbility((AbilityPickerView) callback.getData()); } + else if (callback.getMethod().equals("gameChoosePile")) { + GameClientMessage message = (GameClientMessage) callback.getData(); + GamePanel panel = frame.getGame(callback.getObjectId()); + if (panel != null) + panel.pickPile(message.getMessage(), message.getPile1(), message.getPile2()); + } else if (callback.getMethod().equals("gameChoose")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = frame.getGame(callback.getObjectId()); diff --git a/Mage.Common/src/mage/view/CardsView.java b/Mage.Common/src/mage/view/CardsView.java index 8cc127eb7ef..63d079a7194 100644 --- a/Mage.Common/src/mage/view/CardsView.java +++ b/Mage.Common/src/mage/view/CardsView.java @@ -45,7 +45,7 @@ public class CardsView extends HashMap { public CardsView() {} - public CardsView(Collection cards) { + public CardsView(Collection cards) { for (Card card: cards) { this.put(card.getId(), new CardView(card)); } diff --git a/Mage.Common/src/mage/view/GameClientMessage.java b/Mage.Common/src/mage/view/GameClientMessage.java index cb437bb13e6..0bf124e68ce 100644 --- a/Mage.Common/src/mage/view/GameClientMessage.java +++ b/Mage.Common/src/mage/view/GameClientMessage.java @@ -42,6 +42,7 @@ public class GameClientMessage implements Serializable { private GameView gameView; private CardsView cardsView; + private CardsView cardsView2; private String message; private AbilityPickerView abilityView; private boolean flag; @@ -83,6 +84,12 @@ public class GameClientMessage implements Serializable { this.min = min; this.max = max; } + + public GameClientMessage(String message, CardsView pile1, CardsView pile2) { + this.message = message; + this.cardsView = pile1; + this.cardsView2 = pile2; + } public GameClientMessage(CardsView cardView, String name) { this.cardsView = cardView; @@ -117,6 +124,14 @@ public class GameClientMessage implements Serializable { return targets; } + public CardsView getPile1() { + return cardsView; + } + + public CardsView getPile2() { + return cardsView2; + } + public int getMin() { return min; } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 4854322a873..fa7df354354 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -866,6 +866,12 @@ public class ComputerPlayer> extends PlayerImpl i return true; } + @Override + public boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game) { + //TODO: improve this + return true; + } + @Override public void selectAttackers(Game game) { log.debug("selectAttackers"); diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java index eb088dbc126..66ab3381d42 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java @@ -310,48 +310,40 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { @Override public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) { -// if (this.isHuman()) - return chooseRandomTarget(target, source, game); -// return super.chooseTarget(outcome, target, source, game); + return chooseRandomTarget(target, source, game); } @Override public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) { -// if (this.isHuman()) { - if (cards.isEmpty()) - return !target.isRequired(); - Card card = cards.getRandom(game); - target.addTarget(card.getId(), source, game); - return true; -// } -// return super.chooseTarget(outcome, cards, target, source, game); + if (cards.isEmpty()) + return !target.isRequired(); + Card card = cards.getRandom(game); + target.addTarget(card.getId(), source, game); + return true; } @Override public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { -// if (this.isHuman()) { - Set possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); - if (possibleTargets.isEmpty()) - return !target.isRequired(); - if (!target.isRequired()) { - if (rnd.nextInt(possibleTargets.size() + 1) == 0) { - return false; - } + Set possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); + if (possibleTargets.isEmpty()) + return !target.isRequired(); + if (!target.isRequired()) { + if (rnd.nextInt(possibleTargets.size() + 1) == 0) { + return false; } - if (possibleTargets.size() == 1) { - target.addTarget(possibleTargets.iterator().next(), target.getAmountRemaining(), source, game); - return true; - } - Iterator it = possibleTargets.iterator(); - int targetNum = rnd.nextInt(possibleTargets.size()); - UUID targetId = it.next(); - for (int i = 0; i < targetNum; i++) { - targetId = it.next(); - } - target.addTarget(targetId, rnd.nextInt(target.getAmountRemaining()) + 1, source, game); + } + if (possibleTargets.size() == 1) { + target.addTarget(possibleTargets.iterator().next(), target.getAmountRemaining(), source, game); return true; -// } -// return super.chooseTargetAmount(outcome, target, source, game); + } + Iterator it = possibleTargets.iterator(); + int targetNum = rnd.nextInt(possibleTargets.size()); + UUID targetId = it.next(); + for (int i = 0; i < targetNum; i++) { + targetId = it.next(); + } + target.addTarget(targetId, rnd.nextInt(target.getAmountRemaining()) + 1, source, game); + return true; } @Override @@ -366,6 +358,13 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { return super.chooseUse(outcome, message, game); } + @Override + public boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game) { + if (this.isHuman()) + return rnd.nextBoolean(); + return super.choosePile(outcome, message, pile1, pile2, game); + } + @Override public boolean choose(Outcome outcome, Choice choice, Game game) { if (this.isHuman()) { diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index cfc42e2c4fd..acf26ea453e 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -674,7 +674,17 @@ public class HumanPlayer extends PlayerImpl { return modes.getMode(); } - @Override + @Override + public boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game) { + game.getState().setPriorityPlayerId(getId()); + game.fireChoosePileEvent(playerId, message, pile1, pile2); + waitForBooleanResponse(); + if (!abort) + return response.getBoolean(); + return false; + } + + @Override public void setResponseString(String responseString) { synchronized(response) { response.setString(responseString); diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index e4aed71cd6f..a8d903b6402 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -153,6 +153,9 @@ public class GameController implements GameCallback { case CHOOSE_ABILITY: chooseAbility(event.getPlayerId(), event.getAbilities()); break; + case CHOOSE_PILE: + choosePile(event.getPlayerId(), event.getMessage(), event.getPile1(), event.getPile2()); + break; case CHOOSE_MODE: chooseMode(event.getPlayerId(), event.getModes()); break; @@ -387,6 +390,14 @@ public class GameController implements GameCallback { }); } + private synchronized void choosePile(UUID playerId, final String message, final List pile1, final List pile2) throws MageException { + perform(playerId, new Command() { + public void execute(UUID playerId) { + gameSessions.get(playerId).choosePile(message, new CardsView(pile1), new CardsView(pile2)); + } + }); + } + private synchronized void chooseMode(UUID playerId, final Map modes) throws MageException { perform(playerId, new Command() { public void execute(UUID playerId) { diff --git a/Mage.Server/src/main/java/mage/server/game/GameSession.java b/Mage.Server/src/main/java/mage/server/game/GameSession.java index d9b29398738..bb0621e9e40 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameSession.java +++ b/Mage.Server/src/main/java/mage/server/game/GameSession.java @@ -110,6 +110,19 @@ public class GameSession extends GameWatcher { } } + public void choosePile(final String message, final CardsView pile1, final CardsView pile2) { + if (!killed) { + setupTimeout(); + User user = UserManager.getInstance().getUser(userId); + if (user != null) { + List piles = new ArrayList(); + piles.add(pile1); + piles.add(pile2); + user.fireCallback(new ClientCallback("gameChoosePile", game.getId(), new GameClientMessage(message, pile1, pile2))); + } + } + } + public void choose(final String message, final Set choices) { if (!killed) { setupTimeout(); diff --git a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java index 5a58184ef4a..a37ef7b2c21 100644 --- a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java +++ b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java @@ -27,6 +27,7 @@ */ package mage.sets.innistrad; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.Constants.CardType; @@ -47,11 +48,13 @@ import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.counters.CounterType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; +import mage.target.TargetPermanent; import mage.target.TargetPlayer; /** @@ -112,69 +115,64 @@ class LilianaOfTheVeilEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(source.getFirstTarget()); if (player != null && targetPlayer != null) { - List permanents = game.getBattlefield().getAllActivePermanents(targetPlayer.getId()); - CardsImpl cards = new CardsImpl(); - for (Permanent permanent : permanents) { - cards.add(permanent); - } - - TargetCard target = new TargetCard(0, cards.size(), Zone.BATTLEFIELD, new FilterCard("permanents to put in the first pile")); - CardsImpl pile1 = new CardsImpl(); - if (player.choose(Outcome.Neutral, cards, target, game)) { + int count = game.getBattlefield().countAll(new FilterPermanent(), targetPlayer.getId()); + TargetPermanent target = new TargetPermanent(0, count, new FilterPermanent("permanents to put in the first pile"), false); + List pile1 = new ArrayList(); + if (player.choose(Outcome.Neutral, target, source.getSourceId(), game)) { List targets = target.getTargets(); for (UUID targetId : targets) { - Card card = cards.get(targetId, game); - if (card != null) { - pile1.add(card); - cards.remove(card); + Permanent p = game.getPermanent(targetId); + if (p != null) { + pile1.add(p); } } } - - player.revealCards("Pile 1 (Liliana of the Veil)", pile1, game); - player.revealCards("Pile 2 (Liliana of the Veil)", cards, game); - - Choice choice = createChoice(pile1, cards, game); - if (targetPlayer.choose(Outcome.Neutral, choice, game)) { - if (choice.getChoice().startsWith("Pile 1")) { - sacrificePermanents(pile1, game, source); - } else { - sacrificePermanents(cards, game, source); + List pile2 = new ArrayList(); + for (Permanent p: game.getBattlefield().getAllActivePermanents(targetPlayer.getId())) { + if (!pile1.contains(p)) { + pile2.add(p); } } + boolean choice = targetPlayer.choosePile(Outcome.DestroyPermanent, "Choose a pile to sacrifice.", pile1, pile2, game); + + if (choice) { + sacrificePermanents(pile1, game, source); + } else { + sacrificePermanents(pile2, game, source); + } + return true; } return false; } - private Choice createChoice(CardsImpl pile1, CardsImpl cards, Game game) { - Choice choice = new ChoiceImpl(true); - choice.setMessage("Select a pile of permanents to sacrifice:"); - StringBuilder sb = new StringBuilder("Pile 1: "); - for (UUID cardId : pile1) { - Card card = pile1.get(cardId, game); - if (card != null) { - sb.append(card.getName()).append("; "); - } - } - sb.delete(sb.length() - 2, sb.length()); - choice.getChoices().add(sb.toString()); - sb = new StringBuilder("Pile 2: "); - for (UUID cardId : cards) { - Card card = cards.get(cardId, game); - if (card != null) { - sb.append(card.getName()).append("; "); - } - } - sb.delete(sb.length() - 2, sb.length()); - choice.getChoices().add(sb.toString()); - return choice; - } +// private Choice createChoice(CardsImpl pile1, CardsImpl cards, Game game) { +// Choice choice = new ChoiceImpl(true); +// choice.setMessage("Select a pile of permanents to sacrifice:"); +// StringBuilder sb = new StringBuilder("Pile 1: "); +// for (UUID cardId : pile1) { +// Card card = pile1.get(cardId, game); +// if (card != null) { +// sb.append(card.getName()).append("; "); +// } +// } +// sb.delete(sb.length() - 2, sb.length()); +// choice.getChoices().add(sb.toString()); +// sb = new StringBuilder("Pile 2: "); +// for (UUID cardId : cards) { +// Card card = cards.get(cardId, game); +// if (card != null) { +// sb.append(card.getName()).append("; "); +// } +// } +// sb.delete(sb.length() - 2, sb.length()); +// choice.getChoices().add(sb.toString()); +// return choice; +// } - private void sacrificePermanents(CardsImpl pile1, Game game, Ability source) { - for (UUID permanentId : pile1) { - Permanent permanent = game.getPermanent(permanentId); + private void sacrificePermanents(List pile, Game game, Ability source) { + for (Permanent permanent : pile) { if (permanent != null) { permanent.sacrifice(source.getSourceId(), game); } diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 78b151f437b..b971334566d 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -136,7 +136,7 @@ public interface Game extends MageItem, Serializable { public void fireGetChoiceEvent(UUID playerId, String message, Collection choices); public void fireGetModeEvent(UUID playerId, String message, Map modes); public void fireGetAmountEvent(UUID playerId, String message, int min, int max); - public void fireChoosePileEvent(UUID playerId, List pile1, List pile2); + public void fireChoosePileEvent(UUID playerId, String message, List pile1, List pile2); public void fireInformEvent(String message); public void fireUpdatePlayersEvent(); public void informPlayers(String message); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 25fbbcb0527..b45d2883064 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1032,9 +1032,9 @@ public abstract class GameImpl> implements Game, Serializa } @Override - public void fireChoosePileEvent(UUID playerId, List pile1, List pile2) { + public void fireChoosePileEvent(UUID playerId, String message, List pile1, List pile2) { if (simulation) return; - //playerQueryEventSource.choosePile(playerId, pile1, pile2); + playerQueryEventSource.choosePile(playerId, message, pile1, pile2); } @Override diff --git a/Mage/src/mage/game/events/PlayerQueryEvent.java b/Mage/src/mage/game/events/PlayerQueryEvent.java index 184f678ba20..2e737c82e2c 100644 --- a/Mage/src/mage/game/events/PlayerQueryEvent.java +++ b/Mage/src/mage/game/events/PlayerQueryEvent.java @@ -30,10 +30,8 @@ package mage.game.events; import java.io.Serializable; import java.util.*; - import mage.abilities.Ability; import mage.abilities.ActivatedAbility; -import mage.abilities.TriggeredAbilities; import mage.abilities.TriggeredAbility; import mage.cards.Card; import mage.cards.Cards; @@ -46,7 +44,7 @@ import mage.game.permanent.Permanent; public class PlayerQueryEvent extends EventObject implements ExternalEvent, Serializable { public enum QueryType { - ASK, CHOOSE, CHOOSE_ABILITY, CHOOSE_MODE, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT, LOOK, PICK_CARD, CONSTRUCT + ASK, CHOOSE, CHOOSE_ABILITY, CHOOSE_MODE, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT, LOOK, PICK_CARD, CONSTRUCT, CHOOSE_PILE } private String message; @@ -63,6 +61,9 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri private int max; private Map options; private Map modes; + private List pile1; + private List pile2; + private PlayerQueryEvent(UUID playerId, String message, Collection abilities, Set choices, Set targets, Cards cards, QueryType queryType, int min, int max, boolean required, Map options) { this(playerId, message, abilities, choices, targets, cards, queryType, min, max, required); @@ -116,6 +117,15 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri this.playerId = playerId; this.modes = modes; } + + private PlayerQueryEvent(UUID playerId, String message, List pile1, List pile2) { + super(playerId); + this.queryType = QueryType.CHOOSE_PILE; + this.message = message; + this.playerId = playerId; + this.pile1 = pile1; + this.pile2 = pile2; + } public static PlayerQueryEvent askEvent(UUID playerId, String message) { return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false); @@ -125,7 +135,11 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri return new PlayerQueryEvent(playerId, message, choices, null, null, null, QueryType.CHOOSE_ABILITY, 0, 0, false); } - public static PlayerQueryEvent chooseModeEvent(UUID playerId, String message, Map modes) { + public static PlayerQueryEvent choosePileEvent(UUID playerId, String message, List pile1, List pile2) { + return new PlayerQueryEvent(playerId, message, pile1, pile2); + } + + public static PlayerQueryEvent chooseModeEvent(UUID playerId, String message, Map modes) { return new PlayerQueryEvent(playerId, message, modes); } @@ -237,4 +251,13 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri public Map getModes() { return modes; } + + public List getPile1() { + return pile1; + } + + public List getPile2() { + return pile2; + } + } diff --git a/Mage/src/mage/game/events/PlayerQueryEventSource.java b/Mage/src/mage/game/events/PlayerQueryEventSource.java index fb345d7f532..92d1e4f579b 100644 --- a/Mage/src/mage/game/events/PlayerQueryEventSource.java +++ b/Mage/src/mage/game/events/PlayerQueryEventSource.java @@ -62,6 +62,10 @@ public class PlayerQueryEventSource implements EventSource, Se dispatcher.fireEvent(PlayerQueryEvent.chooseAbilityEvent(playerId, message, choices)); } + public void choosePile(UUID playerId, String message, List pile1, List pile2) { + dispatcher.fireEvent(PlayerQueryEvent.choosePileEvent(playerId, message, pile1, pile2)); + } + public void chooseMode(UUID playerId, String message, Map modes) { dispatcher.fireEvent(PlayerQueryEvent.chooseModeEvent(playerId, message, modes)); } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 334c7c19d6a..8f6d9a883da 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -219,6 +219,7 @@ public interface Player extends MageItem, Copyable { public abstract boolean chooseMulligan(Game game); public abstract boolean chooseUse(Outcome outcome, String message, Game game); public abstract boolean choose(Outcome outcome, Choice choice, Game game); + public abstract boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game); public abstract boolean playMana(ManaCost unpaid, Game game); public abstract boolean playXMana(VariableManaCost cost, ManaCosts costs, Game game); public abstract int chooseEffect(List rEffects, Game game);