Card Plugin implementation. Added displaying card and card layout.

This commit is contained in:
magenoxx 2010-11-03 17:33:51 +00:00
parent b223d83be5
commit 48e3a65d3a
25 changed files with 687 additions and 72 deletions

View file

@ -80,6 +80,7 @@ import mage.client.MageFrame;
import mage.client.game.PlayAreaPanel; import mage.client.game.PlayAreaPanel;
import mage.client.remote.Session; import mage.client.remote.Session;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.DefaultActionCallback;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
import mage.client.util.gui.ArrowBuilder; import mage.client.util.gui.ArrowBuilder;
import mage.sets.Sets; import mage.sets.Sets;
@ -96,7 +97,8 @@ import mage.view.StackAbilityView;
public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener { public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener {
protected static Session session = MageFrame.getSession(); protected static Session session = MageFrame.getSession();
protected static DefaultActionCallback callback = new DefaultActionCallback();
protected Point p; protected Point p;
protected CardDimensions dimension; protected CardDimensions dimension;
@ -340,10 +342,9 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
} }
@Override @Override
public void mouseClicked(MouseEvent arg0) { public void mouseClicked(MouseEvent e) {
requestFocusInWindow(); requestFocusInWindow();
if (gameId != null) callback.mouseClicked(e, gameId, session, card);
session.sendPlayerUUID(gameId, card.getId());
} }
@Override @Override
@ -441,11 +442,32 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
} }
@Override @Override
public void update(PermanentView card) { public List<MagePermanent> 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 @Override
public List<MagePermanent> getLinks() { public void setCardBounds(int x, int y, int width, int height) {
return null; throw new RuntimeException("Not implemented");
}
@Override
public void updateCard(PermanentView card) {
update(card);
} }
} }

View file

@ -64,7 +64,7 @@ import mage.view.PermanentView;
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class Permanent extends Card implements mage.cards.interfaces.PermanentInterface { public class Permanent extends Card {
protected PermanentView permanent; protected PermanentView permanent;

View file

@ -42,8 +42,11 @@ import java.awt.event.ComponentListener;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.Map.Entry;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
@ -61,9 +64,11 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
private Map<UUID, MagePermanent> permanents = new HashMap<UUID, MagePermanent>(); private Map<UUID, MagePermanent> permanents = new HashMap<UUID, MagePermanent>();
private UUID gameId; private UUID gameId;
private BigCard bigCard; private BigCard bigCard;
private Map<String, JComponent> ui = new HashMap<String, JComponent>();
/** Creates new form BattlefieldPanel */ /** Creates new form BattlefieldPanel */
public BattlefieldPanel() { public BattlefieldPanel(JScrollPane jScrollPane) {
ui.put("jScrollPane", jScrollPane);
initComponents(); initComponents();
} }
@ -78,7 +83,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
addPermanent(permanent); addPermanent(permanent);
} }
else { else {
permanents.get(permanent.getId()).update(permanent); permanents.get(permanent.getId()).updateCard(permanent);
} }
} }
for (Iterator<Entry<UUID, MagePermanent>> i = permanents.entrySet().iterator(); i.hasNext();) { for (Iterator<Entry<UUID, MagePermanent>> i = permanents.entrySet().iterator(); i.hasNext();) {
@ -93,16 +98,20 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
groupAttachments(permanent); groupAttachments(permanent);
} }
} }
Plugins.getInstance().sortPermanents(ui, permanents.values());
} }
private void addPermanent(PermanentView permanent) { private void addPermanent(PermanentView permanent) {
MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId);; MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId);;
perm.addComponentListener(this); 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); permanents.put(permanent.getId(), perm);
this.add(perm); this.add(perm);
moveToFront(perm); moveToFront(perm);
perm.update(permanent); perm.updateCard(permanent);
} }
private void groupAttachments(PermanentView permanent) { private void groupAttachments(PermanentView permanent) {

View file

@ -105,7 +105,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
manaPool = new mage.client.game.ManaPool(); manaPool = new mage.client.game.ManaPool();
btnCheat = new javax.swing.JButton(); btnCheat = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane(); 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)); jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

View file

@ -1,5 +1,6 @@
package mage.client.plugins; package mage.client.plugins;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -15,4 +16,6 @@ public interface MagePlugins {
void shutdown(); void shutdown();
void updateGamePanel(Map<String, JComponent> ui); void updateGamePanel(Map<String, JComponent> ui);
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId); MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId);
boolean isCardPluginLoaded();
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents);
} }

View file

