diff --git a/Mage.Client/src/main/java/mage/client/cards/Card.java b/Mage.Client/src/main/java/mage/client/cards/Card.java index ca322655e8..1ef0d5c415 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Card.java +++ b/Mage.Client/src/main/java/mage/client/cards/Card.java @@ -1,45 +1,84 @@ /* -* Copyright 2010 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. -*/ + * Copyright 2010 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. + */ /* * Card.java * * Created on 17-Dec-2009, 9:20:50 PM */ - package mage.client.cards; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.Popup; +import javax.swing.PopupFactory; +import javax.swing.text.BadLocationException; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import javax.swing.text.StyledDocument; import mage.cards.CardDimensions; import mage.cards.MagePermanent; import mage.cards.Sets; import mage.cards.TextPopup; import mage.cards.action.ActionCallback; import mage.client.MageFrame; +import static mage.client.constants.Constants.CONTENT_MAX_XOFFSET; +import static mage.client.constants.Constants.FRAME_MAX_HEIGHT; +import static mage.client.constants.Constants.FRAME_MAX_WIDTH; +import static mage.client.constants.Constants.NAME_FONT_MAX_SIZE; +import static mage.client.constants.Constants.NAME_MAX_YOFFSET; +import static mage.client.constants.Constants.POWBOX_TEXT_MAX_LEFT; +import static mage.client.constants.Constants.POWBOX_TEXT_MAX_TOP; +import static mage.client.constants.Constants.SYMBOL_MAX_XOFFSET; +import static mage.client.constants.Constants.SYMBOL_MAX_YOFFSET; +import static mage.client.constants.Constants.TYPE_MAX_YOFFSET; import mage.client.game.PlayAreaPanel; import mage.client.util.Config; import mage.client.util.DefaultActionCallback; @@ -48,18 +87,11 @@ import mage.client.util.gui.ArrowBuilder; import mage.constants.CardType; import mage.constants.EnlargeMode; import mage.remote.Session; -import mage.view.*; - -import javax.swing.*; -import javax.swing.text.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import static mage.client.constants.Constants.*; +import mage.view.AbilityView; +import mage.view.CardView; +import mage.view.CounterView; +import mage.view.PermanentView; +import mage.view.StackAbilityView; /** * @@ -77,15 +109,18 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis protected final UUID gameId; protected final BigCard bigCard; protected CardView card; - protected Popup popup; - protected boolean popupShowing; + protected Popup tooltipPopup; + protected boolean tooltipShowing; - protected TextPopup popupText = new TextPopup(); + protected TextPopup tooltipText = new TextPopup(); protected BufferedImage background; protected BufferedImage image = new BufferedImage(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT, BufferedImage.TYPE_INT_RGB); protected BufferedImage small; protected String backgroundName; + // if this is set, it's opened if the user right clicks on the card panel + private JPopupMenu popupMenu; + /** * Creates new form Card * @@ -126,7 +161,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void update(PermanentView permanent) { - this.update((CardView)permanent); + this.update((CardView) permanent); } @Override @@ -141,7 +176,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis background = ImageHelper.getBackground(card, backgroundName); } - popupText.setText(getText(cardType)); + tooltipText.setText(getText(cardType)); gImage.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gImage.setColor(Color.BLACK); @@ -159,8 +194,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis gImage.drawString(card.getName(), CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET); if (card.getCardTypes().contains(CardType.CREATURE)) { gImage.drawString(card.getPower() + "/" + card.getToughness(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP); - } - else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { + } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { gImage.drawString(card.getLoyalty(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP); } @@ -174,8 +208,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis gSmall.drawString(card.getName(), Config.dimensions.contentXOffset, Config.dimensions.nameYOffset); if (card.getCardTypes().contains(CardType.CREATURE)) { gSmall.drawString(card.getPower() + "/" + card.getToughness(), Config.dimensions.powBoxTextLeft, Config.dimensions.powBoxTextTop); - } - else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { + } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { gSmall.drawString(card.getLoyalty(), Config.dimensions.powBoxTextLeft, Config.dimensions.powBoxTextTop); } @@ -194,11 +227,10 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis protected String getText(String cardType) { StringBuilder sb = new StringBuilder(); if (card instanceof StackAbilityView || card instanceof AbilityView) { - for (String rule: getRules()) { + for (String rule : getRules()) { sb.append("\n").append(rule); } - } - else { + } else { sb.append(card.getName()); if (card.getManaCost().size() > 0) { sb.append("\n").append(card.getManaCost()); @@ -209,11 +241,10 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis } if (card.getCardTypes().contains(CardType.CREATURE)) { sb.append("\n").append(card.getPower()).append("/").append(card.getToughness()); - } - else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { + } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { sb.append("\n").append(card.getLoyalty()); } - for (String rule: getRules()) { + for (String rule : getRules()) { sb.append("\n").append(rule); } if (card.getExpansionSetCode() != null && card.getExpansionSetCode().length() > 0) { @@ -233,8 +264,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis StringBuilder sb = new StringBuilder(); if (card.getCardTypes().contains(CardType.LAND)) { sb.append("land").append(card.getSuperTypes()).append(card.getSubTypes()); - } - else if (card.getCardTypes() != null && (card.getCardTypes().contains(CardType.CREATURE) || card.getCardTypes().contains(CardType.PLANESWALKER))) { + } else if (card.getCardTypes() != null && (card.getCardTypes().contains(CardType.CREATURE) || card.getCardTypes().contains(CardType.PLANESWALKER))) { sb.append("creature"); } sb.append(card.getColor()).append(card.getRarity()).append(card.getExpansionSetCode()); @@ -246,10 +276,11 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis StyledDocument doc = text.getStyledDocument(); try { - for (String rule: getRules()) { + for (String rule : getRules()) { doc.insertString(doc.getLength(), rule + "\n", doc.getStyle("small")); } - } catch (BadLocationException e) {} + } catch (BadLocationException e) { + } text.setCaretPosition(0); } @@ -257,12 +288,11 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis protected List getRules() { if (card.getCounters() != null) { List rules = new ArrayList<>(card.getRules()); - for (CounterView counter: card.getCounters()) { + for (CounterView counter : card.getCounters()) { rules.add(counter.getCount() + " x " + counter.getName()); } return rules; - } - else { + } else { return card.getRules(); } } @@ -270,17 +300,17 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis protected String getType(CardView card) { StringBuilder sbType = new StringBuilder(); - for (String superType: card.getSuperTypes()) { + for (String superType : card.getSuperTypes()) { sbType.append(superType).append(" "); } - for (CardType cardType: card.getCardTypes()) { + for (CardType cardType : card.getCardTypes()) { sbType.append(cardType.toString()).append(" "); } if (card.getSubTypes().size() > 0) { sbType.append("- "); - for (String subType: card.getSubTypes()) { + for (String subType : card.getSubTypes()) { sbType.append(subType).append(" "); } } @@ -288,10 +318,10 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis return sbType.toString(); } - /** 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. + /** + * 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 @@ -343,7 +373,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void mouseMoved(MouseEvent arg0) { this.bigCard.showTextComponent(); - this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules()); + this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules()); } @Override @@ -362,18 +392,18 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void mouseEntered(MouseEvent arg0) { - if (!popupShowing) { - if (popup != null) { - popup.hide(); + if (!tooltipShowing) { + if (tooltipPopup != null) { + tooltipPopup.hide(); } PopupFactory factory = PopupFactory.getSharedInstance(); - popup = factory.getPopup(this, popupText, (int) this.getLocationOnScreen().getX() + Config.dimensions.frameWidth, (int) this.getLocationOnScreen().getY() + 40); - popup.show(); - //hack to get popup to resize to fit text - popup.hide(); - popup = factory.getPopup(this, popupText, (int) this.getLocationOnScreen().getX() + Config.dimensions.frameWidth, (int) this.getLocationOnScreen().getY() + 40); - popup.show(); - popupShowing = true; + tooltipPopup = factory.getPopup(this, tooltipText, (int) this.getLocationOnScreen().getX() + Config.dimensions.frameWidth, (int) this.getLocationOnScreen().getY() + 40); + tooltipPopup.show(); + //hack to get tooltipPopup to resize to fit text + tooltipPopup.hide(); + tooltipPopup = factory.getPopup(this, tooltipText, (int) this.getLocationOnScreen().getX() + Config.dimensions.frameWidth, (int) this.getLocationOnScreen().getY() + 40); + tooltipPopup.show(); + tooltipShowing = true; // Draw Arrows for targets List targets = card.getTargets(); @@ -383,14 +413,14 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis if (playAreaPanel != null) { Point target = playAreaPanel.getLocationOnScreen(); Point me = this.getLocationOnScreen(); - ArrowBuilder.getBuilder().addArrow(gameId, (int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() - 40, Color.red, ArrowBuilder.Type.TARGET); + ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() - 40, Color.red, ArrowBuilder.Type.TARGET); } else { for (PlayAreaPanel pa : MageFrame.getGame(gameId).getPlayers().values()) { MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid); if (permanent != null) { Point target = permanent.getLocationOnScreen(); Point me = this.getLocationOnScreen(); - ArrowBuilder.getBuilder().addArrow(gameId, (int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() + 10, Color.red, ArrowBuilder.Type.TARGET); + ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() + 10, Color.red, ArrowBuilder.Type.TARGET); } } } @@ -401,12 +431,12 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void mouseExited(MouseEvent arg0) { - if(getMousePosition(true) != null) { + if (getMousePosition(true) != null) { return; } - if (popup != null) { - popup.hide(); - popupShowing = false; + if (tooltipPopup != null) { + tooltipPopup.hide(); + tooltipShowing = false; ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.TARGET); ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.PAIRED); ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.SOURCE); @@ -421,8 +451,8 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void focusLost(FocusEvent arg0) { - if (popup != null) { - popup.hide(); + if (tooltipPopup != null) { + tooltipPopup.hide(); } this.repaint(); } @@ -437,42 +467,54 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis // End of variables declaration//GEN-END:variables @Override - public void componentResized(ComponentEvent e) { } + public void componentResized(ComponentEvent e) { + } @Override - public void componentMoved(ComponentEvent e) { } + public void componentMoved(ComponentEvent e) { + } @Override - public void componentShown(ComponentEvent e) { } + public void componentShown(ComponentEvent e) { + } @Override public void componentHidden(ComponentEvent e) { - if (popup != null) { - popup.hide(); + if (tooltipPopup != null) { + tooltipPopup.hide(); } } @Override - public List getLinks() {return null;} + public List getLinks() { + return null; + } @Override - public boolean isTapped() {return false;} + public boolean isTapped() { + return false; + } @Override - public boolean isFlipped() {return false;} + public boolean isFlipped() { + return false; + } @Override - public void onBeginAnimation() {} + public void onBeginAnimation() { + } @Override - public void onEndAnimation() {} + public void onEndAnimation() { + } @Override - public void setAlpha(float transparency) {} + public void setAlpha(float transparency) { + } @Override public CardView getOriginal() { - return card; + return card; } @Override @@ -539,6 +581,14 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis public void setTextOffset(int yOffset) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - - + + @Override + public JPopupMenu getPopupMenu() { + return popupMenu; + } + + @Override + public void setPopupMenu(JPopupMenu popupMenu) { + this.popupMenu = popupMenu; + } } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardArea.java b/Mage.Client/src/main/java/mage/client/cards/CardArea.java index 1d40d21f80..783724d1a4 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardArea.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardArea.java @@ -1,56 +1,64 @@ /* -* 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. -*/ - + * 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 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; -import org.mage.card.arcane.CardPanel; - -import javax.swing.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.List; import java.util.UUID; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import mage.cards.CardDimensions; +import mage.cards.MageCard; +import mage.client.plugins.impl.Plugins; +import mage.client.util.Config; +import mage.client.util.Event; +import mage.client.util.Listener; +import mage.view.AbilityView; +import mage.view.CardView; +import mage.view.CardsView; +import mage.view.SimpleCardView; +import org.mage.card.arcane.CardPanel; -public class CardArea extends JPanel { +public class CardArea extends JPanel implements MouseListener { + + protected CardEventSource cardEventSource = new CardEventSource(); private boolean reloaded = false; private final javax.swing.JLayeredPane cardArea; private final javax.swing.JScrollPane scrollPane; - private int yTextOffset; + private int yTextOffset; /** * Create the panel. @@ -68,28 +76,23 @@ public class CardArea extends JPanel { } public void cleanUp() { - for(Component comp: cardArea.getComponents()) { - if (comp instanceof CardPanel) { - ((CardPanel) comp).cleanUp(); - cardArea.remove(comp); - } - } - } - - public void loadCards(SimpleCardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, MouseListener listener) { - loadCards(CardsViewUtil.convertSimple(showCards), bigCard, dimension, gameId, listener); + for (Component comp : cardArea.getComponents()) { + if (comp instanceof CardPanel) { + ((CardPanel) comp).cleanUp(); + cardArea.remove(comp); + } + } } - public void loadCards(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, MouseListener listener) { + public void loadCards(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId) { this.reloaded = true; cardArea.removeAll(); if (showCards != null && showCards.size() < 10) { yTextOffset = 10; - loadCardsFew(showCards, bigCard, gameId, listener); - } - else { + loadCardsFew(showCards, bigCard, gameId); + } else { yTextOffset = 0; - loadCardsMany(showCards, bigCard, gameId, listener, dimension); + loadCardsMany(showCards, bigCard, gameId, dimension); } cardArea.revalidate(); @@ -97,28 +100,28 @@ public class CardArea extends JPanel { this.repaint(); } - public void loadCardsNarrow(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, MouseListener listener) { + public void loadCardsNarrow(CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId) { this.reloaded = true; cardArea.removeAll(); - yTextOffset = 0; - loadCardsMany(showCards, bigCard, gameId, listener, dimension); + yTextOffset = 0; + loadCardsMany(showCards, bigCard, gameId, dimension); cardArea.revalidate(); this.revalidate(); this.repaint(); } - private void loadCardsFew(CardsView showCards, BigCard bigCard, UUID gameId, MouseListener listener) { + 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, Config.dimensions, listener); + addCard(card, bigCard, gameId, rectangle, dimension, Config.dimensions); 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, CardDimensions cardDimensions, MouseListener listener) { + private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle, Dimension dimension, CardDimensions cardDimensions) { if (card instanceof AbilityView) { CardView tmp = ((AbilityView) card).getSourceCard(); tmp.overrideRules(card.getRules()); @@ -127,28 +130,26 @@ public class CardArea extends JPanel { tmp.setAbility(card); // cross-reference, required for ability picker card = tmp; } - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId, true); + MageCard cardPanel = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId, true); - cardImg.setBounds(rectangle); - if (listener != null) { - cardImg.addMouseListener(listener); - } - cardArea.add(cardImg); - cardArea.moveToFront(cardImg); - cardImg.update(card); - cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight); - cardImg.setTextOffset(yTextOffset); - cardImg.showCardTitle(); + cardPanel.setBounds(rectangle); + cardPanel.addMouseListener(this); + cardArea.add(cardPanel); + cardArea.moveToFront(cardPanel); + cardPanel.update(card); + cardPanel.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight); + cardPanel.setTextOffset(yTextOffset); + cardPanel.showCardTitle(); } - private void loadCardsMany(CardsView showCards, BigCard bigCard, UUID gameId, MouseListener listener, CardDimensions cardDimensions) { + private void loadCardsMany(CardsView showCards, BigCard bigCard, UUID gameId, CardDimensions cardDimensions) { int columns = 1; if (showCards != null && showCards.size() > 0) { Rectangle rectangle = new Rectangle(cardDimensions.frameWidth, cardDimensions.frameHeight); Dimension dimension = new Dimension(cardDimensions.frameWidth, cardDimensions.frameHeight); int count = 0; for (CardView card : showCards.values()) { - addCard(card, bigCard, gameId, rectangle, dimension, cardDimensions, listener); + addCard(card, bigCard, gameId, rectangle, dimension, cardDimensions); if (count >= 20) { rectangle.translate(cardDimensions.frameWidth, -400); columns++; @@ -169,11 +170,11 @@ public class CardArea extends JPanel { public void clearReloaded() { this.reloaded = false; } - + public void selectCards(List selected) { for (Component component : cardArea.getComponents()) { if (component instanceof MageCard) { - MageCard mageCard = (MageCard)component; + MageCard mageCard = (MageCard) component; if (selected.contains(mageCard.getOriginal().getId())) { mageCard.setSelected(true); } @@ -184,7 +185,7 @@ public class CardArea extends JPanel { public void markCards(List marked) { for (Component component : cardArea.getComponents()) { if (component instanceof MageCard) { - MageCard mageCard = (MageCard)component; + MageCard mageCard = (MageCard) component; if (marked.contains(mageCard.getOriginal().getId())) { mageCard.setChoosable(true); } @@ -192,4 +193,82 @@ public class CardArea extends JPanel { } } + public void setPopupMenu(JPopupMenu popupMenu) { + for (Component component : cardArea.getComponents()) { + if (component instanceof MageCard) { + MageCard mageCard = (MageCard) component; + mageCard.setPopupMenu(popupMenu); + } + } + } + + public void addCardEventListener(Listener listener) { + cardEventSource.addListener(listener); + } + + public void clearCardEventListeners() { + cardEventSource.clearListeners(); + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + if (e.getClickCount() >= 1 && !e.isConsumed()) { + Object obj = e.getSource(); + if (e.getClickCount() == 2) { + e.consume(); + if (obj instanceof Card) { + if (e.isAltDown()) { + cardEventSource.altDoubleClick(((Card) obj).getOriginal(), "alt-double-click"); + } else { + cardEventSource.doubleClick(((Card) obj).getOriginal(), "double-click"); + } + } else if (obj instanceof MageCard) { + if (e.isAltDown()) { + cardEventSource.altDoubleClick(((MageCard) obj).getOriginal(), "alt-double-click"); + } else { + cardEventSource.doubleClick(((MageCard) obj).getOriginal(), "double-click"); + } + } + } + if (obj instanceof MageCard) { + checkMenu(e, ((MageCard) obj).getOriginal()); + } else { + checkMenu(e, null); + } + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (!e.isConsumed()) { + Object obj = e.getSource(); + if (obj instanceof MageCard) { + checkMenu(e, ((MageCard) obj).getOriginal()); + } else { + checkMenu(e, null); + } + } else { + cardEventSource.actionConsumedEvent("action-consumed"); + } + } + + private void checkMenu(MouseEvent Me, SimpleCardView card) { + if (Me.isPopupTrigger()) { + Me.consume(); + cardEventSource.showPopupMenuEvent(card, Me.getComponent(), Me.getX(), Me.getY(), "show-popup-menu"); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java index 5aa243ffc1..01528dd06b 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java @@ -1,49 +1,48 @@ /* -* Copyright 2010 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. -*/ - + * Copyright 2010 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.Component; +import java.io.Serializable; import mage.client.util.Event; import mage.client.util.EventDispatcher; import mage.client.util.EventSource; import mage.client.util.Listener; import mage.view.SimpleCardView; -import java.io.Serializable; - /** * * @author BetaSteward_at_googlemail.com */ public class CardEventSource implements EventSource, Serializable { - protected final EventDispatcher dispatcher = new EventDispatcher() {}; + protected final EventDispatcher dispatcher = new EventDispatcher() { + }; @Override public void addListener(Listener listener) { @@ -74,6 +73,9 @@ public class CardEventSource implements EventSource, Serializable { dispatcher.fireEvent(new Event(card, message, x, y, component)); } + public void actionConsumedEvent(String message) { + dispatcher.fireEvent(new Event(null, message)); + } @Override public void clearListeners() { diff --git a/Mage.Client/src/main/java/mage/client/cards/Permanent.java b/Mage.Client/src/main/java/mage/client/cards/Permanent.java index e7401b39de..a01e368641 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Permanent.java +++ b/Mage.Client/src/main/java/mage/client/cards/Permanent.java @@ -254,20 +254,20 @@ public class Permanent extends Card { @Override public void mouseEntered(MouseEvent arg0) { - if (!popupShowing) { - if (popup != null) { - popup.hide(); + if (!tooltipShowing) { + if (tooltipPopup != null) { + tooltipPopup.hide(); } PopupFactory factory = PopupFactory.getSharedInstance(); int x = (int) this.getLocationOnScreen().getX() + (permanent.isTapped()?Config.dimensions.frameHeight:Config.dimensions.frameWidth); int y = (int) this.getLocationOnScreen().getY() + 40; - popup = factory.getPopup(this, popupText, x, y); - popup.show(); - //hack to get popup to resize to fit text - popup.hide(); - popup = factory.getPopup(this, popupText, x, y); - popup.show(); - popupShowing = true; + tooltipPopup = factory.getPopup(this, tooltipText, x, y); + tooltipPopup.show(); + //hack to get tooltipPopup to resize to fit text + tooltipPopup.hide(); + tooltipPopup = factory.getPopup(this, tooltipText, x, y); + tooltipPopup.show(); + tooltipShowing = true; } } diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java index d2e63313b4..698e14ea6c 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java @@ -1,33 +1,41 @@ /* -* 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. -*/ - + * 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.Component; +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 mage.cards.CardDimensions; import mage.client.MageFrame; import mage.client.cards.BigCard; @@ -35,18 +43,12 @@ import mage.client.cards.CardArea; import mage.client.util.SettingsManager; import mage.client.util.gui.GuiDisplayUtil; import mage.view.CardsView; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.UUID; import org.mage.card.arcane.CardPanel; /** -* -* @author BetaSteward_at_googlemail.com -*/ + * + * @author BetaSteward_at_googlemail.com + */ public class PickPileDialog extends MageDialog { private final CardArea pile1; @@ -94,24 +96,24 @@ public class PickPileDialog extends MageDialog { } public void cleanUp() { - for(Component comp: pile1.getComponents()) { - if (comp instanceof CardPanel) { - ((CardPanel) comp).cleanUp(); - pile1.remove(comp); - } - } - for(Component comp: pile2.getComponents()) { - if (comp instanceof CardPanel) { - ((CardPanel) comp).cleanUp(); - pile2.remove(comp); - } - } + for (Component comp : pile1.getComponents()) { + if (comp instanceof CardPanel) { + ((CardPanel) comp).cleanUp(); + pile1.remove(comp); + } + } + for (Component comp : pile2.getComponents()) { + if (comp instanceof CardPanel) { + ((CardPanel) comp).cleanUp(); + pile2.remove(comp); + } + } } - + 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, null); - this.pile2.loadCardsNarrow(pile2, bigCard, dimension, gameId, null); + 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.MODAL_LAYER); 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 3257c665cd..dffa208b6c 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ShowCardsDialog.java @@ -35,28 +35,28 @@ package mage.client.dialog; import java.awt.Component; import java.awt.Point; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.io.Serializable; import java.util.Map; import java.util.UUID; import javax.swing.JLayeredPane; +import javax.swing.JPopupMenu; 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.Event; +import mage.client.util.Listener; import mage.client.util.SettingsManager; import mage.client.util.gui.GuiDisplayUtil; +import mage.game.events.PlayerQueryEvent.QueryType; import mage.view.CardsView; -import mage.view.SimpleCardsView; import org.mage.card.arcane.CardPanel; /** * @author BetaSteward_at_googlemail.com */ -public class ShowCardsDialog extends MageDialog implements MouseListener { +public class ShowCardsDialog extends MageDialog { // remember if this dialog was already auto positioned, so don't do it after the first time private boolean positioned; @@ -83,18 +83,13 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { } } - public void loadCards(String name, SimpleCardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean modal) { - loadCards(name, CardsViewUtil.convertSimple(showCards), bigCard, dimension, gameId, modal); - } - - public void loadCards(String name, CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean modal) { - loadCards(name, showCards, bigCard, dimension, gameId, modal, null); - } - - public void loadCards(String name, CardsView showCards, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean modal, Map options) { + public void loadCards(String name, CardsView showCards, BigCard bigCard, + CardDimensions dimension, UUID gameId, boolean modal, Map options, + JPopupMenu popupMenu, Listener eventListener) { this.title = name; this.setTitelBarToolTip(name); - cardArea.loadCards(showCards, bigCard, dimension, gameId, this); + cardArea.clearCardEventListeners(); + cardArea.loadCards(showCards, bigCard, dimension, gameId); if (options != null) { if (options.containsKey("chosen")) { java.util.List chosenCards = (java.util.List) options.get("chosen"); @@ -104,6 +99,15 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { java.util.List choosableCards = (java.util.List) options.get("choosable"); cardArea.markCards(choosableCards); } + if (options.containsKey("queryType") && QueryType.PICK_ABILITY.equals(options.get("queryType"))) { + cardArea.setPopupMenu(popupMenu); + } + } + if (popupMenu != null) { + this.cardArea.setPopupMenu(popupMenu); + } + if (eventListener != null) { + this.cardArea.addCardEventListener(eventListener); } if (getParent() != MageFrame.getDesktop() /*|| this.isClosed*/) { @@ -141,38 +145,9 @@ public class ShowCardsDialog extends MageDialog implements MouseListener { setResizable(true); getContentPane().setLayout(new java.awt.BorderLayout()); getContentPane().add(cardArea, java.awt.BorderLayout.CENTER); - this.addMouseListener(this); pack(); } private CardArea cardArea; - - @Override - public void mouseClicked(MouseEvent e) { - if (e.getSource() instanceof CardPanel) { - this.hideDialog(); - } - } - - @Override - public void mousePressed(MouseEvent e) { - // only hide dialog, if a cardPanel was selected - if (e.getSource() instanceof CardPanel) { - this.hideDialog(); - } - } - - @Override - public void mouseReleased(MouseEvent e) { - } - - @Override - public void mouseEntered(MouseEvent e) { - } - - @Override - public void mouseExited(MouseEvent e) { - } - } diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 5752dbe8ec..31269b247f 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -326,7 +326,7 @@ public class DraftPanel extends javax.swing.JPanel { if (view != null) { loadCardsToPickedCardsArea(view.getPicks()); draftBooster.loadBooster(emptyView, bigCard); - Plugins.getInstance().getActionCallback().hidePopup(); + Plugins.getInstance().getActionCallback().hideTooltipPopup(); setMessage("Waiting for other players"); } } 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 2d172a6a33..aab803819d 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -66,8 +66,10 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLayeredPane; +import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.SwingWorker; import javax.swing.border.Border; @@ -100,7 +102,9 @@ import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.impl.Plugins; import mage.client.util.CardsViewUtil; import mage.client.util.Config; +import mage.client.util.Event; import mage.client.util.GameManager; +import mage.client.util.Listener; import mage.client.util.audio.AudioManager; import mage.client.util.gui.ArrowBuilder; import mage.client.util.gui.MageDialogState; @@ -118,7 +122,13 @@ import static mage.constants.PhaseStep.FIRST_COMBAT_DAMAGE; import static mage.constants.PhaseStep.UNTAP; import static mage.constants.PhaseStep.UPKEEP; import mage.constants.PlayerAction; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_FIRST; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_LAST; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_FIRST; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_LAST; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; import mage.constants.Zone; +import mage.game.events.PlayerQueryEvent; import mage.remote.Session; import mage.view.AbilityPickerView; import mage.view.CardView; @@ -131,6 +141,7 @@ import mage.view.PlayerView; import mage.view.RevealedView; import mage.view.SimpleCardsView; import org.apache.log4j.Logger; +import org.mage.card.arcane.CardPanel; import org.mage.plugins.card.utils.impl.ImageManagerImpl; /** @@ -143,6 +154,13 @@ public final class GamePanel extends javax.swing.JPanel { private static final String YOUR_HAND = "Your hand"; private static final int X_PHASE_WIDTH = 55; private static final int STACK_MIN_CARDS_OFFSET_Y = 7; + + private static final String CMD_AUTO_ORDER_FIRST = "cmdAutoOrderFirst"; + private static final String CMD_AUTO_ORDER_LAST = "cmdAutoOrderLast"; + private static final String CMD_AUTO_ORDER_NAME_FIRST = "cmdAutoOrderNameFirst"; + private static final String CMD_AUTO_ORDER_NAME_LAST = "cmdAutoOrderNameLast"; + private static final String CMD_AUTO_ORDER_RESET_ALL = "cmdAutoOrderResetAll"; + private final Map players = new HashMap<>(); // non modal frames @@ -174,9 +192,22 @@ public final class GamePanel extends javax.swing.JPanel { private MageDialogState choiceWindowState; + private enum PopUpMenuType { + + TRIGGER_ORDER + } + // CardView popupMenu was invoked last + private CardView cardViewPopupMenu; + + // popup menu for a card + private JPopupMenu popupMenuCardPanel; + public GamePanel() { initComponents(); + createTriggerOrderPupupMenu(); + this.add(popupMenuCardPanel); + pickNumber = new PickNumberDialog(); MageFrame.getDesktop().add(pickNumber, JLayeredPane.MODAL_LAYER); @@ -281,7 +312,7 @@ public final class GamePanel extends javax.swing.JPanel { pickTargetDialog.cleanUp(); pickTargetDialog.removeDialog(); } - Plugins.getInstance().getActionCallback().hidePopup(); + Plugins.getInstance().getActionCallback().hideTooltipPopup(); try { Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); popupContainer.setVisible(false); @@ -957,31 +988,37 @@ public final class GamePanel extends javax.swing.JPanel { * @param messageId */ public void pickTarget(String message, CardsView cardView, GameView gameView, Set targets, boolean required, Map options, int messageId) { - ShowCardsDialog dialog = null; - if (options != null && options.containsKey("targetZone")) { - if (Zone.HAND.equals(options.get("targetZone"))) { // mark selectable target cards in hand - List choosen = null; - if (options.containsKey("chosen")) { - choosen = (List) options.get("chosen"); - } - for (CardView card : gameView.getHand().values()) { - if (targets == null || targets.isEmpty()) { - card.setPlayable(false); - card.setChoosable(true); - } else if (targets.contains(card.getId())) { - card.setPlayable(false); - card.setChoosable(true); + PopUpMenuType popupMenuType = null; + if (options != null) { + if (options.containsKey("targetZone")) { + if (Zone.HAND.equals(options.get("targetZone"))) { // mark selectable target cards in hand + List choosen = null; + if (options.containsKey("chosen")) { + choosen = (List) options.get("chosen"); } - if (choosen != null && choosen.contains(card.getId())) { - card.setSelected(true); + for (CardView card : gameView.getHand().values()) { + if (targets == null || targets.isEmpty()) { + card.setPlayable(false); + card.setChoosable(true); + } else if (targets.contains(card.getId())) { + card.setPlayable(false); + card.setChoosable(true); + } + if (choosen != null && choosen.contains(card.getId())) { + card.setSelected(true); + } } } } + if (options.containsKey("queryType") && PlayerQueryEvent.QueryType.PICK_ABILITY.equals(options.get("queryType"))) { + popupMenuType = PopUpMenuType.TRIGGER_ORDER; + } } updateGame(gameView); Map options0 = options == null ? new HashMap() : options; + ShowCardsDialog dialog = null; if (cardView != null && cardView.size() > 0) { - dialog = showCards(message, cardView, required, options0); + dialog = showCards(message, cardView, required, options0, popupMenuType); options0.put("dialog", dialog); } this.feedbackPanel.getFeedback(required ? FeedbackMode.INFORM : FeedbackMode.CANCEL, message, gameView.getSpecial(), options0, messageId); @@ -1066,10 +1103,16 @@ public final class GamePanel extends javax.swing.JPanel { ((MageActionCallback) callback).hideGameUpdate(gameId); } - private ShowCardsDialog showCards(String title, CardsView cards, boolean required, Map options) { + private ShowCardsDialog showCards(String title, CardsView cards, boolean required, Map options, PopUpMenuType popupMenuType) { hideAll(); ShowCardsDialog showCards = new ShowCardsDialog(); - showCards.loadCards(title, cards, bigCard, Config.dimensionsEnlarged, gameId, required, options); + JPopupMenu popupMenu = null; + Listener eventListener = null; + if (PopUpMenuType.TRIGGER_ORDER.equals(popupMenuType)) { + popupMenu = getTriggerOrderPopupMenu(); + eventListener = getTriggerOrderEventListener(showCards); + } + showCards.loadCards(title, cards, bigCard, Config.dimensionsEnlarged, gameId, required, options, popupMenu, eventListener); return showCards; } @@ -1942,6 +1985,102 @@ public final class GamePanel extends javax.swing.JPanel { hoverButtons.put(name, button); } + // TriggerOrderPopupMenu + private Listener getTriggerOrderEventListener(final ShowCardsDialog dialog) { + return new Listener() { + @Override + public void event(Event event) { + if (event.getEventName().equals("show-popup-menu")) { + if (event.getComponent() != null && event.getComponent() instanceof CardPanel) { + JPopupMenu menu = ((CardPanel) event.getComponent()).getPopupMenu(); + if (menu != null) { + cardViewPopupMenu = ((CardView) event.getSource()); + menu.show(event.getComponent(), event.getxPos(), event.getyPos()); + } + } + } + if (event.getEventName().equals("action-consumed")) { + dialog.hideDialog(); + } + } + }; + } + + public void handleTriggerOrderPopupMenuEvent(ActionEvent e) { + UUID abilityId = null; + String abilityRuleText = null; + if (cardViewPopupMenu instanceof CardView && cardViewPopupMenu.getAbility() != null) { + abilityId = cardViewPopupMenu.getAbility().getId(); + if (!cardViewPopupMenu.getAbility().getRules().isEmpty() && !cardViewPopupMenu.getAbility().getRules().equals("")) { + abilityRuleText = cardViewPopupMenu.getAbility().getRules().get(0); + } + } + switch (e.getActionCommand()) { + case CMD_AUTO_ORDER_FIRST: + session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_FIRST, gameId, abilityId); + break; + case CMD_AUTO_ORDER_LAST: + session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_LAST, gameId, abilityId); + break; + case CMD_AUTO_ORDER_NAME_FIRST: + if (abilityRuleText != null) { + session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_FIRST, gameId, abilityRuleText); + } + break; + case CMD_AUTO_ORDER_NAME_LAST: + if (abilityRuleText != null) { + session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_LAST, gameId, abilityRuleText); + } + break; + case CMD_AUTO_ORDER_RESET_ALL: + session.sendPlayerAction(TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null); + break; + } + } + + public JPopupMenu getTriggerOrderPopupMenu() { + return popupMenuCardPanel; + } + + private void createTriggerOrderPupupMenu() { + + ActionListener actionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + handleTriggerOrderPopupMenuEvent(e); + } + }; + + popupMenuCardPanel = new JPopupMenu(); + + // String tooltipText = ""; + JMenuItem menuItem; + menuItem = new JMenuItem("Put this ability always first on the stack"); + menuItem.setActionCommand(CMD_AUTO_ORDER_FIRST); + menuItem.addActionListener(actionListener); + popupMenuCardPanel.add(menuItem); + + menuItem = new JMenuItem("Put this ability always last on the stack"); + menuItem.setActionCommand(CMD_AUTO_ORDER_LAST); + menuItem.addActionListener(actionListener); + popupMenuCardPanel.add(menuItem); + + menuItem = new JMenuItem("Put all abilities with that rule text always first on the stack"); + menuItem.setActionCommand(CMD_AUTO_ORDER_NAME_FIRST); + menuItem.addActionListener(actionListener); + popupMenuCardPanel.add(menuItem); + + menuItem = new JMenuItem("Put all abilities with that rule text always last on the stack"); + menuItem.setActionCommand(CMD_AUTO_ORDER_NAME_LAST); + menuItem.addActionListener(actionListener); + popupMenuCardPanel.add(menuItem); + + menuItem = new JMenuItem("Reset all order settings for triggered abilities"); + menuItem.setActionCommand(CMD_AUTO_ORDER_RESET_ALL); + menuItem.addActionListener(actionListener); + popupMenuCardPanel.add(menuItem); + } + public String getGameLog() { return gameChatPanel.getText(); } diff --git a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java index a3d2f246c4..cdf949d149 100644 --- a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java @@ -278,6 +278,18 @@ public class PlayAreaPanel extends javax.swing.JPanel { } }); + menuItem = new JMenuItem("Triggered abilities - reset auto stack order"); + menuItem.setMnemonic(KeyEvent.VK_T); + menuItem.setToolTipText("Deletes all triggered ability order settings you added during the game."); + automaticConfirmsMenu.add(menuItem); + // Reset the replacement effcts that were auto selected for the game + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + gamePanel.getSession().sendPlayerAction(PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null); + } + }); + JMenu handCardsMenu = new JMenu("Cards on hand"); handCardsMenu.setMnemonic(KeyEvent.VK_H); popupMenu.add(handCardsMenu); diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java index c55072a95f..2d7f70b7a2 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java +++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java @@ -65,12 +65,12 @@ public class MageActionCallback implements ActionCallback { public static final int MIN_X_OFFSET_REQUIRED = 20; - private Popup popup; + private Popup tooltipPopup; private JPopupMenu jPopupMenu; private BigCard bigCard; protected static final DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance(); protected static Session session = MageFrame.getSession(); - private CardView popupCard; + private CardView tooltipCard; private TransferData popupData; private JComponent cardInfoPane; private volatile boolean popupTextWindowOpen = false; @@ -92,7 +92,7 @@ public class MageActionCallback implements ActionCallback { private boolean isDragging; private Point initialCardPos; private Point initialMousePos; - private Set cardPanels = new HashSet(); + private final Set cardPanels = new HashSet<>(); public MageActionCallback() { enlargeMode = EnlargeMode.NORMAL; @@ -117,10 +117,10 @@ public class MageActionCallback implements ActionCallback { @Override public void mouseEntered(MouseEvent e, final TransferData data) { - hidePopup(); + hideTooltipPopup(); cancelTimeout(); - this.popupCard = data.card; + this.tooltipCard = data.card; this.popupData = data; Component parentComponent = SwingUtilities.getRoot(data.component); @@ -154,12 +154,12 @@ public class MageActionCallback implements ActionCallback { } data.locationOnScreen = data.component.getLocationOnScreen(); } - popup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40); - popup.show(); + tooltipPopup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40); + tooltipPopup.show(); // hack to get popup to resize to fit text - popup.hide(); - popup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40); - popup.show(); + tooltipPopup.hide(); + tooltipPopup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40); + tooltipPopup.show(); } else { sumbitShowPopupTask(data, parentComponent, parentPoint); } @@ -171,7 +171,7 @@ public class MageActionCallback implements ActionCallback { public void run() { ThreadUtils.sleep(300); - if (popupCard == null || !popupCard.equals(data.card) || session == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { + if (tooltipCard == null || !tooltipCard.equals(data.card) || session == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { return; } @@ -229,13 +229,15 @@ public class MageActionCallback implements ActionCallback { initialMousePos = new Point((int) mouse.getX(), (int) mouse.getY()); initialCardPos = data.component.getLocation(); // Closes popup & enlarged view if a card/Permanent is selected - hidePopup(); + hideTooltipPopup(); } @Override public void mouseReleased(MouseEvent e, TransferData transferData) { CardPanel card = ((CardPanel) transferData.component); - if (card.getZone() != null && card.getZone().equalsIgnoreCase("hand")) { + if (e.isPopupTrigger() /*&& card.getPopupMenu() != null*/) { + hideTooltipPopup(); + } else if (card.getZone() != null && card.getZone().equalsIgnoreCase("hand")) { int maxXOffset = 0; if (isDragging) { Point mouse = new Point(e.getX(), e.getY()); @@ -250,13 +252,15 @@ public class MageActionCallback implements ActionCallback { transferData.component.requestFocusInWindow(); defaultCallback.mouseClicked(e, transferData.gameId, session, transferData.card); // Closes popup & enlarged view if a card/Permanent is selected - hidePopup(); + hideTooltipPopup(); } + e.consume(); } else { transferData.component.requestFocusInWindow(); defaultCallback.mouseClicked(e, transferData.gameId, session, transferData.card); // Closes popup & enlarged view if a card/Permanent is selected - hidePopup(); + hideTooltipPopup(); + e.consume(); } } @@ -264,7 +268,7 @@ public class MageActionCallback implements ActionCallback { if (this.startedDragging && prevCard != null && card != null) { for (Component component : card.getCardArea().getComponents()) { if (component instanceof CardPanel) { - if (cardPanels.contains(component)) { + if (cardPanels.contains((CardPanel) component)) { component.setLocation(component.getLocation().x, component.getLocation().y - GO_DOWN_ON_DRAG_Y_OFFSET); } } @@ -323,7 +327,7 @@ public class MageActionCallback implements ActionCallback { for (Component component : container.getComponents()) { if (component instanceof CardPanel) { if (!component.equals(card)) { - if (!cardPanels.contains(component)) { + if (!cardPanels.contains((CardPanel) component)) { component.setLocation(component.getLocation().x, component.getLocation().y + GO_DOWN_ON_DRAG_Y_OFFSET); } cardPanels.add((CardPanel) component); @@ -405,10 +409,10 @@ public class MageActionCallback implements ActionCallback { * */ @Override - public void hidePopup() { - this.popupCard = null; - if (popup != null) { - popup.hide(); + public void hideTooltipPopup() { + this.tooltipCard = null; + if (tooltipPopup != null) { + tooltipPopup.hide(); } if (jPopupMenu != null) { jPopupMenu.setVisible(false); @@ -421,7 +425,7 @@ public class MageActionCallback implements ActionCallback { Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); popupContainer.setVisible(false); } catch (Exception e2) { - e2.printStackTrace(); + logger.warn("Can't set tooltip to visible = false", e2); } } @@ -433,7 +437,7 @@ public class MageActionCallback implements ActionCallback { } public void hideAll(UUID gameId) { - hidePopup(); + hideTooltipPopup(); startHideTimeout(); this.popupTextWindowOpen = false; if (gameId != null) { @@ -483,7 +487,7 @@ public class MageActionCallback implements ActionCallback { cardView = popupData.card; } if (this.popupTextWindowOpen) { - hidePopup(); + hideTooltipPopup(); } if (cardView != null) { if (cardView.isToRotate()) { @@ -506,7 +510,7 @@ public class MageActionCallback implements ActionCallback { cardPreviewContainer.setVisible(false); } catch (InterruptedException e) { - e.printStackTrace(); + logger.warn("Can't hide enlarged card", e); } } } @@ -582,7 +586,7 @@ public class MageActionCallback implements ActionCallback { } } catch (Exception e) { - e.printStackTrace(); + logger.warn("Problem dring display of enlarged card", e); } } }); diff --git a/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java b/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java index 6e35211152..b1f0a8774e 100644 --- a/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java +++ b/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java @@ -1,37 +1,36 @@ /* -* Copyright 2010 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. -*/ + * Copyright 2010 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. + */ /* * PlayerPanel.java * * Created on Nov 18, 2009, 3:01:31 PM */ - package mage.client.unusedFiles; //package mage.client.game; @@ -58,7 +57,9 @@ public class PlayerPanel extends javax.swing.JPanel { private ShowCardsDialog graveyard; private BigCard bigCard; - /** Creates new form PlayerPanel */ + /** + * Creates new form PlayerPanel + */ public PlayerPanel() { initComponents(); } @@ -79,19 +80,17 @@ public class PlayerPanel extends javax.swing.JPanel { this.btnPlayerName.setText(player.getName()); if (player.isActive()) { this.btnPlayerName.setBackground(Color.DARK_GRAY); - } - else if (player.hasLeft()) { + } else if (player.hasLeft()) { this.btnPlayerName.setBackground(Color.RED); - } - else { + } else { this.btnPlayerName.setBackground(Color.LIGHT_GRAY); } } - /** 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. + /** + * 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 @@ -201,10 +200,9 @@ public class PlayerPanel extends javax.swing.JPanel { if (graveyard == null) { graveyard = new ShowCardsDialog(); } - graveyard.loadCards(player.getName() + " graveyard", player.getGraveyard(), bigCard, Config.dimensions, gameId, false); + graveyard.loadCards(player.getName() + " graveyard", player.getGraveyard(), bigCard, Config.dimensions, gameId, false, null, null, null); }//GEN-LAST:event_btnGraveActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnGrave; private javax.swing.JButton btnPlayerName; diff --git a/Mage.Client/src/main/java/mage/client/util/Listener.java b/Mage.Client/src/main/java/mage/client/util/Listener.java index 8c7ce8dc99..6fb209b684 100644 --- a/Mage.Client/src/main/java/mage/client/util/Listener.java +++ b/Mage.Client/src/main/java/mage/client/util/Listener.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 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. -*/ - + * Copyright 2010 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.util; import java.io.Serializable; @@ -33,7 +32,9 @@ import java.io.Serializable; /** * * @author BetaSteward_at_googlemail.com + * @param */ public interface Listener extends Serializable { + void event(E event); } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index 774fea3adb..5f50c70956 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -29,6 +29,7 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import mage.cards.MagePermanent; import mage.cards.TextPopup; import mage.cards.action.ActionCallback; @@ -63,15 +64,16 @@ import org.mage.plugins.card.utils.impl.ImageManagerImpl; */ @SuppressWarnings({"unchecked", "rawtypes"}) public class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener { + private static final long serialVersionUID = -3272134219262184410L; - private static final Logger log = Logger.getLogger(CardPanel.class); + private static final Logger logger = Logger.getLogger(CardPanel.class); private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter public static final double TAPPED_ANGLE = Math.PI / 2; public static final double FLIPPED_ANGLE = Math.PI; public static final float ASPECT_RATIO = 3.5f / 2.5f; - public static final int POPUP_X_GAP = 1; // prevent popup window from blinking + public static final int POPUP_X_GAP = 1; // prevent tooltip window from blinking public static CardPanel dragAnimationPanel; @@ -120,7 +122,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private GlowText ptText; private boolean displayEnabled = true; private boolean isAnimationPanel; - public int cardXOffset, cardYOffset, cardWidth, cardHeight; + public int cardXOffset, cardYOffset, cardWidth, cardHeight; private boolean isSelected; private boolean isPlayable; @@ -132,8 +134,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private ActionCallback callback; - protected boolean popupShowing; - protected TextPopup popupText = new TextPopup(); + protected boolean tooltipShowing; + protected TextPopup tooltipText = new TextPopup(); protected UUID gameId; private TransferData data = new TransferData(); @@ -152,6 +154,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private int yTextOffset = 10; + // if this is set, it's opened if the user right clicks on the card panel + private JPopupMenu popupMenu; + public CardPanel(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) { this.gameCard = newGameCard; this.callback = callback; @@ -165,7 +170,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti //for container debug (don't remove) //setBorder(BorderFactory.createLineBorder(Color.green)); - if (this.gameCard.canTransform()) { buttonPanel = new JPanel(); buttonPanel.setLayout(null); @@ -222,14 +226,14 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } if (newGameCard.isAbility()) { if (AbilityType.TRIGGERED.equals(newGameCard.getAbilityType())) { - setTypeIcon(ImageManagerImpl.getInstance().getTriggeredAbilityImage(),"Triggered Ability"); + setTypeIcon(ImageManagerImpl.getInstance().getTriggeredAbilityImage(), "Triggered Ability"); } else if (AbilityType.ACTIVATED.equals(newGameCard.getAbilityType())) { - setTypeIcon(ImageManagerImpl.getInstance().getActivatedAbilityImage(),"Activated Ability"); + setTypeIcon(ImageManagerImpl.getInstance().getActivatedAbilityImage(), "Activated Ability"); } } if (this.gameCard.isToken()) { - setTypeIcon(ImageManagerImpl.getInstance().getTokenIconImage(),"Token Permanent"); + setTypeIcon(ImageManagerImpl.getInstance().getTokenIconImage(), "Token Permanent"); } // icon to inform about permanent is copying something @@ -299,7 +303,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti imagePanel.setScalingMultiPassType(MultipassType.none); String cardType = getType(newGameCard); - popupText.setText(getText(cardType, newGameCard)); + tooltipText.setText(getText(cardType, newGameCard)); Util.threadPool.submit(new Runnable() { @Override @@ -326,9 +330,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } setText(gameCard); } catch (Exception e) { - e.printStackTrace(); + logger.fatal("Problem during image animation", e); } catch (Error err) { - err.printStackTrace(); + logger.error("Problem during image animation", err); } } }); @@ -344,7 +348,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti typeButton.setLocation(2, 2); typeButton.setSize(25, 25); - iconPanel.setVisible(true); typeButton.setIcon(new ImageIcon(bufferedImage)); if (toolTipText != null) { @@ -355,17 +358,17 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti public void cleanUp() { if (dayNightButton != null) { - for(ActionListener al: dayNightButton.getActionListeners()) { + for (ActionListener al : dayNightButton.getActionListeners()) { dayNightButton.removeActionListener(al); } } - for(MouseListener ml: this.getMouseListeners() ){ + for (MouseListener ml : this.getMouseListeners()) { this.removeMouseListener(ml); } - for(MouseMotionListener ml: this.getMouseMotionListeners() ){ + for (MouseMotionListener ml : this.getMouseMotionListeners()) { this.removeMouseMotionListener(ml); } - for(MouseWheelListener ml: this.getMouseWheelListeners() ){ + for (MouseWheelListener ml : this.getMouseWheelListeners()) { this.removeMouseWheelListener(ml); } // this holds reference to ActionCallback forever so set it to null to prevent @@ -394,7 +397,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } } - @Override public void setZone(String zone) { this.zone = zone; @@ -502,7 +504,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } else if (isPlayable) { g2d.setColor(new Color(153, 102, 204, 200)); //g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); - g2d.fillRoundRect(cardXOffset, cardYOffset , cardWidth , cardHeight , cornerSize, cornerSize); + g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize); } if (canAttack) { @@ -512,10 +514,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti //TODO:uncomment /* - if (gameCard.isAttacking()) { - g2d.setColor(new Color(200,10,10,200)); - g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize); - }*/ + if (gameCard.isAttacking()) { + g2d.setColor(new Color(200,10,10,200)); + g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize); + }*/ } @Override @@ -562,8 +564,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti if (counterPanel != null) { counterPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); counterPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - int size = cardWidth > WIDTH_LIMIT ? 40: 20; - + int size = cardWidth > WIDTH_LIMIT ? 40 : 20; minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2); minusCounterLabel.setSize(size, size); @@ -577,7 +578,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti otherCounterLabel.setLocation(5, counterPanel.getHeight() - size); otherCounterLabel.setSize(size, size); - } int fontHeight = Math.round(cardHeight * (27f / 680)); boolean showText = (!isAnimationPanel && fontHeight < 12); @@ -823,7 +823,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti this.gameCard = card; String cardType = getType(card); - popupText.setText(getText(cardType, card)); + tooltipText.setText(getText(cardType, card)); if (hasSickness && CardUtil.isCreature(gameCard) && isPermanent) { overlayPanel.setVisible(true); @@ -864,11 +864,11 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti minusCounterLabel.setVisible(false); loyaltyCounterLabel.setVisible(false); otherCounterLabel.setVisible(false); - for (CounterView counterView:card.getCounters()) { + for (CounterView counterView : card.getCounters()) { if (counterView.getCount() == 0) { continue; } - switch(counterView.getName()) { + switch (counterView.getName()) { case "+1/+1": if (counterView.getCount() != plusCounter) { plusCounter = counterView.getCount(); @@ -913,10 +913,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) { - int factor = cardWidth > WIDTH_LIMIT ? 2 :1; + int factor = cardWidth > WIDTH_LIMIT ? 2 : 1; int xOffset = amount > 9 ? 2 : 5; - int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7: 6 - :amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12: amount < 10000 ?9 : 8; + int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7 : 6 + : amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12 : amount < 10000 ? 9 : 8; BufferedImage newImage; if (cardWidth > WIDTH_LIMIT) { newImage = ImageManagerImpl.deepCopy(image); @@ -925,7 +925,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } Graphics graphics = newImage.getGraphics(); graphics.setColor(Color.BLACK); - graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize )); + graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize)); graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor); return new ImageIcon(newImage); } @@ -977,12 +977,12 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti if (gameCard.hideInfo()) { return; } - if (!popupShowing) { + if (!tooltipShowing) { synchronized (this) { - if (!popupShowing) { + if (!tooltipShowing) { TransferData transferData = getTransferDataForMouseEntered(); if (this.isShowing()) { - popupShowing = true; + tooltipShowing = true; callback.mouseEntered(e, transferData); } } @@ -1013,13 +1013,13 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti if (getMousePosition(true) != null) { return; } - if (popupShowing) { + if (tooltipShowing) { synchronized (this) { - if (popupShowing) { - popupShowing = false; + if (tooltipShowing) { + tooltipShowing = false; data.component = this; data.card = this.gameCard; - data.popupText = popupText; + data.popupText = tooltipText; callback.mouseExited(e, data); } } @@ -1047,7 +1047,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private TransferData getTransferDataForMouseEntered() { data.component = this; data.card = this.gameCard; - data.popupText = popupText; + data.popupText = tooltipText; data.gameId = this.gameId; data.locationOnScreen = data.component.getLocationOnScreen(); // we need this for popup data.popupOffsetX = isTapped() ? cardHeight + cardXOffset + POPUP_X_GAP : cardWidth + cardXOffset + POPUP_X_GAP; @@ -1145,7 +1145,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti dayNightButton.setIcon(new ImageIcon(night)); } if (this.gameCard.getSecondCardFace() == null) { - log.error("no second side for card to transform!"); + logger.error("no second side for card to transform!"); return; } if (!isPermanent) { // use only for custom transformation (when pressing day-night button) @@ -1210,5 +1210,14 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti yTextOffset = yOffset; } + @Override + public JPopupMenu getPopupMenu() { + return popupMenu; + } + + @Override + public void setPopupMenu(JPopupMenu popupMenu) { + this.popupMenu = popupMenu; + } } diff --git a/Mage.Common/src/mage/cards/MageCard.java b/Mage.Common/src/mage/cards/MageCard.java index 320e9d1139..275c3773c0 100644 --- a/Mage.Common/src/mage/cards/MageCard.java +++ b/Mage.Common/src/mage/cards/MageCard.java @@ -1,35 +1,61 @@ package mage.cards; +import java.awt.Image; +import java.util.UUID; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; import mage.cards.action.ActionCallback; import mage.view.CardView; -import javax.swing.*; -import java.awt.*; -import java.util.UUID; - public abstract class MageCard extends JPanel { + private static final long serialVersionUID = 6089945326434301879L; public abstract void onBeginAnimation(); + public abstract void onEndAnimation(); + public abstract boolean isTapped(); + public abstract boolean isFlipped(); + public abstract void setAlpha(float transparency); + public abstract float getAlpha(); + public abstract CardView getOriginal(); + // sets the vertical text offset for the card name on the image public abstract void setTextOffset(int yOffset); + public abstract void setCardBounds(int x, int y, int width, int height); + public abstract void update(CardView card); + public abstract void updateImage(); + public abstract Image getImage(); + public abstract void setZone(String zone); + public abstract String getZone(); + public abstract void updateCallback(ActionCallback callback, UUID gameId); + public abstract void toggleTransformed(); + public abstract boolean isTransformed(); + public abstract void showCardTitle(); + public abstract void setSelected(boolean selected); + public abstract void setCardAreaRef(JPanel cardArea); + public abstract void setChoosable(boolean isChoosable); + + public abstract void setPopupMenu(JPopupMenu popupMenu); + + public abstract JPopupMenu getPopupMenu(); + } diff --git a/Mage.Common/src/mage/cards/action/ActionCallback.java b/Mage.Common/src/mage/cards/action/ActionCallback.java index c355ff4fae..a2b1345f01 100644 --- a/Mage.Common/src/mage/cards/action/ActionCallback.java +++ b/Mage.Common/src/mage/cards/action/ActionCallback.java @@ -12,6 +12,6 @@ public interface ActionCallback { void mouseEntered(MouseEvent e, TransferData data); void mouseExited(MouseEvent e, TransferData data); void mouseWheelMoved(MouseWheelEvent e, TransferData data); - void hidePopup(); + void hideTooltipPopup(); } diff --git a/Mage.Common/src/mage/cards/action/impl/EmptyCallback.java b/Mage.Common/src/mage/cards/action/impl/EmptyCallback.java index 425225a573..9db675f342 100644 --- a/Mage.Common/src/mage/cards/action/impl/EmptyCallback.java +++ b/Mage.Common/src/mage/cards/action/impl/EmptyCallback.java @@ -35,7 +35,7 @@ public class EmptyCallback implements ActionCallback { } @Override - public void hidePopup() { + public void hideTooltipPopup() { } @Override 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 c96384e4dc..aed2451d8b 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 @@ -63,6 +63,7 @@ import mage.constants.ManaType; import mage.constants.Outcome; import mage.constants.PhaseStep; import mage.constants.PlayerAction; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; import mage.constants.RangeOfInfluence; import mage.constants.Zone; import mage.filter.common.FilterAttackingCreature; @@ -109,6 +110,11 @@ public class HumanPlayer extends PlayerImpl { protected HashSet autoSelectReplacementEffects = new HashSet<>(); protected ManaCost currentlyUnpaidMana; + protected Set triggerAutoOrderAbilityFirst = new HashSet<>(); + protected Set triggerAutoOrderAbilityLast = new HashSet<>(); + protected Set triggerAutoOrderNameFirst = new HashSet<>(); + protected Set triggerAutoOrderNameLast = new HashSet<>(); + public HumanPlayer(String name, RangeOfInfluence range, int skill) { super(name, range); replacementEffectChoice = new ChoiceImpl(true); @@ -669,12 +675,39 @@ public class HumanPlayer extends PlayerImpl { @Override public TriggeredAbility chooseTriggeredAbility(List abilities, Game game) { + // try to set trigger auto order + List abilitiesWithNoOrderSet = new ArrayList<>(); + TriggeredAbility abilityOrderLast = null; + for (TriggeredAbility ability : abilities) { + if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) { + return ability; + } + if (triggerAutoOrderNameFirst.contains(ability.getRule())) { + return ability; + } + if (triggerAutoOrderAbilityLast.contains(ability.getOriginalId())) { + abilityOrderLast = ability; + continue; + } + if (triggerAutoOrderNameLast.contains(ability.getRule())) { + abilityOrderLast = ability; + continue; + } + abilitiesWithNoOrderSet.add(ability); + } + if (abilitiesWithNoOrderSet.isEmpty()) { + return abilityOrderLast; + } + if (abilitiesWithNoOrderSet.size() == 1) { + return abilitiesWithNoOrderSet.iterator().next(); + } + updateGameStatePriority("chooseTriggeredAbility", game); while (!abort) { - game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities); + game.fireSelectTargetTriggeredAbilityEvent(playerId, "Pick triggered ability (goes to the stack first)", abilitiesWithNoOrderSet); waitForResponse(game); if (response.getUUID() != null) { - for (TriggeredAbility ability : abilities) { + for (TriggeredAbility ability : abilitiesWithNoOrderSet) { if (ability.getId().equals(response.getUUID())) { return ability; } @@ -1309,11 +1342,60 @@ public class HumanPlayer extends PlayerImpl { } @Override - public void sendPlayerAction(PlayerAction playerAction, Game game) { - if (PlayerAction.RESET_AUTO_SELECT_REPLACEMENT_EFFECTS.equals(playerAction)) { - autoSelectReplacementEffects.clear(); - } else { - super.sendPlayerAction(playerAction, game); + public void sendPlayerAction(PlayerAction playerAction, Game game, Object data) { + switch (playerAction) { + case RESET_AUTO_SELECT_REPLACEMENT_EFFECTS: + autoSelectReplacementEffects.clear(); + break; + case TRIGGER_AUTO_ORDER_ABILITY_FIRST: + case TRIGGER_AUTO_ORDER_ABILITY_LAST: + case TRIGGER_AUTO_ORDER_NAME_FIRST: + case TRIGGER_AUTO_ORDER_NAME_LAST: + case TRIGGER_AUTO_ORDER_RESET_ALL: + setTriggerAutoOrder(playerAction, game, data); + break; + default: + super.sendPlayerAction(playerAction, game, data); + } + } + + private void setTriggerAutoOrder(PlayerAction playerAction, Game game, Object data) { + if (playerAction.equals(TRIGGER_AUTO_ORDER_RESET_ALL)) { + triggerAutoOrderAbilityFirst.clear(); + triggerAutoOrderAbilityLast.clear(); + triggerAutoOrderNameFirst.clear(); + triggerAutoOrderNameLast.clear(); + return; + } + if (data instanceof UUID) { + UUID abilityId = (UUID) data; + UUID originalId = null; + for (TriggeredAbility ability : game.getState().getTriggered(getId())) { + if (ability.getId().equals(abilityId)) { + originalId = ability.getOriginalId(); + break; + } + } + if (originalId != null) { + switch (playerAction) { + case TRIGGER_AUTO_ORDER_ABILITY_FIRST: + triggerAutoOrderAbilityFirst.add(originalId); + break; + case TRIGGER_AUTO_ORDER_ABILITY_LAST: + triggerAutoOrderAbilityFirst.add(originalId); + break; + } + } + } else if (data instanceof String) { + String abilityName = (String) data; + switch (playerAction) { + case TRIGGER_AUTO_ORDER_NAME_FIRST: + triggerAutoOrderNameFirst.add(abilityName); + break; + case TRIGGER_AUTO_ORDER_NAME_LAST: + triggerAutoOrderNameLast.add(abilityName); + break; + } } } @@ -1332,7 +1414,7 @@ public class HumanPlayer extends PlayerImpl { } if (!chooseUse(Outcome.Detriment, GameLog.getPlayerConfirmColoredText("You have still mana in your mana pool. Pass regardless?") + GameLog.getSmallSecondLineText(activePlayerText + " / " + game.getStep().getType().toString() + priorityPlayerText), null, game)) { - sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game); + sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game, null); return false; } } 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 30fbe4fcd1..07ed9e64e9 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -582,7 +582,7 @@ public class GameController implements GameCallback { } break; default: - game.sendPlayerAction(playerAction, getPlayerId(userId)); + game.sendPlayerAction(playerAction, getPlayerId(userId), data); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 1b7945ff26..eb098ea182 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1384,8 +1384,8 @@ public class TestPlayer implements Player { } @Override - public void sendPlayerAction(mage.constants.PlayerAction playerAction, Game game) { - computerPlayer.sendPlayerAction(playerAction, game); + public void sendPlayerAction(mage.constants.PlayerAction playerAction, Game game, Object data) { + computerPlayer.sendPlayerAction(playerAction, game, data); } @Override diff --git a/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java index 197e1b040d..eb834b17d7 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java @@ -54,11 +54,11 @@ public class BoostControlledEffect extends ContinuousEffectImpl { protected boolean lockedIn = false; public BoostControlledEffect(int power, int toughness, Duration duration) { - this(power, toughness, duration, new FilterCreaturePermanent("Creatures"), false); + this(power, toughness, duration, new FilterCreaturePermanent("creatures"), false); } public BoostControlledEffect(DynamicValue power, DynamicValue toughness, Duration duration) { - this(power, toughness, duration, new FilterCreaturePermanent("Creatures"), false); + this(power, toughness, duration, new FilterCreaturePermanent("creatures"), false); } public BoostControlledEffect(int power, int toughness, Duration duration, boolean excludeSource) { diff --git a/Mage/src/mage/constants/PlayerAction.java b/Mage/src/mage/constants/PlayerAction.java index 82c18616d7..e572a6f2b6 100644 --- a/Mage/src/mage/constants/PlayerAction.java +++ b/Mage/src/mage/constants/PlayerAction.java @@ -29,16 +29,22 @@ package mage.constants; /** * Defines player actions for a game - * + * * @author LevelX2 */ public enum PlayerAction { + PASS_PRIORITY_UNTIL_MY_NEXT_TURN, PASS_PRIORITY_UNTIL_TURN_END_STEP, PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, PASS_PRIORITY_UNTIL_NEXT_TURN, PASS_PRIORITY_UNTIL_STACK_RESOLVED, PASS_PRIORITY_CANCEL_ALL_ACTIONS, + TRIGGER_AUTO_ORDER_ABILITY_FIRST, + TRIGGER_AUTO_ORDER_NAME_FIRST, + TRIGGER_AUTO_ORDER_ABILITY_LAST, + TRIGGER_AUTO_ORDER_NAME_LAST, + TRIGGER_AUTO_ORDER_RESET_ALL, ROLLBACK_TURNS, UNDO, CONCEDE, @@ -55,4 +61,4 @@ public enum PlayerAction { DENY_PERMISSON_TO_ROLLBACK_TURN, PERMISSION_REQUESTS_ALLOWED_ON, PERMISSION_REQUESTS_ALLOWED_OFF -} \ No newline at end of file +} diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 1e0a491f92..0c10ca220a 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -229,7 +229,7 @@ public interface Game extends MageItem, Serializable { void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map options); - void fireSelectTargetEvent(UUID playerId, String message, List abilities); + void fireSelectTargetTriggeredAbilityEvent(UUID playerId, String message, List abilities); void fireSelectTargetEvent(UUID playerId, String message, List perms, boolean required); @@ -353,7 +353,7 @@ public interface Game extends MageItem, Serializable { void addPermanent(Permanent permanent); // priority method - void sendPlayerAction(PlayerAction playerAction, UUID playerId); + void sendPlayerAction(PlayerAction playerAction, UUID playerId, Object data); /** * This version supports copying of copies of any depth. diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index e30b539ce2..bddd512b7b 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1136,10 +1136,10 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public void sendPlayerAction(PlayerAction playerAction, UUID playerId) { + public void sendPlayerAction(PlayerAction playerAction, UUID playerId, Object data) { Player player = state.getPlayer(playerId); if (player != null) { - player.sendPlayerAction(playerAction, this); + player.sendPlayerAction(playerAction, this, data); } } @@ -1929,11 +1929,16 @@ public abstract class GameImpl implements Game, Serializable { playerQueryEventSource.target(playerId, message, cards, required, options); } + /** + * Only used from human players to select order triggered abilities go to + * the stack. + * + * @param playerId + * @param message + * @param abilities + */ @Override - public void fireSelectTargetEvent(UUID playerId, String message, List abilities) { - if (simulation) { - return; - } + public void fireSelectTargetTriggeredAbilityEvent(UUID playerId, String message, List abilities) { playerQueryEventSource.target(playerId, message, abilities); } diff --git a/Mage/src/mage/game/events/PlayerQueryEvent.java b/Mage/src/mage/game/events/PlayerQueryEvent.java index c6d18ba396..6b299f2085 100644 --- a/Mage/src/mage/game/events/PlayerQueryEvent.java +++ b/Mage/src/mage/game/events/PlayerQueryEvent.java @@ -29,6 +29,7 @@ package mage.game.events; import java.io.Serializable; import java.util.EventObject; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -60,8 +61,8 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri private Set targets; private Cards cards; private List booster; - private QueryType queryType; - private UUID playerId; + private final QueryType queryType; + private final UUID playerId; private boolean required; private int min; private int max; @@ -72,11 +73,6 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri private Choice choice; private PlayerQueryEvent(UUID playerId, String message, List 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); - this.options = options; - } - - private PlayerQueryEvent(UUID playerId, String message, List abilities, Set choices, Set targets, Cards cards, QueryType queryType, int min, int max, boolean required) { super(playerId); this.queryType = queryType; this.message = message; @@ -88,6 +84,12 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri this.required = required; this.min = min; this.max = max; + if (options == null) { + this.options = new HashMap<>(); + } else { + this.options = options; + } + this.options.put("queryType", queryType); } private PlayerQueryEvent(UUID playerId, String message, List booster, QueryType queryType, int time) { @@ -148,7 +150,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri } public static PlayerQueryEvent askEvent(UUID playerId, String message) { - return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false); + return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false, null); } public static PlayerQueryEvent chooseAbilityEvent(UUID playerId, String message, String objectName, List choices) { @@ -157,7 +159,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri nameAsSet = new HashSet<>(); nameAsSet.add(objectName); } - return new PlayerQueryEvent(playerId, message, choices, nameAsSet, null, null, QueryType.CHOOSE_ABILITY, 0, 0, false); + return new PlayerQueryEvent(playerId, message, choices, nameAsSet, null, null, QueryType.CHOOSE_ABILITY, 0, 0, false, null); } public static PlayerQueryEvent choosePileEvent(UUID playerId, String message, List pile1, List pile2) { @@ -173,7 +175,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri } public static PlayerQueryEvent targetEvent(UUID playerId, String message, Set targets, boolean required) { - return new PlayerQueryEvent(playerId, message, null, null, targets, null, QueryType.PICK_TARGET, 0, 0, required); + return new PlayerQueryEvent(playerId, message, null, null, targets, null, QueryType.PICK_TARGET, 0, 0, required, null); } public static PlayerQueryEvent targetEvent(UUID playerId, String message, Set targets, boolean required, Map options) { @@ -185,7 +187,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri } public static PlayerQueryEvent targetEvent(UUID playerId, String message, List abilities) { - return new PlayerQueryEvent(playerId, message, abilities, null, null, null, QueryType.PICK_ABILITY, 0, 0, true); + return new PlayerQueryEvent(playerId, message, abilities, null, null, null, QueryType.PICK_ABILITY, 0, 0, true, null); } public static PlayerQueryEvent targetEvent(UUID playerId, String message, List perms, boolean required) { @@ -193,7 +195,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri } public static PlayerQueryEvent selectEvent(UUID playerId, String message) { - return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.SELECT, 0, 0, false); + return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.SELECT, 0, 0, false, null); } public static PlayerQueryEvent selectEvent(UUID playerId, String message, Map options) { @@ -205,11 +207,11 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri } public static PlayerQueryEvent playXManaEvent(UUID playerId, String message) { - return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.PLAY_X_MANA, 0, 0, false); + return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.PLAY_X_MANA, 0, 0, false, null); } public static PlayerQueryEvent amountEvent(UUID playerId, String message, int min, int max) { - return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.AMOUNT, min, max, false); + return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.AMOUNT, min, max, false, null); } public static PlayerQueryEvent pickCard(UUID playerId, String message, List booster, int time) { diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 8e12ba8b25..5c960e650c 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -402,7 +402,7 @@ public interface Player extends MageItem, Copyable { void skip(); // priority, undo, ... - void sendPlayerAction(PlayerAction passPriorityAction, Game game); + void sendPlayerAction(PlayerAction passPriorityAction, Game game, Object data); int getStoredBookmark(); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 7bfa31a2b0..4ee90b73ca 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -1878,7 +1878,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public void sendPlayerAction(PlayerAction playerAction, Game game) { + public void sendPlayerAction(PlayerAction playerAction, Game game, Object data) { switch (playerAction) { case PASS_PRIORITY_UNTIL_MY_NEXT_TURN: // F9 passedUntilNextMain = false; diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt index 95d40c590e..98eacef81c 100644 --- a/Utils/release/getting_implemented_cards.txt +++ b/Utils/release/getting_implemented_cards.txt @@ -6,157 +6,7 @@ git log tagOrSha1..HEAD --diff-filter=A --name-status | sed -ne 's/^A[^u]Mage.Se for Windows: you need to replace ' by "" and remove -u in sort -Example for cards implemented from 0.8.7 till 0.9: -git log 9ac166abc92f70aebdbe34825880ff8f909465ed..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.0.2-release: -git log 6b38cd5b18298b07962b969bfa2eb69c62839575..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.0.3-release: -git log 7ba3d451da95183b8c1cfb732b332f640963cc4a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -git log 68333a2eff6b643b2028d18dad16d1f228be7a2c..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -20130901 -git log 10902581140fe4268fc12408f099ad82347d7cd0..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.1.0-release: -git log d6c1075125e657d4dd2e7bb120e108bb4c4536ff..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.1.2-2013_10_26-release: -git log 63889f5bd4faa0a0915bb1e845ca3a0bc1093070..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.2.0 -git log b724d7fe136abbe09144eb2824739df3238061ee..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-02-03 -git log 9c5d5208b96e28e1e767574e1143b845e6b7308f..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-02-15 -git log 88d8c30b6c3dbf7c90354eccfd04107641c308f1..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-04-25 -git log a1cfd040d74dd6d2100168754961cfebb154f153..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-05-10 -git log e93cd580dd8ff985fbda018bb5ea652134c1865e..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-05-10v2 -git log e484da4028e6c0498bbcd76b83af39bca93d26b1..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-05-30v1 -git log 99a60c3063521551ab08c506386729f1feaee257..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-06-15 -git log 6c8b818d890e9e0ce4bc5e3128249bb9e62c0b23..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-06-28 -git log 1129858a6c5c0dae5d1e29ea931804c1165b8c38..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-07-11 -git log 458255cd0627af90c2ebeab4c410a16d55a36f41..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-07-19 -git log 75eb0bdfdf36ba83dd5a3e2c6a204ceb186c9d5e..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-07-30 -git log 69ce53e6e8036bf01bdd090e8785f4d63c486d1e..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-08-11 -git log 709dc83ae6fd6778e5b52e5176a978f1c6fda3b7..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-08-19 -git log edd1563c12422f69c10bc76d310e0a84421ab4a2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-08-30 -git log fbc2a7258face1e908f3f08da1c2fec4ec0f86fe..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-09-13 -git log 632f711fe237defe43111f9b7236fda1da74bfc0..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-09-26 -git log b76102b0cdb911c7217fc2f510b4de86651f91d2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-10-05 -git log 8121849a185b913ef2de59fff2f3d9a6c9b3a613..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-10-18v1 -git log 58bbe60c724c7940996cf33db690d5eb1abfce0a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-10-18v2 (2014-10-20) -git log 974cb4435bb826769b935aaffc8335eeaa83d53f..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-10-18v3 (2014-10-25) -git log 26b5a277c4404a93e3b41ba477c5ec58dedcf826..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-11-01v1 -git log 8426816b0948991fdb100ce010f009a4aae7796a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-08v1 -git log 0ce2348e3362c60972c7901b1c083361c926f861..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-29v1 -git log 3446953a9d594f324a4b4e36ea13560f1fe2685b..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-29v2 -git log 68f2b65c345d4f16f33f6f23d849d48b1924bbd1..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-29v3 -git log 68fed320f79a43a4af21ed9238b7659df53a008e..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-29v4 (2014-12-13) -git log 96ce77e9d0e21610569071c81e661f91c53a3a17..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.3.0-2014-11-29v5 (2014-12-27) -git log c4ad51c4af2467f3483204e29f23b76c53f8f880..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-11-29v7 (2015-01-01) -git log c370189787cff7fc129b1ccf1b223807143460de..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-11-29v8 (2015-01-17) -git log 79ceae999a72151e2fadd1e15ddd37ec76c3f205..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2014-11-29v10 (2015-01-23) -git log 79ceae999a72151e2fadd1e15ddd37ec76c3f205..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-02-07v1 -git log e0b17eacc7b3abff4f6a6e878c01ebfab577df9e..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-02-07v3 -git log ba1fb775b2efd63d4de60786ab9d7857e00c3a57..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-02-07v4 -git log 7d7afb60d6fbe6d3f15a8fae9af147df3d3f31c6..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-02-07v7 -git log 6bd17716cd23e0f19142fb59c9c1bc44d87441e3..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v1 -git log ece4d69f367536ffb80cdf94d5a3dd771ba40f04..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v2 -git log b78d6f69af6d2b565c95b3ac20f76dd7eeecb3f8..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v2 -git log 78df43fd30850568c6494fb12c1f9d8415ef850f..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v5 -git log 65f731557bb55d0c85723e382001bdf9701f0a7f..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v6 -git log b79d6e64cff01726be93cbbfffca8a6f18188a3c..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v8 -git log 47b17535194c6aa5397a966463c8b17d37f8bd44..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.3.0-2015-03-14v9 -git log 00692410273d4c2ff70eec7bfcf6a601fb404bf9..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.0.v0 -git log fa847e8feb646e94d77fc8abc35e1d9817622f8a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.0.v1 -git log e8b2e01cd465f6a8ced2c83ec52a698ee093baa4..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt -since 1.4.0.v2 -git log eb96b08dfac3de4f78403d6f23e41ce8d41ece6f..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.1.v0 -git log 7a54d5364c9789ce2c3ef2c3eb4df7e0e0cde0cf..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.1.v1 -git log 3e9b4cfb7c22d363755d28f5ff1de351f6b7123c..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.1.v2 -git log 675801e8d493b023add4333e7835751d20da07a1..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.1.v3 -git log 757b9ea99ec1f0ce46bb533f9f86f3473d122a60..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.2.v0 -git log cd0cba6ec7d8799bb85247b7b4f5d545e170b093..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.2.v1 -git log 0b26aaff6ec033a538179bf607b1c7a7736aedb2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.2.v2 -git log 8d5137e40ebe1c029e737ef475935ff7cc40bb64..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.2.v3 -git log 60c7a2b34b5dd9a64bd415b65424a559294cf52b..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt - -since 1.4.2.v4 -git log 193177d9999d56729a687ca3b1a2fc3f3b96d9e2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +Example for cards implemented since hash: since 1.4.2.v5 git log 8dca887fadbbea41fb649ff17c5fe547a82ef23a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt @@ -167,6 +17,13 @@ git log 5de4637d9c7967612c207d3cf915c2861d922029..HEAD --diff-filter=A --name-st since 1.4.3.v2 git log 6d8378d5e49629a2fa126baf84340156a28f25db..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +since 1.4.3.v3 +git log 23039572f2206ade860f5835e9b85e82a9c4b2a1..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt + +since 1.4.3.v2 +git log 6d8378d5e49629a2fa126baf84340156a28f25db..23039572f2206ade860f5835e9b85e82a9c4b2a1 --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt + + 3. Copy added_cards.txt to trunk\Utils folder 4. Run script: > perl extract_in_wiki_format.perl