From 48e3a65d3a761c27cc1c976109b8733164f5a0b2 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Wed, 3 Nov 2010 17:33:51 +0000 Subject: [PATCH] Card Plugin implementation. Added displaying card and card layout. --- .../plugins/Mage-Theme-Plugin-0.3-shaded.jar | Bin 360925 -> 360898 bytes .../src/main/java/mage/client/cards/Card.java | 36 +- .../java/mage/client/cards/Permanent.java | 2 +- .../mage/client/game/BattlefieldPanel.java | 19 +- .../java/mage/client/game/PlayAreaPanel.java | 2 +- .../java/mage/client/plugins/MagePlugins.java | 3 + .../mage/client/plugins/impl/Plugins.java | 31 +- .../client/util/DefaultActionCallback.java | 16 + Mage.Common/src/mage/cards/MagePermanent.java | 11 +- .../mage/cards/interfaces/ActionCallback.java | 7 + .../mage/cards/interfaces/CardInterface.java | 5 - .../cards/interfaces/PermanentInterface.java | 9 +- Mage.Common/src/mage/constants/Constants.java | 1 - .../mage/interfaces/plugin/CardPlugin.java | 10 +- Mage.Common/src/mage/utils/CardUtil.java | 17 + Mage.Plugins/Mage.Card.Plugin/pom.xml | 23 ++ .../src/main/java/org/mage/card/MageCard.java | 9 - .../java/org/mage/card/arcane/Animation.java | 8 +- .../java/org/mage/card/arcane/CardPanel.java | 167 ++++++-- .../org/mage/card/arcane/ManaSymbols.java | 2 +- .../org/mage/plugins/card/CardPluginImpl.java | 365 ++++++++++++++++++ .../card/constants/Constants.java | 5 +- .../src/main/resources/log4j.properties | 8 + Mage.Plugins/Mage.Theme.Plugin/pom.xml | 1 - .../mage/plugins/theme/ThemePluginImpl.java | 2 +- 25 files changed, 687 insertions(+), 72 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java create mode 100644 Mage.Common/src/mage/cards/interfaces/ActionCallback.java delete mode 100644 Mage.Common/src/mage/cards/interfaces/CardInterface.java delete mode 100644 Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/MageCard.java create mode 100644 Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java rename Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/{ => plugins}/card/constants/Constants.java (66%) create mode 100644 Mage.Plugins/Mage.Card.Plugin/src/main/resources/log4j.properties diff --git a/Mage.Client/plugins/Mage-Theme-Plugin-0.3-shaded.jar b/Mage.Client/plugins/Mage-Theme-Plugin-0.3-shaded.jar index 192fc6472c4764de40f77cb3658b79204b5ea5a2..7f32941e99c0a7a9d8a6995f16046ab4daaa9f4f 100644 GIT binary patch delta 17097 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 delta 16818 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 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 3203268359..8ea649068e 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Card.java +++ b/Mage.Client/src/main/java/mage/client/cards/Card.java @@ -80,6 +80,7 @@ import mage.client.MageFrame; import mage.client.game.PlayAreaPanel; import mage.client.remote.Session; import mage.client.util.Config; +import mage.client.util.DefaultActionCallback; import mage.client.util.ImageHelper; import mage.client.util.gui.ArrowBuilder; import mage.sets.Sets; @@ -96,7 +97,8 @@ import mage.view.StackAbilityView; public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener { protected static Session session = MageFrame.getSession(); - + protected static DefaultActionCallback callback = new DefaultActionCallback(); + protected Point p; protected CardDimensions dimension; @@ -340,10 +342,9 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis } @Override - public void mouseClicked(MouseEvent arg0) { + public void mouseClicked(MouseEvent e) { requestFocusInWindow(); - if (gameId != null) - session.sendPlayerUUID(gameId, card.getId()); + callback.mouseClicked(e, gameId, session, card); } @Override @@ -441,11 +442,32 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis } @Override - public void update(PermanentView card) { + public List getLinks() {return null;} + + @Override + public boolean isTapped() {return false;} + + @Override + public void onBeginAnimation() {} + + @Override + public void onEndAnimation() {} + + @Override + public void setAlpha(float transparency) {} + + @Override + public PermanentView getOriginal() { + throw new RuntimeException("Not implemented"); } @Override - public List getLinks() { - return null; + public void setCardBounds(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + @Override + public void updateCard(PermanentView card) { + update(card); } } 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 5aa5813b2b..fd755f7255 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Permanent.java +++ b/Mage.Client/src/main/java/mage/client/cards/Permanent.java @@ -64,7 +64,7 @@ import mage.view.PermanentView; * * @author BetaSteward_at_googlemail.com */ -public class Permanent extends Card implements mage.cards.interfaces.PermanentInterface { +public class Permanent extends Card { protected PermanentView permanent; diff --git a/Mage.Client/src/main/java/mage/client/game/BattlefieldPanel.java b/Mage.Client/src/main/java/mage/client/game/BattlefieldPanel.java index 8850e805ec..6ff77ee079 100644 --- a/Mage.Client/src/main/java/mage/client/game/BattlefieldPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/BattlefieldPanel.java @@ -42,8 +42,11 @@ import java.awt.event.ComponentListener; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.Map.Entry; import java.util.UUID; +import java.util.Map.Entry; + +import javax.swing.JComponent; +import javax.swing.JScrollPane; import mage.cards.MagePermanent; import mage.client.cards.BigCard; @@ -61,9 +64,11 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon private Map permanents = new HashMap(); private UUID gameId; private BigCard bigCard; + private Map ui = new HashMap(); /** Creates new form BattlefieldPanel */ - public BattlefieldPanel() { + public BattlefieldPanel(JScrollPane jScrollPane) { + ui.put("jScrollPane", jScrollPane); initComponents(); } @@ -78,7 +83,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon addPermanent(permanent); } else { - permanents.get(permanent.getId()).update(permanent); + permanents.get(permanent.getId()).updateCard(permanent); } } for (Iterator> i = permanents.entrySet().iterator(); i.hasNext();) { @@ -93,16 +98,20 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon groupAttachments(permanent); } } + + Plugins.getInstance().sortPermanents(ui, permanents.values()); } private void addPermanent(PermanentView permanent) { MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId);; perm.addComponentListener(this); - perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight))); + if (!Plugins.getInstance().isCardPluginLoaded()) { + perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight))); + } permanents.put(permanent.getId(), perm); this.add(perm); moveToFront(perm); - perm.update(permanent); + perm.updateCard(permanent); } private void groupAttachments(PermanentView permanent) { 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 b340b23db3..c794cfdf01 100644 --- a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java @@ -105,7 +105,7 @@ public class PlayAreaPanel extends javax.swing.JPanel { manaPool = new mage.client.game.ManaPool(); btnCheat = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); - battlefieldPanel = new mage.client.game.BattlefieldPanel(); + battlefieldPanel = new mage.client.game.BattlefieldPanel(jScrollPane1); jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); diff --git a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java index b5691eeca5..d4fce6bc6c 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java @@ -1,5 +1,6 @@ package mage.client.plugins; +import java.util.Collection; import java.util.Map; import java.util.UUID; @@ -15,4 +16,6 @@ public interface MagePlugins { void shutdown(); void updateGamePanel(Map ui); MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId); + boolean isCardPluginLoaded(); + void sortPermanents(Map ui, Collection permanents); } diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java index 60d656039b..63d172df3a 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java @@ -1,6 +1,8 @@ package mage.client.plugins.impl; +import java.awt.event.MouseEvent; import java.io.File; +import java.util.Collection; import java.util.Map; import java.util.UUID; import java.util.logging.Level; @@ -10,10 +12,14 @@ import javax.swing.JComponent; import mage.cards.CardDimensions; import mage.cards.MagePermanent; +import mage.cards.interfaces.ActionCallback; +import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.cards.Permanent; import mage.client.plugins.MagePlugins; +import mage.client.remote.Session; import mage.client.util.Config; +import mage.client.util.DefaultActionCallback; import mage.constants.Constants; import mage.interfaces.plugin.CardPlugin; import mage.interfaces.plugin.ThemePlugin; @@ -29,6 +35,8 @@ public class Plugins implements MagePlugins { private static final MagePlugins fINSTANCE = new Plugins(); private static PluginManager pm; private final static Logger logger = Logging.getLogger(Plugins.class.getName()); + private CardPlugin cardPlugin = null; + protected static DefaultActionCallback defaultCallback = new DefaultActionCallback(); public static MagePlugins getInstance() { return fINSTANCE; @@ -39,6 +47,7 @@ public class Plugins implements MagePlugins { logger.log(Level.INFO, "Loading plugins..."); pm = PluginManagerFactory.createPluginManager(); pm.addPluginsFrom(new File(Constants.PLUGINS_DIRECTORY).toURI()); + this.cardPlugin = pm.getPlugin(CardPlugin.class); logger.log(Level.INFO, "Done."); } @@ -57,12 +66,26 @@ public class Plugins implements MagePlugins { } @Override - public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId) { - CardPlugin cp = pm.getPlugin(CardPlugin.class); - if (cp != null) { - return cp.getMagePermanent(card, dimension, gameId); + public MagePermanent getMagePermanent(final PermanentView card, BigCard bigCard, CardDimensions dimension, final UUID gameId) { + if (cardPlugin != null) { + return cardPlugin.getMagePermanent(card, dimension, gameId, new ActionCallback() { + @Override + public void mouseClicked(MouseEvent e) { + defaultCallback.mouseClicked(e, gameId, MageFrame.getSession(), card); + } + }); } else { return new Permanent(card, bigCard, Config.dimensions, gameId); } } + + @Override + public boolean isCardPluginLoaded() { + return this.cardPlugin != null; + } + + @Override + public void sortPermanents(Map ui, Collection permanents) { + if (this.cardPlugin != null) this.cardPlugin.sortPermanents(ui, permanents); + } } diff --git a/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java b/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java new file mode 100644 index 0000000000..d898b554ec --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java @@ -0,0 +1,16 @@ +package mage.client.util; + +import java.awt.event.MouseEvent; +import java.util.UUID; + +import mage.client.remote.Session; +import mage.view.CardView; + + +public class DefaultActionCallback { + public void mouseClicked(MouseEvent e, UUID gameId, Session session, CardView card) { + System.out.println("gameId:" + gameId); + if (gameId != null) + session.sendPlayerUUID(gameId, card.getId()); + } +} diff --git a/Mage.Common/src/mage/cards/MagePermanent.java b/Mage.Common/src/mage/cards/MagePermanent.java index 455f9411fe..6052ef23d4 100644 --- a/Mage.Common/src/mage/cards/MagePermanent.java +++ b/Mage.Common/src/mage/cards/MagePermanent.java @@ -4,10 +4,17 @@ import java.util.List; import javax.swing.JPanel; -import mage.cards.interfaces.CardInterface; import mage.cards.interfaces.PermanentInterface; +import mage.view.PermanentView; -public abstract class MagePermanent extends JPanel implements PermanentInterface, CardInterface { +public abstract class MagePermanent extends JPanel implements PermanentInterface { private static final long serialVersionUID = -3469258620601702171L; abstract public List getLinks(); + + abstract public void onBeginAnimation(); + abstract public void onEndAnimation(); + abstract public boolean isTapped(); + abstract public void setAlpha(float transparency); + abstract public PermanentView getOriginal(); + abstract public void setCardBounds(int x, int y, int width, int height); } diff --git a/Mage.Common/src/mage/cards/interfaces/ActionCallback.java b/Mage.Common/src/mage/cards/interfaces/ActionCallback.java new file mode 100644 index 0000000000..fe09e64c19 --- /dev/null +++ b/Mage.Common/src/mage/cards/interfaces/ActionCallback.java @@ -0,0 +1,7 @@ +package mage.cards.interfaces; + +import java.awt.event.MouseEvent; + +public interface ActionCallback { + void mouseClicked(MouseEvent e); +} diff --git a/Mage.Common/src/mage/cards/interfaces/CardInterface.java b/Mage.Common/src/mage/cards/interfaces/CardInterface.java deleted file mode 100644 index 0bb4c8e64c..0000000000 --- a/Mage.Common/src/mage/cards/interfaces/CardInterface.java +++ /dev/null @@ -1,5 +0,0 @@ -package mage.cards.interfaces; - -public interface CardInterface { - -} diff --git a/Mage.Common/src/mage/cards/interfaces/PermanentInterface.java b/Mage.Common/src/mage/cards/interfaces/PermanentInterface.java index c26433808a..aef77bacc5 100644 --- a/Mage.Common/src/mage/cards/interfaces/PermanentInterface.java +++ b/Mage.Common/src/mage/cards/interfaces/PermanentInterface.java @@ -1,7 +1,12 @@ package mage.cards.interfaces; +import java.awt.event.ComponentListener; +import java.awt.event.FocusListener; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + import mage.view.PermanentView; -public interface PermanentInterface { - void update(PermanentView card); +public interface PermanentInterface extends MouseMotionListener, MouseListener, FocusListener, ComponentListener { + void updateCard(PermanentView card); } diff --git a/Mage.Common/src/mage/constants/Constants.java b/Mage.Common/src/mage/constants/Constants.java index d2c4a8f29e..5868f1f643 100644 --- a/Mage.Common/src/mage/constants/Constants.java +++ b/Mage.Common/src/mage/constants/Constants.java @@ -28,7 +28,6 @@ package mage.constants; -import java.io.File; /** * diff --git a/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java index 0f948e04e6..4ae2490499 100644 --- a/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java +++ b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java @@ -1,10 +1,15 @@ package mage.interfaces.plugin; +import java.util.Collection; +import java.util.Map; import java.util.UUID; +import javax.swing.JComponent; + import mage.cards.CardDimensions; import mage.cards.MagePermanent; -import mage.view.CardView; +import mage.cards.interfaces.ActionCallback; +import mage.view.PermanentView; import net.xeoh.plugins.base.Plugin; /** @@ -14,5 +19,6 @@ import net.xeoh.plugins.base.Plugin; * @author nantuko */ public interface CardPlugin extends Plugin { - MagePermanent getMagePermanent(CardView card, CardDimensions dimension, UUID gameId); + MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback); + void sortPermanents(Map ui, Collection cards); } diff --git a/Mage.Common/src/mage/utils/CardUtil.java b/Mage.Common/src/mage/utils/CardUtil.java index e2251379d9..57b4729fe8 100644 --- a/Mage.Common/src/mage/utils/CardUtil.java +++ b/Mage.Common/src/mage/utils/CardUtil.java @@ -1,6 +1,7 @@ package mage.utils; import mage.Constants.CardType; +import mage.cards.MagePermanent; import mage.view.CardView; /** @@ -19,6 +20,22 @@ public class CardUtil { return is(card, CardType.PLANESWALKER); } + public static boolean isLand(CardView card) { + return is(card, CardType.LAND); + } + + public static boolean isCreature(MagePermanent card) { + return is(card.getOriginal(), CardType.CREATURE); + } + + public static boolean isPlaneswalker(MagePermanent card) { + return is(card.getOriginal(), CardType.PLANESWALKER); + } + + public static boolean isLand(MagePermanent card) { + return is(card.getOriginal(), CardType.LAND); + } + public static boolean is(CardView card, CardType type) { return card.getCardTypes().contains(type); } diff --git a/Mage.Plugins/Mage.Card.Plugin/pom.xml b/Mage.Plugins/Mage.Card.Plugin/pom.xml index 13936ce810..71fd30f5b9 100644 --- a/Mage.Plugins/Mage.Card.Plugin/pom.xml +++ b/Mage.Plugins/Mage.Card.Plugin/pom.xml @@ -44,6 +44,29 @@ 1.6 + + + org.apache.maven.plugins + maven-shade-plugin + 1.4 + + + package + + shade + + + true + + + log4j:log4j:jar: + + + + + + + mage-card-plugin diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/MageCard.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/MageCard.java deleted file mode 100644 index 360c223b2b..0000000000 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/MageCard.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mage.card; - -public abstract class MageCard { - abstract public void onBeginAnimation(); - abstract public void onEndAnimation(); - abstract public void repaint(); - abstract public boolean isTapped(); - abstract public void setTransparency(double transparency); -} \ No newline at end of file diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/Animation.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/Animation.java index e92086932b..9f80fab8e3 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/Animation.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/Animation.java @@ -9,7 +9,7 @@ import java.util.TimerTask; import javax.swing.JLayeredPane; import javax.swing.SwingUtilities; -import org.mage.card.MageCard; +import mage.cards.MagePermanent; abstract public class Animation { static private final long TARGET_MILLIS_PER_FRAME = 30; @@ -102,7 +102,7 @@ abstract public class Animation { } } - static public void tapCardToggle (final CardPanel panel, final MageCard parent) { + static public void tapCardToggle (final CardPanel panel, final MagePermanent parent) { new Animation(300) { protected void start () { parent.onBeginAnimation(); @@ -303,7 +303,7 @@ abstract public class Animation { }; } - static public void hideCard(final CardPanel panel, final MageCard card) { + static public void hideCard(final CardPanel panel, final MagePermanent card) { new Animation(600) { protected void start () { } @@ -311,7 +311,7 @@ abstract public class Animation { protected void update (float percentage) { float alpha = 1 - percentage; panel.setAlpha(alpha); - card.setTransparency(alpha); + card.setAlpha(alpha); card.repaint(); } diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/CardPanel.java index fa31d2aed1..15da48140e 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/CardPanel.java @@ -10,15 +10,19 @@ 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.FocusEvent; +import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; -import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.SwingUtilities; +import mage.cards.MagePermanent; +import mage.cards.interfaces.ActionCallback; import mage.utils.CardUtil; import mage.view.PermanentView; @@ -26,7 +30,7 @@ import org.mage.card.arcane.ScaledImagePanel.MultipassType; import org.mage.card.arcane.ScaledImagePanel.ScalingType; @SuppressWarnings({"unchecked","rawtypes"}) -public class CardPanel extends JPanel { +public class CardPanel extends MagePermanent { private static final long serialVersionUID = -3272134219262184410L; static public final double TAPPED_ANGLE = Math.PI / 2; static public final float ASPECT_RATIO = 3.5f / 2.5f; @@ -62,9 +66,17 @@ public class CardPanel extends JPanel { private boolean showCastingCost; private boolean hasImage = false; private float alpha = 1.0f; + + private ActionCallback callback; - public CardPanel (PermanentView newGameCard, boolean loadImage) { + public CardPanel (PermanentView newGameCard, boolean loadImage, ActionCallback callback) { this.gameCard = newGameCard; + this.callback = callback; + + addMouseListener(this); + addFocusListener(this); + addMouseMotionListener(this); + addComponentListener(this); //for container debug (don't remove) //setBorder(BorderFactory.createLineBorder(Color.green)); @@ -302,6 +314,7 @@ public class CardPanel extends JPanel { return gameCard.toString(); } + @Override public void setCardBounds (int x, int y, int width, int height) { cardWidth = width; cardHeight = height; @@ -353,28 +366,7 @@ public class CardPanel extends JPanel { return this.gameCard; } - public void setCard(PermanentView card) { - if (CardUtil.isCreature(card) && CardUtil.isPlaneswalker(card)) { - ptText.setText(card.getPower() + "/" + card.getToughness() + " (" + card.getLoyalty() + ")"); - } else if (CardUtil.isCreature(card)) { - ptText.setText(card.getPower() + "/" + card.getToughness()); - } else if (CardUtil.isPlaneswalker(card)) { - ptText.setText(card.getLoyalty()); - } else { - ptText.setText(""); - } - setText(card); - this.gameCard = card; - //TODO: uncomment - /*if (gameCard.hasSickness() && gameCard.isCreature() && gameCard.getTableID() != 0) { - overlayPanel.setVisible(true); - } else { - overlayPanel.setVisible(false); - }*/ - - repaint(); - } - + @Override public void setAlpha(float alpha) { this.alpha = alpha; } @@ -407,4 +399,129 @@ public class CardPanel extends JPanel { }); } } + + @Override + public List getLinks() { + return null; + } + + @Override + public boolean isTapped() { + return false; + } + + @Override + public void onBeginAnimation() { + } + + @Override + public void onEndAnimation() { + } + + @Override + public void updateCard(PermanentView card) { + if (this.gameCard.isTapped() != card.isTapped()) { + Animation.tapCardToggle(this, this); + } + if (CardUtil.isCreature(card) && CardUtil.isPlaneswalker(card)) { + ptText.setText(card.getPower() + "/" + card.getToughness() + " (" + card.getLoyalty() + ")"); + } else if (CardUtil.isCreature(card)) { + ptText.setText(card.getPower() + "/" + card.getToughness()); + } else if (CardUtil.isPlaneswalker(card)) { + ptText.setText(card.getLoyalty()); + } else { + ptText.setText(""); + } + setText(card); + this.gameCard = card; + //TODO: uncomment + /*if (gameCard.hasSickness() && gameCard.isCreature() && gameCard.getTableID() != 0) { + overlayPanel.setVisible(true); + } else { + overlayPanel.setVisible(false); + }*/ + + repaint(); + } + + @Override + public boolean contains(int x, int y) { + if (containsThis(x, y, true)) + return true; + + /* + * if (attachedCount > 0) { for (MWCardImpl card : + * mwAttachedCards.keySet()) { if (card.contains(x, y)) return true; } } + */ + + return false; + } + + public boolean containsThis(int x, int y, boolean root) { + int dy = getLocation().y; + if (root) dy = 0; + int cx = getCardX(); + int cy = getCardY() + dy; + int cw = getCardWidth(); + int ch = getCardHeight(); + if (isTapped()) { + cy = ch - cw + cx /*+ attachedDy*attachedCount*/; + ch = cw; + cw = getCardHeight(); + } + //int dx = drawIcons ? 19 : 0; + int dx = 0; + if (x >= cx && x <= cx + cw + dx && y >= cy && y <= cy + ch) { + return true; + } + return false; + } + + + @Override + public PermanentView getOriginal() { + return this.gameCard; + } + + @Override + public void mouseDragged(MouseEvent e) {} + + @Override + public void mouseMoved(MouseEvent e) {} + + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("clicked: " + this.gameCard.getId()); + callback.mouseClicked(e); + } + + @Override + public void mouseEntered(MouseEvent e) {} + + @Override + public void mouseExited(MouseEvent e) { } + + @Override + public void mousePressed(MouseEvent e) {} + + @Override + public void mouseReleased(MouseEvent e) {} + + @Override + public void focusGained(FocusEvent e) { } + + @Override + public void focusLost(FocusEvent e) {} + + @Override + public void componentHidden(ComponentEvent e) { } + + @Override + public void componentMoved(ComponentEvent e) {} + + @Override + public void componentResized(ComponentEvent e) {} + + @Override + public void componentShown(ComponentEvent e) {} } diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java index e36e40ff7d..8427bc6338 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -8,7 +8,7 @@ import java.util.StringTokenizer; import java.util.regex.Pattern; import org.apache.log4j.Logger; -import org.mage.card.constants.Constants; +import org.mage.plugins.card.constants.Constants; public class ManaSymbols { private static final Logger log = Logger.getLogger(ManaSymbols.class); diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java new file mode 100644 index 0000000000..fc8f8e1633 --- /dev/null +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -0,0 +1,365 @@ +package org.mage.plugins.card; + +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.swing.JComponent; +import javax.swing.JScrollPane; + +import mage.cards.CardDimensions; +import mage.cards.MagePermanent; +import mage.cards.interfaces.ActionCallback; +import mage.interfaces.plugin.CardPlugin; +import mage.utils.CardUtil; +import mage.view.PermanentView; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.Init; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.meta.Author; + +import org.apache.log4j.Logger; +import org.mage.card.arcane.CardPanel; +import org.mage.plugins.card.constants.Constants; + +@PluginImplementation +@Author(name = "nantuko") +public class CardPluginImpl implements CardPlugin { + + private final static Logger log = Logger.getLogger(CardPluginImpl.class); + + static private final int GUTTER_Y = 15; + static private final int GUTTER_X = 5; + static final float EXTRA_CARD_SPACING_X = 0.04f; + static private final float CARD_SPACING_Y = 0.03f; + static private final float STACK_SPACING_X = 0.07f; + static private final float STACK_SPACING_Y = 0.13f; + static private final int MW_GUIDE_HEIGHT = 30; + + private int landStackMax = 5; + private int cardWidthMin = 50, cardWidthMax = Constants.CARD_SIZE_FULL.width; + private boolean stackVertical = false; + + private int playAreaWidth, playAreaHeight; + private int cardWidth, cardHeight; + private int extraCardSpacingX, cardSpacingX, cardSpacingY; + private int stackSpacingX, stackSpacingY; + private List rows = new ArrayList(); + + @Init + public void init() { + } + + @PluginLoaded + public void newPlugin(CardPlugin plugin) { + log.info(plugin.toString() + " has been loaded."); + } + + public String toString() { + return "[Card plugin, version 0.1]"; + } + + @Override + public MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback) { + //log.debug("Card plugin: building mage permanent [w="+dimension.frameWidth+",h="+dimension.frameHeight+"]"); + CardPanel cardPanel = new CardPanel(permanent, false, callback); + cardPanel.setShowCastingCost(true); + cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight); + //cardPanel.setBorder(BorderFactory.createLineBorder(Color.red)); + return cardPanel; + } + + @Override + public void sortPermanents(Map ui, Collection permanents) { + if (ui == null) + throw new RuntimeException("Error: no components"); + JComponent component = ui.get("jScrollPane"); + if (component == null) + throw new RuntimeException("Error: jScrollPane is missing"); + if (!(component instanceof JScrollPane)) + throw new RuntimeException("Error: jScrollPane has wrong type."); + + JScrollPane jScrollPane = (JScrollPane)component; + + Row allLands = new Row(); + + outerLoop: // + for (MagePermanent permanent : permanents) { + if (!CardUtil.isLand(permanent) || CardUtil.isCreature(permanent)) + continue; + + int insertIndex = -1; + + // Find lands with the same name. + for (int i = 0, n = allLands.size(); i < n; i++) { + Stack stack = allLands.get(i); + MagePermanent firstPanel = stack.get(0); + if (firstPanel.getOriginal().getName().equals(permanent.getOriginal().getName())) { + if (!empty(firstPanel.getLinks())) { + // Put this land to the left of lands with the same name and attachments. + insertIndex = i; + break; + } + if (!empty(permanent.getLinks()) || stack.size() == landStackMax) { + // If this land has attachments or the stack is full, put it to the right. + insertIndex = i + 1; + continue; + } + // Add to stack. + stack.add(0, permanent); + continue outerLoop; + } + if (insertIndex != -1) + break; + } + + Stack stack = new Stack(); + stack.add(permanent); + allLands.add(insertIndex == -1 ? allLands.size() : insertIndex, stack); + } + + Row allCreatures = new Row(permanents, RowType.creature); + Row allOthers = new Row(permanents, RowType.other); + + cardWidth = cardWidthMax; + Rectangle rect = jScrollPane.getVisibleRect(); + playAreaWidth = rect.width; + playAreaHeight = rect.height - MW_GUIDE_HEIGHT; + while (true) { + rows.clear(); + cardHeight = Math.round(cardWidth * CardPanel.ASPECT_RATIO); + extraCardSpacingX = (int) Math.round(cardWidth * EXTRA_CARD_SPACING_X); + cardSpacingX = cardHeight - cardWidth + extraCardSpacingX; + cardSpacingY = (int) Math.round(cardHeight * CARD_SPACING_Y); + stackSpacingX = stackVertical ? 0 : (int) Math.round(cardWidth * STACK_SPACING_X); + stackSpacingY = (int) Math.round(cardHeight * STACK_SPACING_Y); + Row creatures = (Row) allCreatures.clone(); + Row lands = (Row) allLands.clone(); + Row others = (Row) allOthers.clone(); + // Wrap all creatures and lands. + wrap(creatures, rows, -1); + int afterCreaturesIndex = rows.size(); + wrap(lands, rows, afterCreaturesIndex); + // Store the current rows and others. + List storedRows = new ArrayList(rows.size()); + for (Row row : rows) + storedRows.add((Row) row.clone()); + Row storedOthers = (Row) others.clone(); + // Fill in all rows with others. + for (Row row : rows) + fillRow(others, rows, row); + + // Stop if everything fits, otherwise revert back to the stored values. + if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty()) + break; + rows = storedRows; + others = storedOthers; + // Try to put others on their own row(s) and fill in the rest. + wrap(others, rows, afterCreaturesIndex); + for (Row row : rows) + fillRow(others, rows, row); + // If that still doesn't fit, scale down. + if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty()) + break; + //cardWidth = (int)(cardWidth / 1.2); + cardWidth--; + } + + // Get size of all the rows. + int x, y = GUTTER_Y; + int maxRowWidth = 0; + for (Row row : rows) { + int rowBottom = 0; + x = GUTTER_X; + for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) { + Stack stack = row.get(stackIndex); + rowBottom = Math.max(rowBottom, y + stack.getHeight()); + x += stack.getWidth(); + } + y = rowBottom; + maxRowWidth = Math.max(maxRowWidth, x); + } + //setPreferredSize(new Dimension(maxRowWidth - cardSpacingX, y - cardSpacingY)); + //revalidate(); + + // Position all card panels. + x = 0; + y = GUTTER_Y; + for (Row row : rows) { + int rowBottom = 0; + x = GUTTER_X; + for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) { + Stack stack = row.get(stackIndex); + // Align others to the right. + if (RowType.other.isType(stack.get(0))) { + x = playAreaWidth - GUTTER_X + extraCardSpacingX; + for (int i = stackIndex, n = row.size(); i < n; i++) + x -= row.get(i).getWidth(); + } + for (int panelIndex = 0, panelCount = stack.size(); panelIndex < panelCount; panelIndex++) { + MagePermanent panel = stack.get(panelIndex); + int stackPosition = panelCount - panelIndex - 1; + //setComponentZOrder((Component)panel, panelIndex); + int panelX = x + (stackPosition * stackSpacingX); + int panelY = y + (stackPosition * stackSpacingY); + ///panel.setLocation(panelX, panelY); + panel.setCardBounds(panelX, panelY, cardWidth, cardHeight); + } + rowBottom = Math.max(rowBottom, y + stack.getHeight()); + x += stack.getWidth(); + } + y = rowBottom; + } + } + + private boolean empty(List list) { + return list == null || list.size() == 0; + } + + private int wrap(Row sourceRow, List rows, int insertIndex) { + // The cards are sure to fit (with vertical scrolling) at the minimum card width. + boolean allowHeightOverflow = cardWidth == cardWidthMin; + + Row currentRow = new Row(); + for (int i = 0, n = sourceRow.size() - 1; i <= n; i++) { + Stack stack = sourceRow.get(i); + // If the row is not empty and this stack doesn't fit, add the row. + int rowWidth = currentRow.getWidth(); + if (!currentRow.isEmpty() && rowWidth + stack.getWidth() > playAreaWidth) { + // Stop processing if the row is too wide or tall. + if (!allowHeightOverflow && rowWidth > playAreaWidth) + break; + if (!allowHeightOverflow && getRowsHeight(rows) + sourceRow.getHeight() > playAreaHeight) + break; + rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow); + currentRow = new Row(); + } + currentRow.add(stack); + } + // Add the last row if it is not empty and it fits. + if (!currentRow.isEmpty()) { + int rowWidth = currentRow.getWidth(); + if (allowHeightOverflow || rowWidth <= playAreaWidth) { + if (allowHeightOverflow || getRowsHeight(rows) + sourceRow.getHeight() <= playAreaHeight) { + rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow); + } + } + } + // Remove the wrapped stacks from the source row. + for (Row row : rows) + for (Stack stack : row) + sourceRow.remove(stack); + return insertIndex; + } + + private void fillRow(Row sourceRow, List rows, Row row) { + int rowWidth = row.getWidth(); + while (!sourceRow.isEmpty()) { + Stack stack = sourceRow.get(0); + rowWidth += stack.getWidth(); + if (rowWidth > playAreaWidth) + break; + if (stack.getHeight() > row.getHeight()) { + if (getRowsHeight(rows) - row.getHeight() + stack.getHeight() > playAreaHeight) + break; + } + row.add(sourceRow.remove(0)); + } + } + + private int getRowsHeight(List rows) { + int height = 0; + for (Row row : rows) + height += row.getHeight(); + return height - cardSpacingY + GUTTER_Y * 2; + } + + static private enum RowType { + land, creature, other; + + public boolean isType(MagePermanent card) { + switch (this) { + case land: + return CardUtil.isLand(card); + case creature: + return CardUtil.isCreature(card); + case other: + return !CardUtil.isLand(card) && !CardUtil.isCreature(card); + default: + throw new RuntimeException("Unhandled type: " + this); + } + } + } + + private class Row extends ArrayList { + public Row() { + super(16); + } + + public Row(Collection permanents, RowType type) { + this(); + addAll(permanents, type); + } + + private void addAll(Collection permanents, RowType type) { + for (MagePermanent panel : permanents) { + if (!type.isType(panel)) + continue; + Stack stack = new Stack(); + stack.add(panel); + add(stack); + } + } + + public boolean addAll(Collection c) { + boolean changed = super.addAll(c); + c.clear(); + return changed; + } + + private int getWidth() { + if (isEmpty()) + return 0; + int width = 0; + for (Stack stack : this) + width += stack.getWidth(); + return width + GUTTER_X * 2 - extraCardSpacingX; + } + + private int getHeight() { + if (isEmpty()) + return 0; + int height = 0; + for (Stack stack : this) + height = Math.max(height, stack.getHeight()); + return height; + } + } + + private class Stack extends ArrayList { + public Stack() { + super(8); + } + + public boolean add(MagePermanent panel) { + boolean appended = super.add(panel); + //for (CardPanel attachedPanel : panel.attachedPanels) + //add(attachedPanel); + return appended; + } + + private int getWidth() { + return cardWidth + (size() - 1) * stackSpacingX + cardSpacingX; + } + + private int getHeight() { + return cardHeight + (size() - 1) * stackSpacingY + cardSpacingY; + } + } + + +} diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/constants/Constants.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/constants/Constants.java similarity index 66% rename from Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/constants/Constants.java rename to Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/constants/Constants.java index 15df8302d2..632578704c 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/constants/Constants.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/constants/Constants.java @@ -1,9 +1,12 @@ -package org.mage.card.constants; +package org.mage.plugins.card.constants; + +import java.awt.Rectangle; public class Constants { public static final String RESOURCE_PATH = "/images"; public static final String RESOURCE_PATH_MANA = resourcePath("mana"); + public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149); /** * Build resource path. diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/resources/log4j.properties b/Mage.Plugins/Mage.Card.Plugin/src/main/resources/log4j.properties new file mode 100644 index 0000000000..08d7f0e74f --- /dev/null +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +#default levels +log4j.rootLogger=debug, console + +#console log +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p [%d{yyyy-MM-dd HH:mm [ss:SSS]}] %C{1}[%t]: %m%n +log4j.appender.console.Threshold=DEBUG \ No newline at end of file diff --git a/Mage.Plugins/Mage.Theme.Plugin/pom.xml b/Mage.Plugins/Mage.Theme.Plugin/pom.xml index cc15d2dd43..a4be97af38 100644 --- a/Mage.Plugins/Mage.Theme.Plugin/pom.xml +++ b/Mage.Plugins/Mage.Theme.Plugin/pom.xml @@ -45,7 +45,6 @@ - org.apache.maven.plugins maven-shade-plugin diff --git a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java index 236b231a3a..fef605c690 100644 --- a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java +++ b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java @@ -31,7 +31,7 @@ public class ThemePluginImpl implements ThemePlugin { } public String toString() { - return "[Theme plugin by nantuko, version 0.1]"; + return "[Theme plugin, version 0.1]"; } public void apply(Map ui) {