@ -1,6 +1,8 @@
package mage.client.plugins.impl; package mage.client.plugins.impl;
import java.awt.event.MouseEvent;
import java.io.File; import java.io.File;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@ -10,10 +12,14 @@ import javax.swing.JComponent;
import mage.cards.CardDimensions; import mage.cards.CardDimensions;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.interfaces.ActionCallback;
import mage.client.MageFrame;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.cards.Permanent; import mage.client.cards.Permanent;
import mage.client.plugins.MagePlugins; import mage.client.plugins.MagePlugins;
import mage.client.remote.Session;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.DefaultActionCallback;
import mage.constants.Constants; import mage.constants.Constants;
import mage.interfaces.plugin.CardPlugin; import mage.interfaces.plugin.CardPlugin;
import mage.interfaces.plugin.ThemePlugin; import mage.interfaces.plugin.ThemePlugin;
@ -29,6 +35,8 @@ public class Plugins implements MagePlugins {
private static final MagePlugins fINSTANCE = new Plugins(); private static final MagePlugins fINSTANCE = new Plugins();
private static PluginManager pm; private static PluginManager pm;
private final static Logger logger = Logging.getLogger(Plugins.class.getName()); private final static Logger logger = Logging.getLogger(Plugins.class.getName());
private CardPlugin cardPlugin = null;
protected static DefaultActionCallback defaultCallback = new DefaultActionCallback();
public static MagePlugins getInstance() { public static MagePlugins getInstance() {
return fINSTANCE; return fINSTANCE;
@ -39,6 +47,7 @@ public class Plugins implements MagePlugins {
logger.log(Level.INFO, "Loading plugins..."); logger.log(Level.INFO, "Loading plugins...");
pm = PluginManagerFactory.createPluginManager(); pm = PluginManagerFactory.createPluginManager();
pm.addPluginsFrom(new File(Constants.PLUGINS_DIRECTORY).toURI()); pm.addPluginsFrom(new File(Constants.PLUGINS_DIRECTORY).toURI());
this.cardPlugin = pm.getPlugin(CardPlugin.class);
logger.log(Level.INFO, "Done."); logger.log(Level.INFO, "Done.");
} }
@ -57,12 +66,26 @@ public class Plugins implements MagePlugins {
} }
@Override @Override
public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId) { public MagePermanent getMagePermanent(final PermanentView card, BigCard bigCard, CardDimensions dimension, final UUID gameId) {
CardPlugin cp = pm.getPlugin(CardPlugin.class); if (cardPlugin != null) {
if (cp != null) { return cardPlugin.getMagePermanent(card, dimension, gameId, new ActionCallback() {
return cp.getMagePermanent(card, dimension, gameId); @Override
public void mouseClicked(MouseEvent e) {
defaultCallback.mouseClicked(e, gameId, MageFrame.getSession(), card);
}
});
} else { } else {
return new Permanent(card, bigCard, Config.dimensions, gameId); return new Permanent(card, bigCard, Config.dimensions, gameId);
} }
} }
@Override
public boolean isCardPluginLoaded() {
return this.cardPlugin != null;
}
@Override
public void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents) {
if (this.cardPlugin != null) this.cardPlugin.sortPermanents(ui, permanents);
}
} }

View file

@ -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());
}
}

View file

@ -4,10 +4,17 @@ import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
import mage.cards.interfaces.CardInterface;
import mage.cards.interfaces.PermanentInterface; 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; private static final long serialVersionUID = -3469258620601702171L;
abstract public List<MagePermanent> getLinks(); abstract public List<MagePermanent> 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);
} }

View file

@ -0,0 +1,7 @@
package mage.cards.interfaces;
import java.awt.event.MouseEvent;
public interface ActionCallback {
void mouseClicked(MouseEvent e);
}

View file

@ -1,5 +0,0 @@
package mage.cards.interfaces;
public interface CardInterface {
}

View file

@ -1,7 +1,12 @@
package mage.cards.interfaces; 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; import mage.view.PermanentView;
public interface PermanentInterface { public interface PermanentInterface extends MouseMotionListener, MouseListener, FocusListener, ComponentListener {
void update(PermanentView card); void updateCard(PermanentView card);
} }

View file

@ -28,7 +28,6 @@
package mage.constants; package mage.constants;
import java.io.File;
/** /**
* *

View file

@ -1,10 +1,15 @@
package mage.interfaces.plugin; package mage.interfaces.plugin;
import java.util.Collection;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.swing.JComponent;
import mage.cards.CardDimensions; import mage.cards.CardDimensions;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.view.CardView; import mage.cards.interfaces.ActionCallback;
import mage.view.PermanentView;
import net.xeoh.plugins.base.Plugin; import net.xeoh.plugins.base.Plugin;
/** /**
@ -14,5 +19,6 @@ import net.xeoh.plugins.base.Plugin;
* @author nantuko * @author nantuko
*/ */
public interface CardPlugin extends Plugin { 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<String, JComponent> ui, Collection<MagePermanent> cards);
} }

View file

@ -1,6 +1,7 @@
package mage.utils; package mage.utils;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.cards.MagePermanent;
import mage.view.CardView; import mage.view.CardView;
/** /**
@ -19,6 +20,22 @@ public class CardUtil {
return is(card, CardType.PLANESWALKER); 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) { public static boolean is(CardView card, CardType type) {
return card.getCardTypes().contains(type); return card.getCardTypes().contains(type);
} }

View file

@ -44,6 +44,29 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<artifactSet>
<includes>
<include>log4j:log4j:jar:</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
<finalName>mage-card-plugin</finalName> <finalName>mage-card-plugin</finalName>

View file

@ -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);
}

View file

@ -9,7 +9,7 @@ import java.util.TimerTask;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.mage.card.MageCard; import mage.cards.MagePermanent;
abstract public class Animation { abstract public class Animation {
static private final long TARGET_MILLIS_PER_FRAME = 30; 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) { new Animation(300) {
protected void start () { protected void start () {
parent.onBeginAnimation(); 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) { new Animation(600) {
protected void start () { protected void start () {
} }
@ -311,7 +311,7 @@ abstract public class Animation {
protected void update (float percentage) { protected void update (float percentage) {
float alpha = 1 - percentage; float alpha = 1 - percentage;
panel.setAlpha(alpha); panel.setAlpha(alpha);
card.setTransparency(alpha); card.setAlpha(alpha);
card.repaint(); card.repaint();
} }

View file

@ -10,15 +10,19 @@ import java.awt.Image;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.RenderingHints; 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.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JRootPane; import javax.swing.JRootPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import mage.cards.MagePermanent;
import mage.cards.interfaces.ActionCallback;
import mage.utils.CardUtil; import mage.utils.CardUtil;
import mage.view.PermanentView; import mage.view.PermanentView;
@ -26,7 +30,7 @@ import org.mage.card.arcane.ScaledImagePanel.MultipassType;
import org.mage.card.arcane.ScaledImagePanel.ScalingType; import org.mage.card.arcane.ScaledImagePanel.ScalingType;
@SuppressWarnings({"unchecked","rawtypes"}) @SuppressWarnings({"unchecked","rawtypes"})
public class CardPanel extends JPanel { public class CardPanel extends MagePermanent {
private static final long serialVersionUID = -3272134219262184410L; private static final long serialVersionUID = -3272134219262184410L;
static public final double TAPPED_ANGLE = Math.PI / 2; static public final double TAPPED_ANGLE = Math.PI / 2;
static public final float ASPECT_RATIO = 3.5f / 2.5f; static public final float ASPECT_RATIO = 3.5f / 2.5f;
@ -62,9 +66,17 @@ public class CardPanel extends JPanel {
private boolean showCastingCost; private boolean showCastingCost;
private boolean hasImage = false; private boolean hasImage = false;
private float alpha = 1.0f; 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.gameCard = newGameCard;
this.callback = callback;
addMouseListener(this);
addFocusListener(this);
addMouseMotionListener(this);
addComponentListener(this);
//for container debug (don't remove) //for container debug (don't remove)
//setBorder(BorderFactory.createLineBorder(Color.green)); //setBorder(BorderFactory.createLineBorder(Color.green));
@ -302,6 +314,7 @@ public class CardPanel extends JPanel {
return gameCard.toString(); return gameCard.toString();
} }
@Override
public void setCardBounds (int x, int y, int width, int height) { public void setCardBounds (int x, int y, int width, int height) {
cardWidth = width; cardWidth = width;
cardHeight = height; cardHeight = height;
@ -353,28 +366,7 @@ public class CardPanel extends JPanel {
return this.gameCard; return this.gameCard;
} }
public void setCard(PermanentView card) { @Override
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();
}
public void setAlpha(float alpha) { public void setAlpha(float alpha) {
this.alpha = alpha; this.alpha = alpha;
} }
@ -407,4 +399,129 @@ public class CardPanel extends JPanel {
}); });
} }
} }
@Override
public List<MagePermanent> 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) {}
} }

View file

@ -8,7 +8,7 @@ import java.util.StringTokenizer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.constants.Constants; import org.mage.plugins.card.constants.Constants;
public class ManaSymbols { public class ManaSymbols {
private static final Logger log = Logger.getLogger(ManaSymbols.class); private static final Logger log = Logger.getLogger(ManaSymbols.class);

View file

@ -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<Row> rows = new ArrayList<Row>();
@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<String, JComponent> ui, Collection<MagePermanent> 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<Row> storedRows = new ArrayList<Row>(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<Row> 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<Row> 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<Row> 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<Stack> {
public Row() {
super(16);
}
public Row(Collection<MagePermanent> permanents, RowType type) {
this();
addAll(permanents, type);
}
private void addAll(Collection<MagePermanent> 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<? extends Stack> 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<MagePermanent> {
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;
}
}
}

View file

@ -1,9 +1,12 @@
package org.mage.card.constants; package org.mage.plugins.card.constants;
import java.awt.Rectangle;
public class Constants { public class Constants {
public static final String RESOURCE_PATH = "/images"; public static final String RESOURCE_PATH = "/images";
public static final String RESOURCE_PATH_MANA = resourcePath("mana"); public static final String RESOURCE_PATH_MANA = resourcePath("mana");
public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149);
/** /**
* Build resource path. * Build resource path.

View file

@ -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

View file

@ -45,7 +45,6 @@
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>

View file

@ -31,7 +31,7 @@ public class ThemePluginImpl implements ThemePlugin {
} }
public String toString() { public String toString() {
return "[Theme plugin by nantuko, version 0.1]"; return "[Theme plugin, version 0.1]";
} }
public void apply(Map<String, JComponent> ui) { public void apply(Map<String, JComponent> ui) {