mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Merge
This commit is contained in:
commit
4653a53078
127 changed files with 3754 additions and 788 deletions
Binary file not shown.
|
@ -50,23 +50,17 @@ import java.util.logging.Logger;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.Box;
|
import javax.swing.*;
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JDesktopPane;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JLayeredPane;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JToolBar.Separator;
|
import javax.swing.JToolBar.Separator;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
|
|
||||||
|
import com.sun.java.swing.Painter;
|
||||||
|
import mage.cards.decks.Deck;
|
||||||
import mage.client.cards.CardsStorage;
|
import mage.client.cards.CardsStorage;
|
||||||
import mage.client.components.MageComponents;
|
import mage.client.components.MageComponents;
|
||||||
|
import mage.client.components.MageJDesktop;
|
||||||
|
import mage.client.components.MageRoundPane;
|
||||||
import mage.client.components.arcane.ManaSymbols;
|
import mage.client.components.arcane.ManaSymbols;
|
||||||
|
import mage.client.constants.Constants.DeckEditorMode;
|
||||||
import mage.client.dialog.*;
|
import mage.client.dialog.*;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
import mage.client.remote.Session;
|
import mage.client.remote.Session;
|
||||||
|
@ -122,6 +116,7 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
UIManager.put("desktop", new Color(0,0,0,0));
|
||||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||||
//MageSynthStyleFactory f = new MageSynthStyleFactory(SynthLookAndFeel.getStyleFactory());
|
//MageSynthStyleFactory f = new MageSynthStyleFactory(SynthLookAndFeel.getStyleFactory());
|
||||||
//SynthLookAndFeel.setStyleFactory(f);
|
//SynthLookAndFeel.setStyleFactory(f);
|
||||||
|
@ -145,60 +140,12 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
desktopPane.add(pickNumber, JLayeredPane.POPUP_LAYER);
|
desktopPane.add(pickNumber, JLayeredPane.POPUP_LAYER);
|
||||||
session.getUI().addComponent(MageComponents.DESKTOP_PANE, desktopPane);
|
session.getUI().addComponent(MageComponents.DESKTOP_PANE, desktopPane);
|
||||||
|
|
||||||
JComponent cardInfoPane = Plugins.getInstance().getCardInfoPane();
|
|
||||||
cardInfoPane.setSize(161, 221);
|
|
||||||
cardInfoPane.setPreferredSize(new Dimension(161, 221));
|
|
||||||
cardInfoPane.setVisible(false);
|
|
||||||
session.getUI().addComponent(MageComponents.CARD_INFO_PANE, cardInfoPane);
|
|
||||||
desktopPane.add(cardInfoPane, JLayeredPane.POPUP_LAYER);
|
|
||||||
|
|
||||||
ManaSymbols.loadImages();
|
ManaSymbols.loadImages();
|
||||||
|
|
||||||
String filename = "/background.jpg";
|
addTooltipContainer();
|
||||||
try {
|
setBackground();
|
||||||
if (Plugins.getInstance().isThemePluginLoaded()) {
|
addMageLabel();
|
||||||
Map<String, JComponent> ui = new HashMap<String, JComponent>();
|
setAppIcon();
|
||||||
backgroundPane = (ImagePanel) Plugins.getInstance().updateTablePanel(ui);
|
|
||||||
} else {
|
|
||||||
InputStream is = this.getClass().getResourceAsStream(filename);
|
|
||||||
BufferedImage background = ImageIO.read(is);
|
|
||||||
backgroundPane = new ImagePanel(background, ImagePanel.SCALED);
|
|
||||||
}
|
|
||||||
backgroundPane.setSize(1024, 768);
|
|
||||||
desktopPane.add(backgroundPane, JLayeredPane.DEFAULT_LAYER);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = "/label-mage.png";
|
|
||||||
try {
|
|
||||||
InputStream is = this.getClass().getResourceAsStream(filename);
|
|
||||||
|
|
||||||
float ratio = 1179.0f / 678.0f;
|
|
||||||
titleRectangle = new Rectangle(640, (int)(640 / ratio));
|
|
||||||
if (is != null) {
|
|
||||||
BufferedImage image = ImageIO.read(is);
|
|
||||||
//ImageIcon resized = new ImageIcon(image.getScaledInstance(titleRectangle.width, titleRectangle.height, java.awt.Image.SCALE_SMOOTH));
|
|
||||||
title = new JLabel();
|
|
||||||
title.setIcon(new ImageIcon(image));
|
|
||||||
backgroundPane.setLayout(null);
|
|
||||||
backgroundPane.add(title);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = "/icon-mage.png";
|
|
||||||
try {
|
|
||||||
InputStream is = this.getClass().getResourceAsStream(filename);
|
|
||||||
|
|
||||||
if (is != null) {
|
|
||||||
BufferedImage image = ImageIO.read(is);
|
|
||||||
setIconImage(image);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
desktopPane.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.DRAG_LAYER);
|
desktopPane.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.DRAG_LAYER);
|
||||||
|
|
||||||
|
@ -271,6 +218,77 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addTooltipContainer() {
|
||||||
|
final JEditorPane cardInfoPane = (JEditorPane) Plugins.getInstance().getCardInfoPane();
|
||||||
|
cardInfoPane.setSize(320, 201);
|
||||||
|
cardInfoPane.setLocation(40, 40);
|
||||||
|
cardInfoPane.setBackground(new Color(0,0,0,0));
|
||||||
|
|
||||||
|
MageRoundPane popupContainer = new MageRoundPane();
|
||||||
|
popupContainer.setLayout(null);
|
||||||
|
|
||||||
|
popupContainer.add(cardInfoPane);
|
||||||
|
popupContainer.setVisible(false);
|
||||||
|
popupContainer.setBounds(0, 0, 320 + 80, 201 + 80);
|
||||||
|
|
||||||
|
desktopPane.add(popupContainer, JLayeredPane.POPUP_LAYER);
|
||||||
|
|
||||||
|
session.getUI().addComponent(MageComponents.CARD_INFO_PANE, cardInfoPane);
|
||||||
|
session.getUI().addComponent(MageComponents.POPUP_CONTAINER, popupContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBackground() {
|
||||||
|
String filename = "/background.jpg";
|
||||||
|
try {
|
||||||
|
if (Plugins.getInstance().isThemePluginLoaded()) {
|
||||||
|
Map<String, JComponent> ui = new HashMap<String, JComponent>();
|
||||||
|
backgroundPane = (ImagePanel) Plugins.getInstance().updateTablePanel(ui);
|
||||||
|
} else {
|
||||||
|
InputStream is = this.getClass().getResourceAsStream(filename);
|
||||||
|
BufferedImage background = ImageIO.read(is);
|
||||||
|
backgroundPane = new ImagePanel(background, ImagePanel.SCALED);
|
||||||
|
}
|
||||||
|
backgroundPane.setSize(1024, 768);
|
||||||
|
desktopPane.add(backgroundPane, JLayeredPane.DEFAULT_LAYER);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMageLabel() {
|
||||||
|
String filename = "/label-mage.png";
|
||||||
|
try {
|
||||||
|
InputStream is = this.getClass().getResourceAsStream(filename);
|
||||||
|
|
||||||
|
float ratio = 1179.0f / 678.0f;
|
||||||
|
titleRectangle = new Rectangle(640, (int)(640 / ratio));
|
||||||
|
if (is != null) {
|
||||||
|
BufferedImage image = ImageIO.read(is);
|
||||||
|
//ImageIcon resized = new ImageIcon(image.getScaledInstance(titleRectangle.width, titleRectangle.height, java.awt.Image.SCALE_SMOOTH));
|
||||||
|
title = new JLabel();
|
||||||
|
title.setIcon(new ImageIcon(image));
|
||||||
|
backgroundPane.setLayout(null);
|
||||||
|
backgroundPane.add(title);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAppIcon() {
|
||||||
|
String filename = "/icon-mage.png";
|
||||||
|
try {
|
||||||
|
InputStream is = this.getClass().getResourceAsStream(filename);
|
||||||
|
|
||||||
|
if (is != null) {
|
||||||
|
BufferedImage image = ImageIO.read(is);
|
||||||
|
setIconImage(image);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) {
|
private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
Plugins.getInstance().downloadImage(CardsStorage.getAllCards());
|
Plugins.getInstance().downloadImage(CardsStorage.getAllCards());
|
||||||
}
|
}
|
||||||
|
@ -337,7 +355,7 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
desktopPane = new javax.swing.JDesktopPane();
|
desktopPane = new MageJDesktop();
|
||||||
tablesPane = new mage.client.table.TablesPane();
|
tablesPane = new mage.client.table.TablesPane();
|
||||||
gamePane = new mage.client.game.GamePane();
|
gamePane = new mage.client.game.GamePane();
|
||||||
deckEditorPane = new mage.client.deckeditor.DeckEditorPane();
|
deckEditorPane = new mage.client.deckeditor.DeckEditorPane();
|
||||||
|
@ -486,11 +504,10 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed
|
private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed
|
||||||
this.gamePane.setVisible(false);
|
this.gamePane.setVisible(false);
|
||||||
this.tablesPane.setVisible(false);
|
this.tablesPane.setVisible(false);
|
||||||
this.deckEditorPane.setVisible(true);
|
showDeckEditor(DeckEditorMode.Constructed, null, null);
|
||||||
this.deckEditorPane.showTables();
|
|
||||||
}//GEN-LAST:event_btnDeckEditorActionPerformed
|
}//GEN-LAST:event_btnDeckEditorActionPerformed
|
||||||
|
|
||||||
private void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed
|
private void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
PhasesDialog.main(new String[]{});
|
PhasesDialog.main(new String[]{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,6 +563,11 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
this.deckEditorPane.setVisible(false);
|
this.deckEditorPane.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showDeckEditor(DeckEditorMode mode, Deck deck, UUID tableId) {
|
||||||
|
this.deckEditorPane.setVisible(true);
|
||||||
|
this.deckEditorPane.show(mode, deck, tableId);
|
||||||
|
}
|
||||||
|
|
||||||
public static CombatDialog getCombatDialog() {
|
public static CombatDialog getCombatDialog() {
|
||||||
return combat;
|
return combat;
|
||||||
}
|
}
|
||||||
|
@ -595,7 +617,7 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
private javax.swing.JButton btnExit;
|
private javax.swing.JButton btnExit;
|
||||||
private javax.swing.JButton btnGames;
|
private javax.swing.JButton btnGames;
|
||||||
private mage.client.deckeditor.DeckEditorPane deckEditorPane;
|
private mage.client.deckeditor.DeckEditorPane deckEditorPane;
|
||||||
private static javax.swing.JDesktopPane desktopPane;
|
private static MageJDesktop desktopPane;
|
||||||
private mage.client.game.GamePane gamePane;
|
private mage.client.game.GamePane gamePane;
|
||||||
private javax.swing.JToolBar.Separator jSeparator1;
|
private javax.swing.JToolBar.Separator jSeparator1;
|
||||||
private javax.swing.JToolBar.Separator jSeparator2;
|
private javax.swing.JToolBar.Separator jSeparator2;
|
||||||
|
|
|
@ -6,7 +6,8 @@ public enum MageComponents {
|
||||||
NEW_TABLE_OK_BUTTON("btnOK"),
|
NEW_TABLE_OK_BUTTON("btnOK"),
|
||||||
TABLE_WAITING_START_BUTTON("btnStart"),
|
TABLE_WAITING_START_BUTTON("btnStart"),
|
||||||
DESKTOP_PANE("desktopPane"),
|
DESKTOP_PANE("desktopPane"),
|
||||||
CARD_INFO_PANE("cardInfoPane");
|
CARD_INFO_PANE("cardInfoPane"),
|
||||||
|
POPUP_CONTAINER("popupContainer");
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
MageComponents(String name) {
|
MageComponents(String name) {
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package mage.client.components;
|
||||||
|
|
||||||
|
import com.sun.java.swing.Painter;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides JDesktopPane settings for Nimbus LAF.
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class MageJDesktop extends JDesktopPane {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
if ("Nimbus".equals(UIManager.getLookAndFeel().getName())) {
|
||||||
|
UIDefaults map = new UIDefaults();
|
||||||
|
Painter painter = new Painter() {
|
||||||
|
|
||||||
|
Color color = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics2D g, Object c, int w, int h) {
|
||||||
|
g.setColor(color == null ? UIManager.getDefaults().getColor("desktop") : color);
|
||||||
|
g.fillRect(0,0,w,h);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
map.put("DesktopPane[Enabled].backgroundPainter", painter);
|
||||||
|
putClientProperty("Nimbus.Overrides", map);
|
||||||
|
}
|
||||||
|
super.updateUI();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package mage.client.components;
|
||||||
|
|
||||||
|
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||||
|
import org.jdesktop.swingx.graphics.ShadowRenderer;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mage round pane with transparency.
|
||||||
|
* Used for tooltips.
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class MageRoundPane extends JPanel {
|
||||||
|
|
||||||
|
private static int X_OFFSET = 30;
|
||||||
|
private static int Y_OFFSET = 30;
|
||||||
|
private BufferedImage shadow = null;
|
||||||
|
private Color backgroundColor = new Color(255, 255, 255, 220);
|
||||||
|
private int alpha = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
int x = X_OFFSET;
|
||||||
|
int y = Y_OFFSET;
|
||||||
|
int w = getWidth() - 2 * X_OFFSET;
|
||||||
|
int h = getHeight() - 2 * Y_OFFSET;
|
||||||
|
int arc = 10;
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
if (shadow != null) {
|
||||||
|
int xOffset = (shadow.getWidth() - w) / 2;
|
||||||
|
int yOffset = (shadow.getHeight() - h) / 2;
|
||||||
|
g2.drawImage(shadow, x - xOffset, y - yOffset, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// fill content
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add white translucent substrate
|
||||||
|
*/
|
||||||
|
/*if (alpha != 0) {
|
||||||
|
g2.setColor(new Color(255, 255, 255, alpha));
|
||||||
|
g2.fillRoundRect(x, y, w, h, arc, arc);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
g2.setColor(backgroundColor);
|
||||||
|
g2.fillRoundRect(x, y, w, h, arc, arc);
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// draw border
|
||||||
|
g2.setStroke(new BasicStroke(1.5f));
|
||||||
|
g2.setColor(Color.BLACK);
|
||||||
|
g2.drawRoundRect(x, y, w, h, arc, arc);
|
||||||
|
// ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBounds(int x, int y, int width, int height) {
|
||||||
|
super.setBounds(x, y, width, height);
|
||||||
|
|
||||||
|
int w = getWidth() - 2 * X_OFFSET;
|
||||||
|
int h = getHeight() - 2 * Y_OFFSET;
|
||||||
|
int arc = 10;
|
||||||
|
int shadowSize = 50;
|
||||||
|
|
||||||
|
shadow = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
|
||||||
|
Graphics2D g2 = shadow.createGraphics();
|
||||||
|
g2.setColor(Color.WHITE);
|
||||||
|
g2.fillRoundRect(0, 0, w, h, arc, arc);
|
||||||
|
g2.dispose();
|
||||||
|
|
||||||
|
ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f,
|
||||||
|
Color.GRAY);
|
||||||
|
shadow = renderer.createShadow(shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDialog(boolean bShow) {
|
||||||
|
setVisible(bShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default UID.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -82,4 +82,11 @@ public final class Constants {
|
||||||
public static final String imageBaseDir = "plugins" + File.separator + "images" + File.separator;
|
public static final String imageBaseDir = "plugins" + File.separator + "images" + File.separator;
|
||||||
public static final String IMAGE_PROPERTIES_FILE = "image.url.properties";
|
public static final String IMAGE_PROPERTIES_FILE = "image.url.properties";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum DeckEditorMode {
|
||||||
|
Constructed,
|
||||||
|
Limited,
|
||||||
|
Sideboard
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ public class DeckGenerator {
|
||||||
private static final int MIN_SOURCE = 16;
|
private static final int MIN_SOURCE = 16;
|
||||||
private static final int MAX_NON_BASIC_SOURCE = DECK_LANDS / 2;
|
private static final int MAX_NON_BASIC_SOURCE = DECK_LANDS / 2;
|
||||||
|
|
||||||
|
private static final boolean GENERATE_RANDOM_BASIC_LAND = true;
|
||||||
|
|
||||||
private static Deck deck = new Deck();
|
private static Deck deck = new Deck();
|
||||||
private static String manaSource;
|
private static String manaSource;
|
||||||
|
|
||||||
|
@ -283,19 +285,19 @@ public class DeckGenerator {
|
||||||
private static Card getBestBasicLand(ColoredManaSymbol color) {
|
private static Card getBestBasicLand(ColoredManaSymbol color) {
|
||||||
manaSource = color.toString();
|
manaSource = color.toString();
|
||||||
if (color.equals(ColoredManaSymbol.G)) {
|
if (color.equals(ColoredManaSymbol.G)) {
|
||||||
return CardImpl.createCard(Sets.findCard("Forest"));
|
return CardImpl.createCard(Sets.findCard("Forest", GENERATE_RANDOM_BASIC_LAND));
|
||||||
}
|
}
|
||||||
if (color.equals(ColoredManaSymbol.R)) {
|
if (color.equals(ColoredManaSymbol.R)) {
|
||||||
return CardImpl.createCard(Sets.findCard("Mountain"));
|
return CardImpl.createCard(Sets.findCard("Mountain", GENERATE_RANDOM_BASIC_LAND));
|
||||||
}
|
}
|
||||||
if (color.equals(ColoredManaSymbol.B)) {
|
if (color.equals(ColoredManaSymbol.B)) {
|
||||||
return CardImpl.createCard(Sets.findCard("Swamp"));
|
return CardImpl.createCard(Sets.findCard("Swamp", GENERATE_RANDOM_BASIC_LAND));
|
||||||
}
|
}
|
||||||
if (color.equals(ColoredManaSymbol.U)) {
|
if (color.equals(ColoredManaSymbol.U)) {
|
||||||
return CardImpl.createCard(Sets.findCard("Island"));
|
return CardImpl.createCard(Sets.findCard("Island", GENERATE_RANDOM_BASIC_LAND));
|
||||||
}
|
}
|
||||||
if (color.equals(ColoredManaSymbol.W)) {
|
if (color.equals(ColoredManaSymbol.W)) {
|
||||||
return CardImpl.createCard(Sets.findCard("Plains"));
|
return CardImpl.createCard(Sets.findCard("Plains", GENERATE_RANDOM_BASIC_LAND));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.1" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
|
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
|
||||||
<SyntheticProperties>
|
<SyntheticProperties>
|
||||||
|
|
|
@ -37,10 +37,13 @@ package mage.client.deckeditor;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import mage.cards.decks.Deck;
|
||||||
|
|
||||||
import mage.client.MagePane;
|
import mage.client.MagePane;
|
||||||
|
import mage.client.constants.Constants.DeckEditorMode;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,8 +73,8 @@ public class DeckEditorPane extends MagePane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showTables() {
|
public void show(DeckEditorMode mode, Deck deck, UUID tableId) {
|
||||||
this.deckEditorPanel1.showDeckEditor();
|
this.deckEditorPanel1.showDeckEditor(mode, deck, tableId);
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ package mage.client.deckeditor;
|
||||||
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckCardLists;
|
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
import mage.client.util.Event;
|
import mage.client.util.Event;
|
||||||
|
@ -49,14 +48,13 @@ import mage.view.CardsView;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import mage.client.constants.Constants.DeckEditorMode;
|
||||||
import mage.sets.Sets;
|
import mage.sets.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,6 +67,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
private JFileChooser fcImportDeck;
|
private JFileChooser fcImportDeck;
|
||||||
private Deck deck = new Deck();
|
private Deck deck = new Deck();
|
||||||
private boolean isShowCardInfo = false;
|
private boolean isShowCardInfo = false;
|
||||||
|
private UUID tableId;
|
||||||
|
|
||||||
/** Creates new form DeckEditorPanel */
|
/** Creates new form DeckEditorPanel */
|
||||||
public DeckEditorPanel() {
|
public DeckEditorPanel() {
|
||||||
|
@ -85,10 +84,18 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
jSplitPane1.setOpaque(false);
|
jSplitPane1.setOpaque(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDeckEditor() {
|
public void showDeckEditor(DeckEditorMode mode, Deck deck, UUID tableId) {
|
||||||
|
if (deck != null)
|
||||||
|
this.deck = deck;
|
||||||
|
this.tableId = tableId;
|
||||||
|
showDeckEditor(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDeckEditor(DeckEditorMode mode) {
|
||||||
this.cardSelector.loadCards(this.bigCard);
|
this.cardSelector.loadCards(this.bigCard);
|
||||||
this.cardSelector.setVisible(true);
|
this.cardSelector.setVisible(true);
|
||||||
this.jPanel1.setVisible(true);
|
this.jPanel1.setVisible(true);
|
||||||
|
this.btnSubmit.setVisible(mode == DeckEditorMode.Sideboard);
|
||||||
this.cardSelector.getCardsList().clearCardEventListeners();
|
this.cardSelector.getCardsList().clearCardEventListeners();
|
||||||
this.cardSelector.getCardsList().addCardEventListener(
|
this.cardSelector.getCardsList().addCardEventListener(
|
||||||
new Listener<Event> () {
|
new Listener<Event> () {
|
||||||
|
@ -132,6 +139,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
refreshDeck();
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
@ -172,6 +180,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
btnNew = new javax.swing.JButton();
|
btnNew = new javax.swing.JButton();
|
||||||
btnExit = new javax.swing.JButton();
|
btnExit = new javax.swing.JButton();
|
||||||
btnImport = new javax.swing.JButton();
|
btnImport = new javax.swing.JButton();
|
||||||
|
btnSubmit = new javax.swing.JButton();
|
||||||
|
|
||||||
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||||
jSplitPane1.setResizeWeight(0.5);
|
jSplitPane1.setResizeWeight(0.5);
|
||||||
|
@ -229,6 +238,14 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
btnSubmit.setText("Submit");
|
||||||
|
btnSubmit.setName("btnSubmit"); // NOI18N
|
||||||
|
btnSubmit.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
btnSubmitActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||||
jPanel1.setLayout(jPanel1Layout);
|
jPanel1.setLayout(jPanel1Layout);
|
||||||
jPanel1Layout.setHorizontalGroup(
|
jPanel1Layout.setHorizontalGroup(
|
||||||
|
@ -253,7 +270,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
.addComponent(btnExit))
|
.addComponent(btnExit))
|
||||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(btnImport)))
|
.addComponent(btnImport)
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(btnSubmit)))
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
jPanel1Layout.setVerticalGroup(
|
jPanel1Layout.setVerticalGroup(
|
||||||
|
@ -270,7 +289,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
.addComponent(btnNew)
|
.addComponent(btnNew)
|
||||||
.addComponent(btnExit))
|
.addComponent(btnExit))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(btnImport)
|
.addComponent(btnImport)
|
||||||
|
.addComponent(btnSubmit))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE)
|
||||||
.addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
@ -383,6 +404,11 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
fcImportDeck.setSelectedFile(null);
|
fcImportDeck.setSelectedFile(null);
|
||||||
}//GEN-LAST:event_btnImportActionPerformed
|
}//GEN-LAST:event_btnImportActionPerformed
|
||||||
|
|
||||||
|
private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
MageFrame.getSession().submitDeck(tableId, deck.getDeckCardLists());
|
||||||
|
this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
public DeckImporter getDeckImporter(String file) {
|
public DeckImporter getDeckImporter(String file) {
|
||||||
if (file.toLowerCase().endsWith("dec"))
|
if (file.toLowerCase().endsWith("dec"))
|
||||||
return new DecDeckImporter();
|
return new DecDeckImporter();
|
||||||
|
@ -410,6 +436,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
private JComponent cardInfoPane;
|
private JComponent cardInfoPane;
|
||||||
|
private javax.swing.JButton btnSubmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeckFilter extends FileFilter {
|
class DeckFilter extends FileFilter {
|
||||||
|
|
|
@ -138,7 +138,6 @@ public class JoinTableDialog extends MageDialog {
|
||||||
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
||||||
Session session = MageFrame.getSession();
|
Session session = MageFrame.getSession();
|
||||||
try {
|
try {
|
||||||
PhaseManager.getInstance().setName(this.newPlayerPanel.getPlayerName());
|
|
||||||
joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), Sets.loadDeck(this.newPlayerPanel.getDeckFile()));
|
joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), Sets.loadDeck(this.newPlayerPanel.getDeckFile()));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
handleError(ex);
|
handleError(ex);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace pref="358" max="32767" attributes="0"/>
|
<EmptySpace pref="395" max="32767" attributes="0"/>
|
||||||
<Component id="btnOK" min="-2" max="-2" attributes="0"/>
|
<Component id="btnOK" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
|
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="lbDeckType" min="-2" max="-2" attributes="0"/>
|
<Component id="lbDeckType" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="426" max="32767" attributes="0"/>
|
<EmptySpace pref="463" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
@ -41,17 +41,22 @@
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="spnNumPlayers" min="-2" pref="90" max="-2" attributes="0"/>
|
<Component id="spnNumPlayers" min="-2" pref="57" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="lblRange" min="-2" max="-2" attributes="1"/>
|
<Component id="lblRange" min="-2" max="-2" attributes="1"/>
|
||||||
<Component id="cbRange" min="-2" pref="141" max="-2" attributes="1"/>
|
<Component id="cbRange" min="-2" pref="143" max="-2" attributes="1"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="lblAttack" min="-2" max="-2" attributes="0"/>
|
<Component id="lblAttack" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="cbAttackOption" alignment="0" min="-2" pref="199" max="-2" attributes="0"/>
|
<Component id="cbAttackOption" pref="235" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="spnNumWins" min="-2" pref="50" max="-2" attributes="0"/>
|
||||||
|
<Component id="lblNumWins" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="lblGameType" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="lblGameType" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
@ -61,34 +66,34 @@
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator2" pref="466" max="32767" attributes="0"/>
|
<Component id="jSeparator2" pref="503" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="396" max="32767" attributes="0"/>
|
<EmptySpace pref="433" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="player1Panel" pref="466" max="32767" attributes="0"/>
|
<Component id="player1Panel" pref="503" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="399" max="32767" attributes="0"/>
|
<EmptySpace pref="436" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator1" pref="466" max="32767" attributes="0"/>
|
<Component id="jSeparator1" pref="503" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="pnlOtherPlayers" alignment="0" min="-2" pref="486" max="-2" attributes="0"/>
|
<Component id="pnlOtherPlayers" alignment="0" min="-2" pref="486" max="-2" attributes="0"/>
|
||||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator3" pref="466" max="32767" attributes="0"/>
|
<Component id="jSeparator3" pref="503" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -105,13 +110,9 @@
|
||||||
<Component id="lblGameType" min="-2" max="-2" attributes="0"/>
|
<Component id="lblGameType" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
<Component id="cbGameType" min="-2" max="-2" attributes="0"/>
|
<Component id="cbGameType" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
|
||||||
<Component id="lblAttack" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
|
||||||
<Component id="cbAttackOption" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
|
@ -122,8 +123,19 @@
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
<Component id="cbRange" min="-2" max="-2" attributes="0"/>
|
<Component id="cbRange" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="lblAttack" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
|
<Component id="cbAttackOption" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="lblNumWins" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
|
<Component id="spnNumWins" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
|
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
|
@ -132,21 +144,21 @@
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="pnlOtherPlayers" pref="83" max="32767" attributes="0"/>
|
<Component id="pnlOtherPlayers" pref="97" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator1" pref="4" max="32767" attributes="0"/>
|
<Component id="jSeparator1" pref="19" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnOK" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnOK" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="223" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="223" max="-2" attributes="0"/>
|
||||||
<Component id="jSeparator3" min="-2" max="-2" attributes="0"/>
|
<Component id="jSeparator3" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="149" max="32767" attributes="0"/>
|
<EmptySpace pref="159" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -260,5 +272,18 @@
|
||||||
<Property name="text" type="java.lang.String" value="Other Players"/>
|
<Property name="text" type="java.lang.String" value="Other Players"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="lblNumWins">
|
||||||
|
<Properties>
|
||||||
|
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||||
|
<ComponentRef name="spnNumWins"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" value="Wins"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JSpinner" name="spnNumWins">
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spnNumWinsnumPlayersChanged"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
@ -53,6 +53,7 @@ import mage.client.remote.Session;
|
||||||
import mage.client.table.TablePlayerPanel;
|
import mage.client.table.TablePlayerPanel;
|
||||||
import mage.client.util.Event;
|
import mage.client.util.Event;
|
||||||
import mage.client.util.Listener;
|
import mage.client.util.Listener;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.sets.Sets;
|
import mage.sets.Sets;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.view.GameTypeView;
|
import mage.view.GameTypeView;
|
||||||
|
@ -77,6 +78,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
/** Creates new form NewTableDialog */
|
/** Creates new form NewTableDialog */
|
||||||
public NewTableDialog() {
|
public NewTableDialog() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method is called from within the constructor to
|
/** This method is called from within the constructor to
|
||||||
|
@ -107,6 +109,8 @@ public class NewTableDialog extends MageDialog {
|
||||||
jLabel1 = new javax.swing.JLabel();
|
jLabel1 = new javax.swing.JLabel();
|
||||||
jSeparator3 = new javax.swing.JSeparator();
|
jSeparator3 = new javax.swing.JSeparator();
|
||||||
jLabel2 = new javax.swing.JLabel();
|
jLabel2 = new javax.swing.JLabel();
|
||||||
|
lblNumWins = new javax.swing.JLabel();
|
||||||
|
spnNumWins = new javax.swing.JSpinner();
|
||||||
|
|
||||||
setTitle("New Table");
|
setTitle("New Table");
|
||||||
|
|
||||||
|
@ -157,12 +161,21 @@ public class NewTableDialog extends MageDialog {
|
||||||
jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));
|
jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));
|
||||||
jLabel2.setText("Other Players");
|
jLabel2.setText("Other Players");
|
||||||
|
|
||||||
|
lblNumWins.setLabelFor(spnNumWins);
|
||||||
|
lblNumWins.setText("Wins");
|
||||||
|
|
||||||
|
spnNumWins.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||||
|
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||||
|
spnNumWinsnumPlayersChanged(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||||
getContentPane().setLayout(layout);
|
getContentPane().setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addContainerGap(358, Short.MAX_VALUE)
|
.addContainerGap(395, Short.MAX_VALUE)
|
||||||
.addComponent(btnOK)
|
.addComponent(btnOK)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(btnCancel)
|
.addComponent(btnCancel)
|
||||||
|
@ -170,7 +183,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(lbDeckType)
|
.addComponent(lbDeckType)
|
||||||
.addContainerGap(426, Short.MAX_VALUE))
|
.addContainerGap(463, Short.MAX_VALUE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
|
@ -178,43 +191,47 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(lblNumPlayers)
|
.addComponent(lblNumPlayers)
|
||||||
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGap(18, 18, 18)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(lblRange)
|
.addComponent(lblRange)
|
||||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGap(18, 18, 18)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(lblAttack)
|
.addComponent(lblAttack)
|
||||||
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(cbAttackOption, 0, 235, Short.MAX_VALUE))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(lblNumWins)))
|
||||||
.addComponent(lblGameType)
|
.addComponent(lblGameType)
|
||||||
.addComponent(cbDeckType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addComponent(cbDeckType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
.addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jLabel1)
|
.addComponent(jLabel1)
|
||||||
.addContainerGap(396, Short.MAX_VALUE))
|
.addContainerGap(433, Short.MAX_VALUE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
.addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jLabel2)
|
.addComponent(jLabel2)
|
||||||
.addContainerGap(399, Short.MAX_VALUE))
|
.addContainerGap(436, Short.MAX_VALUE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 486, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 486, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
.addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||||
.addContainerGap()))
|
.addContainerGap()))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
|
@ -229,11 +246,8 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGap(0, 0, 0)
|
.addGap(0, 0, 0)
|
||||||
.addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(lblAttack)
|
|
||||||
.addGap(0, 0, 0)
|
|
||||||
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(lblNumPlayers)
|
.addComponent(lblNumPlayers)
|
||||||
.addGap(0, 0, 0)
|
.addGap(0, 0, 0)
|
||||||
|
@ -241,7 +255,15 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(lblRange)
|
.addComponent(lblRange)
|
||||||
.addGap(0, 0, 0)
|
.addGap(0, 0, 0)
|
||||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(lblAttack)
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(lblNumWins)
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
@ -251,19 +273,19 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(jLabel2)
|
.addComponent(jLabel2)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 83, Short.MAX_VALUE)
|
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 4, Short.MAX_VALUE)
|
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(btnCancel)
|
.addComponent(btnCancel)
|
||||||
.addComponent(btnOK))
|
.addComponent(btnOK))
|
||||||
.addGap(0, 0, 0))
|
.addGap(6, 6, 6))
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(223, 223, 223)
|
.addGap(223, 223, 223)
|
||||||
.addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addContainerGap(149, Short.MAX_VALUE)))
|
.addContainerGap(159, Short.MAX_VALUE)))
|
||||||
);
|
);
|
||||||
|
|
||||||
pack();
|
pack();
|
||||||
|
@ -277,18 +299,16 @@ public class NewTableDialog extends MageDialog {
|
||||||
|
|
||||||
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
||||||
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
||||||
List<String> playerTypes = new ArrayList<String>();
|
MatchOptions options = new MatchOptions("Quick Start Game", gameType.getName());
|
||||||
playerTypes.add("Human");
|
options.getPlayerTypes().add("Human");
|
||||||
for (TablePlayerPanel player: players) {
|
for (TablePlayerPanel player: players) {
|
||||||
playerTypes.add(player.getPlayerType());
|
options.getPlayerTypes().add(player.getPlayerType());
|
||||||
}
|
}
|
||||||
table = session.createTable(
|
options.setDeckType((String) this.cbDeckType.getSelectedItem());
|
||||||
roomId,
|
options.setAttackOption((MultiplayerAttackOption) this.cbAttackOption.getSelectedItem());
|
||||||
gameType.getName(),
|
options.setRange((RangeOfInfluence) this.cbRange.getSelectedItem());
|
||||||
(String)this.cbDeckType.getSelectedItem(),
|
options.setWinsNeeded((Integer)this.spnNumWins.getValue());
|
||||||
playerTypes,
|
table = session.createTable(roomId, options);
|
||||||
(MultiplayerAttackOption)this.cbAttackOption.getSelectedItem(),
|
|
||||||
(RangeOfInfluence)this.cbRange.getSelectedItem());
|
|
||||||
try {
|
try {
|
||||||
if (session.joinTable(roomId, table.getTableId(), this.player1Panel.getPlayerName(), Sets.loadDeck(this.player1Panel.getDeckFile()))) {
|
if (session.joinTable(roomId, table.getTableId(), this.player1Panel.getPlayerName(), Sets.loadDeck(this.player1Panel.getDeckFile()))) {
|
||||||
for (TablePlayerPanel player: players) {
|
for (TablePlayerPanel player: players) {
|
||||||
|
@ -325,6 +345,10 @@ public class NewTableDialog extends MageDialog {
|
||||||
createPlayers(numPlayers);
|
createPlayers(numPlayers);
|
||||||
}//GEN-LAST:event_numPlayersChanged
|
}//GEN-LAST:event_numPlayersChanged
|
||||||
|
|
||||||
|
private void spnNumWinsnumPlayersChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumWinsnumPlayersChanged
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_spnNumWinsnumPlayersChanged
|
||||||
|
|
||||||
private void setGameOptions() {
|
private void setGameOptions() {
|
||||||
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
||||||
this.spnNumPlayers.setModel(new SpinnerNumberModel(gameType.getMinPlayers(), gameType.getMinPlayers(), gameType.getMaxPlayers(), 1));
|
this.spnNumPlayers.setModel(new SpinnerNumberModel(gameType.getMinPlayers(), gameType.getMinPlayers(), gameType.getMaxPlayers(), 1));
|
||||||
|
@ -423,10 +447,12 @@ public class NewTableDialog extends MageDialog {
|
||||||
private javax.swing.JLabel lblAttack;
|
private javax.swing.JLabel lblAttack;
|
||||||
private javax.swing.JLabel lblGameType;
|
private javax.swing.JLabel lblGameType;
|
||||||
private javax.swing.JLabel lblNumPlayers;
|
private javax.swing.JLabel lblNumPlayers;
|
||||||
|
private javax.swing.JLabel lblNumWins;
|
||||||
private javax.swing.JLabel lblRange;
|
private javax.swing.JLabel lblRange;
|
||||||
private mage.client.table.NewPlayerPanel player1Panel;
|
private mage.client.table.NewPlayerPanel player1Panel;
|
||||||
private javax.swing.JPanel pnlOtherPlayers;
|
private javax.swing.JPanel pnlOtherPlayers;
|
||||||
private javax.swing.JSpinner spnNumPlayers;
|
private javax.swing.JSpinner spnNumPlayers;
|
||||||
|
private javax.swing.JSpinner spnNumWins;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,12 +98,12 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
public void update(Map<UUID, PermanentView> battlefield) {
|
public void update(Map<UUID, PermanentView> battlefield) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
|
|
||||||
|
List<PermanentView> permanentsToAdd = new ArrayList<PermanentView>();
|
||||||
for (PermanentView permanent: battlefield.values()) {
|
for (PermanentView permanent: battlefield.values()) {
|
||||||
if (!permanents.containsKey(permanent.getId())) {
|
if (!permanents.containsKey(permanent.getId())) {
|
||||||
addPermanent(permanent);
|
permanentsToAdd.add(permanent);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
MagePermanent p = permanents.get(permanent.getId());
|
MagePermanent p = permanents.get(permanent.getId());
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
int s1 = permanent.getAttachments() == null ? 0 : permanent.getAttachments().size();
|
int s1 = permanent.getAttachments() == null ? 0 : permanent.getAttachments().size();
|
||||||
|
@ -115,10 +115,15 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
permanents.get(permanent.getId()).update(permanent);
|
permanents.get(permanent.getId()).update(permanent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int count = permanentsToAdd.size();
|
||||||
|
for (PermanentView permanent : permanentsToAdd) {
|
||||||
|
addPermanent(permanent, count);
|
||||||
|
}
|
||||||
|
|
||||||
for (Iterator<Entry<UUID, MagePermanent>> i = permanents.entrySet().iterator(); i.hasNext();) {
|
for (Iterator<Entry<UUID, MagePermanent>> i = permanents.entrySet().iterator(); i.hasNext();) {
|
||||||
Entry<UUID, MagePermanent> entry = i.next();
|
Entry<UUID, MagePermanent> entry = i.next();
|
||||||
if (!battlefield.containsKey(entry.getKey())) {
|
if (!battlefield.containsKey(entry.getKey())) {
|
||||||
removePermanent(entry.getKey());
|
removePermanent(entry.getKey(), 1);
|
||||||
i.remove();
|
i.remove();
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -150,12 +155,12 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPermanent(PermanentView permanent) {
|
private void addPermanent(PermanentView permanent, final int count) {
|
||||||
final MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId);
|
final MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId);
|
||||||
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
||||||
perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight)));
|
perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight)));
|
||||||
} else {
|
} else {
|
||||||
perm.setAlpha(0);
|
//perm.setAlpha(0);
|
||||||
}
|
}
|
||||||
permanents.put(permanent.getId(), perm);
|
permanents.put(permanent.getId(), perm);
|
||||||
|
|
||||||
|
@ -164,15 +169,16 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
moveToFront(perm);
|
moveToFront(perm);
|
||||||
perm.update(permanent);
|
perm.update(permanent);
|
||||||
} else {
|
} else {
|
||||||
Thread t = new Thread(new Runnable() {
|
Plugins.getInstance().onAddCard(perm, 1);
|
||||||
|
/*Thread t = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Plugins.getInstance().onAddCard(perm);
|
Plugins.getInstance().onAddCard(perm, count);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
threads.add(t);
|
threads.add(t);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +214,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removePermanent(UUID permanentId) {
|
private void removePermanent(UUID permanentId, final int count) {
|
||||||
for (Component c: this.getComponents()) {
|
for (Component c: this.getComponents()) {
|
||||||
final Component comp = c;
|
final Component comp = c;
|
||||||
if (comp instanceof Permanent) {
|
if (comp instanceof Permanent) {
|
||||||
|
@ -220,7 +226,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
||||||
Thread t = new Thread(new Runnable() {
|
Thread t = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Plugins.getInstance().onRemoveCard((MagePermanent)comp);
|
Plugins.getInstance().onRemoveCard((MagePermanent)comp, count);
|
||||||
BattlefieldPanel.this.remove(comp);
|
BattlefieldPanel.this.remove(comp);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ public interface MagePlugins {
|
||||||
int getGamesPlayed();
|
int getGamesPlayed();
|
||||||
void addGamesPlayed();
|
void addGamesPlayed();
|
||||||
Image getManaSymbolImage(String symbol);
|
Image getManaSymbolImage(String symbol);
|
||||||
void onAddCard(MagePermanent card);
|
void onAddCard(MagePermanent card, int count);
|
||||||
void onRemoveCard(MagePermanent card);
|
void onRemoveCard(MagePermanent card, int count);
|
||||||
JComponent getCardInfoPane();
|
JComponent getCardInfoPane();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.awt.*;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ import mage.cards.action.TransferData;
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.cards.BigCard;
|
import mage.client.cards.BigCard;
|
||||||
import mage.client.components.MageComponents;
|
import mage.client.components.MageComponents;
|
||||||
|
import mage.client.components.MageRoundPane;
|
||||||
import mage.client.game.PlayAreaPanel;
|
import mage.client.game.PlayAreaPanel;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
import mage.client.remote.Session;
|
import mage.client.remote.Session;
|
||||||
|
@ -130,9 +132,6 @@ public class MageActionCallback implements ActionCallback {
|
||||||
popup.show();
|
popup.show();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ThreadUtils.threadPool2.submit(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ThreadUtils.threadPool2.submit(new Runnable() {
|
ThreadUtils.threadPool2.submit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -142,38 +141,41 @@ public class MageActionCallback implements ActionCallback {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PopupFactory factory = PopupFactory.getSharedInstance();
|
|
||||||
((CardInfoPane)cardInfoPane).setCard(data.card);
|
|
||||||
cardInfoPane.setSize(161, 221);
|
|
||||||
cardInfoPane.setPreferredSize(new Dimension(161, 221));
|
|
||||||
popup = factory.getPopup(data.component, cardInfoPane, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40);
|
|
||||||
popup.show();
|
|
||||||
*/
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
|
||||||
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
||||||
((CardInfoPane) popup2).setCard(data.card);
|
((CardInfoPane) popup2).setCard(data.card);
|
||||||
Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40);
|
Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX - 40, (int) data.locationOnScreen.getY() + data.popupOffsetY - 40);
|
||||||
location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, popup2, parentComponent);
|
location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, popup2, parentComponent);
|
||||||
location.translate(-parentPoint.x, -parentPoint.y);
|
location.translate(-parentPoint.x, -parentPoint.y);
|
||||||
popup2.setLocation(location);
|
popupContainer.setLocation(location);
|
||||||
ThreadUtils.sleep(200);
|
ThreadUtils.sleep(200);
|
||||||
popup2.setVisible(true);
|
final Component c = session.getUI().getComponent(MageComponents.DESKTOP_PANE);
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
popupContainer.setVisible(true);
|
||||||
|
c.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e, TransferData data) {
|
public void mouseMoved(MouseEvent e, TransferData data) {
|
||||||
if (!Plugins.getInstance().isCardPluginLoaded()) {return;}
|
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
||||||
if (bigCard == null) {return;}
|
return;
|
||||||
|
}
|
||||||
|
if (bigCard == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MageCard card = (MageCard) data.component;
|
MageCard card = (MageCard) data.component;
|
||||||
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
||||||
|
@ -188,7 +190,8 @@ public class MageActionCallback implements ActionCallback {
|
||||||
bigCard.showTextComponent();
|
bigCard.showTextComponent();
|
||||||
} else {
|
} else {
|
||||||
bigCard.hideTextComponent();
|
bigCard.hideTextComponent();
|
||||||
};
|
}
|
||||||
|
;
|
||||||
} else {
|
} else {
|
||||||
JXPanel panel = GuiDisplayUtil.getDescription(card.getOriginal(), bigCard.getWidth(), bigCard.getHeight());
|
JXPanel panel = GuiDisplayUtil.getDescription(card.getOriginal(), bigCard.getWidth(), bigCard.getHeight());
|
||||||
panel.setVisible(true);
|
panel.setVisible(true);
|
||||||
|
@ -209,10 +212,10 @@ public class MageActionCallback implements ActionCallback {
|
||||||
jPopupMenu.setVisible(false);
|
jPopupMenu.setVisible(false);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
|
||||||
popup2.setVisible(false);
|
popupContainer.setVisible(false);
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
e2.printStackTrace();;
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,16 +169,16 @@ public class Plugins implements MagePlugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAddCard(MagePermanent card) {
|
public void onAddCard(MagePermanent card, int count) {
|
||||||
if (this.cardPlugin != null) {
|
if (this.cardPlugin != null) {
|
||||||
this.cardPlugin.onAddCard(card);
|
this.cardPlugin.onAddCard(card, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoveCard(MagePermanent card) {
|
public void onRemoveCard(MagePermanent card, int count) {
|
||||||
if (this.cardPlugin != null) {
|
if (this.cardPlugin != null) {
|
||||||
this.cardPlugin.onRemoveCard(card);
|
this.cardPlugin.onRemoveCard(card, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,12 @@ import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import mage.cards.decks.Deck;
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.chat.ChatPanel;
|
import mage.client.chat.ChatPanel;
|
||||||
|
import mage.client.constants.Constants.DeckEditorMode;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
|
import mage.client.util.GameManager;
|
||||||
import mage.interfaces.callback.CallbackClient;
|
import mage.interfaces.callback.CallbackClient;
|
||||||
import mage.interfaces.callback.ClientCallback;
|
import mage.interfaces.callback.ClientCallback;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
|
@ -43,6 +46,7 @@ import mage.view.AbilityPickerView;
|
||||||
import mage.view.ChatMessage;
|
import mage.view.ChatMessage;
|
||||||
import mage.view.GameClientMessage;
|
import mage.view.GameClientMessage;
|
||||||
import mage.view.GameView;
|
import mage.view.GameView;
|
||||||
|
import mage.view.TableClientMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -72,8 +76,9 @@ public class Client implements CallbackClient {
|
||||||
logger.info(callback.getMessageId() + " - " + callback.getMethod());
|
logger.info(callback.getMessageId() + " - " + callback.getMethod());
|
||||||
try {
|
try {
|
||||||
if (callback.getMethod().equals("startGame")) {
|
if (callback.getMethod().equals("startGame")) {
|
||||||
UUID[] data = (UUID[]) callback.getData();
|
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||||
gameStarted(data[0], data[1]);
|
GameManager.getInstance().setCurrentPlayerUUID(message.getPlayerId());
|
||||||
|
gameStarted(message.getGameId(), message.getPlayerId());
|
||||||
}
|
}
|
||||||
else if (callback.getMethod().equals("replayGame")) {
|
else if (callback.getMethod().equals("replayGame")) {
|
||||||
replayGame();
|
replayGame();
|
||||||
|
@ -152,6 +157,10 @@ public class Client implements CallbackClient {
|
||||||
logger.warning("message out of sequence - ignoring");
|
logger.warning("message out of sequence - ignoring");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (callback.getMethod().equals("sideboard")) {
|
||||||
|
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||||
|
sideboard(message.getDeck(), message.getTableId());
|
||||||
|
}
|
||||||
messageId = callback.getMessageId();
|
messageId = callback.getMessageId();
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
|
@ -197,6 +206,10 @@ public class Client implements CallbackClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sideboard(Deck deck, UUID tableId) {
|
||||||
|
frame.showDeckEditor(DeckEditorMode.Sideboard, deck, tableId);
|
||||||
|
}
|
||||||
|
|
||||||
private void handleException(Exception ex) {
|
private void handleException(Exception ex) {
|
||||||
logger.log(Level.SEVERE, "Client error\n", ex);
|
logger.log(Level.SEVERE, "Client error\n", ex);
|
||||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Unrecoverable client error. Disconnecting", "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Unrecoverable client error. Disconnecting", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
|
@ -40,8 +40,6 @@ import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.chat.ChatPanel;
|
import mage.client.chat.ChatPanel;
|
||||||
|
@ -50,6 +48,7 @@ import mage.client.game.GamePanel;
|
||||||
import mage.client.util.Config;
|
import mage.client.util.Config;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
import mage.interfaces.MageException;
|
import mage.interfaces.MageException;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.interfaces.Server;
|
import mage.interfaces.Server;
|
||||||
import mage.interfaces.ServerState;
|
import mage.interfaces.ServerState;
|
||||||
import mage.interfaces.callback.CallbackClientDaemon;
|
import mage.interfaces.callback.CallbackClientDaemon;
|
||||||
|
@ -396,9 +395,9 @@ public class Session {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableView createTable(UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public TableView createTable(UUID roomId, MatchOptions matchOptions) {
|
||||||
try {
|
try {
|
||||||
return server.createTable(sessionId, roomId, gameType, deckType, playerTypes, attackOption, range);
|
return server.createTable(sessionId, roomId, matchOptions);
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
handleRemoteException(ex);
|
handleRemoteException(ex);
|
||||||
} catch (MageException ex) {
|
} catch (MageException ex) {
|
||||||
|
@ -456,7 +455,7 @@ public class Session {
|
||||||
|
|
||||||
public boolean startGame(UUID roomId, UUID tableId) {
|
public boolean startGame(UUID roomId, UUID tableId) {
|
||||||
try {
|
try {
|
||||||
server.startGame(sessionId, roomId, tableId);
|
server.startMatch(sessionId, roomId, tableId);
|
||||||
return true;
|
return true;
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
handleRemoteException(ex);
|
handleRemoteException(ex);
|
||||||
|
@ -466,6 +465,20 @@ public class Session {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean submitDeck(UUID tableId, DeckCardLists deck) {
|
||||||
|
try {
|
||||||
|
server.submitDeck(sessionId, tableId, deck);
|
||||||
|
return true;
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
handleRemoteException(ex);
|
||||||
|
} catch (MageException ex) {
|
||||||
|
handleMageException(ex);
|
||||||
|
} catch (GameException ex) {
|
||||||
|
handleGameException(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean concedeGame(UUID gameId) {
|
public boolean concedeGame(UUID gameId) {
|
||||||
try {
|
try {
|
||||||
server.concedeGame(gameId, sessionId);
|
server.concedeGame(gameId, sessionId);
|
||||||
|
|
|
@ -37,9 +37,7 @@ package mage.client.table;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
@ -53,8 +51,9 @@ import javax.swing.JComponent;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import mage.Constants.MultiplayerAttackOption;
|
||||||
|
import mage.Constants.RangeOfInfluence;
|
||||||
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.components.MageComponents;
|
import mage.client.components.MageComponents;
|
||||||
import mage.client.dialog.JoinTableDialog;
|
import mage.client.dialog.JoinTableDialog;
|
||||||
|
@ -63,6 +62,7 @@ import mage.client.dialog.TableWaitingDialog;
|
||||||
import mage.client.remote.MageRemoteException;
|
import mage.client.remote.MageRemoteException;
|
||||||
import mage.client.remote.Session;
|
import mage.client.remote.Session;
|
||||||
import mage.client.util.ButtonColumn;
|
import mage.client.util.ButtonColumn;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.sets.Sets;
|
import mage.sets.Sets;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.view.TableView;
|
import mage.view.TableView;
|
||||||
|
@ -280,16 +280,14 @@ public class TablesPanel extends javax.swing.JPanel implements Observer {
|
||||||
private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed
|
private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed
|
||||||
TableView table;
|
TableView table;
|
||||||
try {
|
try {
|
||||||
List<String> playerTypes = new ArrayList<String>();
|
MatchOptions options = new MatchOptions("1", "Two Player Duel");
|
||||||
playerTypes.add("Human");
|
options.getPlayerTypes().add("Human");
|
||||||
playerTypes.add("Computer - default");
|
options.getPlayerTypes().add("Computer - default");
|
||||||
table = session.createTable(
|
options.setDeckType("Limited");
|
||||||
roomId,
|
options.setAttackOption(MultiplayerAttackOption.LEFT);
|
||||||
"Two Player Duel",
|
options.setRange(RangeOfInfluence.ALL);
|
||||||
"Constructed",
|
options.setWinsNeeded(1);
|
||||||
playerTypes,
|
table = session.createTable(roomId, options);
|
||||||
null, null
|
|
||||||
);
|
|
||||||
session.joinTable(
|
session.joinTable(
|
||||||
roomId,
|
roomId,
|
||||||
table.getTableId(),
|
table.getTableId(),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package mage.client.util;
|
package mage.client.util;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls game state on client side.
|
* Controls game state on client side.
|
||||||
*
|
*
|
||||||
|
@ -7,15 +9,27 @@ package mage.client.util;
|
||||||
*/
|
*/
|
||||||
public class GameManager {
|
public class GameManager {
|
||||||
private static GameManager fInstance = new GameManager();
|
private static GameManager fInstance = new GameManager();
|
||||||
|
|
||||||
public static GameManager getInstance() {
|
public static GameManager getInstance() {
|
||||||
return fInstance;
|
return fInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStackSize(int stackSize) {
|
public void setStackSize(int stackSize) {
|
||||||
this.stackSize = stackSize;
|
this.stackSize = stackSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStackSize() {
|
public int getStackSize() {
|
||||||
return stackSize;
|
return stackSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int stackSize;
|
public UUID getCurrentPlayerUUID() {
|
||||||
|
return currentPlayerUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPlayerUUID(UUID currentPlayerUUID) {
|
||||||
|
this.currentPlayerUUID = currentPlayerUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int stackSize;
|
||||||
|
private UUID currentPlayerUUID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package mage.client.util;
|
||||||
|
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.view.GameView;
|
import mage.view.GameView;
|
||||||
|
import mage.view.PlayerView;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
public class PhaseManager {
|
public class PhaseManager {
|
||||||
|
@ -51,21 +53,27 @@ public class PhaseManager {
|
||||||
put("End Turn - play instants and activated abilities.", END_OF_TURN_OTHERS);
|
put("End Turn - play instants and activated abilities.", END_OF_TURN_OTHERS);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private String yourName;
|
|
||||||
|
|
||||||
public static PhaseManager getInstance() {
|
public static PhaseManager getInstance() {
|
||||||
return fInstance;
|
return fInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String yourName) {
|
|
||||||
this.yourName = yourName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSkip(GameView gameView, String message) {
|
public boolean isSkip(GameView gameView, String message) {
|
||||||
if (GameManager.getInstance().getStackSize() > 0) {
|
if (GameManager.getInstance().getStackSize() > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Map<String, String> map = gameView.getActivePlayerName().equals(DEFAULT_PLAYER_NAME) ? mapYou : mapOthers;
|
UUID activePlayer = null;
|
||||||
|
Map<String, String> map = mapOthers;
|
||||||
|
for (PlayerView playerView : gameView.getPlayers()) {
|
||||||
|
if (playerView.isActive()) {
|
||||||
|
activePlayer = playerView.getPlayerId();
|
||||||
|
if (activePlayer.equals(GameManager.getInstance().getCurrentPlayerUUID())) {
|
||||||
|
map = mapYou;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (activePlayer == null) {
|
||||||
|
throw new IllegalStateException("No active player found.");
|
||||||
|
}
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
if (message.equals(entry.getKey())) {
|
if (message.equals(entry.getKey())) {
|
||||||
Preferences prefs = MageFrame.getPreferences();
|
Preferences prefs = MageFrame.getPreferences();
|
||||||
|
|
|
@ -14,7 +14,8 @@ import org.jdesktop.swingx.JXPanel;
|
||||||
|
|
||||||
public class GuiDisplayUtil {
|
public class GuiDisplayUtil {
|
||||||
private static final Font cardNameFont = new Font("Calibri", Font.BOLD, 15);
|
private static final Font cardNameFont = new Font("Calibri", Font.BOLD, 15);
|
||||||
private static Insets DEFAULT_INSETS = new Insets(0,0, 68, 15);
|
private static Insets DEFAULT_INSETS = new Insets(0, 0, 70, 25);
|
||||||
|
private static Insets COMPONENT_INSETS = new Insets(0, 0, 40, 40);
|
||||||
|
|
||||||
public static JXPanel getDescription(CardView card, int width, int height) {
|
public static JXPanel getDescription(CardView card, int width, int height) {
|
||||||
JXPanel descriptionPanel = new JXPanel();
|
JXPanel descriptionPanel = new JXPanel();
|
||||||
|
@ -127,12 +128,12 @@ public class GuiDisplayUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Point keepComponentInsideParent(Point l, Point parentPoint, Component c, Component parent) {
|
public static Point keepComponentInsideParent(Point l, Point parentPoint, Component c, Component parent) {
|
||||||
int dx = parentPoint.x + parent.getWidth() - DEFAULT_INSETS.right;
|
int dx = parentPoint.x + parent.getWidth() - DEFAULT_INSETS.right - COMPONENT_INSETS.right;
|
||||||
if (l.x + c.getWidth() > dx) {
|
if (l.x + c.getWidth() > dx) {
|
||||||
l.x = dx - c.getWidth();
|
l.x = dx - c.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int dy = parentPoint.y + parent.getHeight() - DEFAULT_INSETS.bottom;
|
int dy = parentPoint.y + parent.getHeight() - DEFAULT_INSETS.bottom - COMPONENT_INSETS.bottom;
|
||||||
if (l.y + c.getHeight() > dy) {
|
if (l.y + c.getHeight() > dy) {
|
||||||
l.y = Math.max(10, dy - c.getHeight());
|
l.y = Math.max(10, dy - c.getHeight());
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,16 +28,14 @@
|
||||||
|
|
||||||
package mage.interfaces;
|
package mage.interfaces;
|
||||||
|
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import java.rmi.Remote;
|
import java.rmi.Remote;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
import mage.interfaces.callback.CallbackServer;
|
import mage.interfaces.callback.CallbackServer;
|
||||||
import mage.view.GameTypeView;
|
|
||||||
import mage.view.TableView;
|
import mage.view.TableView;
|
||||||
import mage.view.GameView;
|
import mage.view.GameView;
|
||||||
|
|
||||||
|
@ -54,8 +52,9 @@ public interface Server extends Remote, CallbackServer {
|
||||||
public ServerState getServerState() throws RemoteException, MageException;
|
public ServerState getServerState() throws RemoteException, MageException;
|
||||||
|
|
||||||
//table methods
|
//table methods
|
||||||
public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) throws RemoteException, MageException;
|
public TableView createTable(UUID sessionId, UUID roomId, MatchOptions matchOptions) throws RemoteException, MageException;
|
||||||
public boolean joinTable(UUID sessionId, UUID roomId, UUID tableId, String name, DeckCardLists deckList) throws RemoteException, MageException, GameException;
|
public boolean joinTable(UUID sessionId, UUID roomId, UUID tableId, String name, DeckCardLists deckList) throws RemoteException, MageException, GameException;
|
||||||
|
public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws RemoteException, MageException, GameException;
|
||||||
public boolean watchTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
public boolean watchTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
||||||
public boolean replayTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
public boolean replayTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
||||||
public void leaveTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
public void leaveTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
||||||
|
@ -77,7 +76,7 @@ public interface Server extends Remote, CallbackServer {
|
||||||
public UUID getMainRoomId() throws RemoteException, MageException;
|
public UUID getMainRoomId() throws RemoteException, MageException;
|
||||||
|
|
||||||
//game methods
|
//game methods
|
||||||
public void startGame(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
public void startMatch(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException;
|
||||||
public void joinGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
public void joinGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
||||||
public void watchGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
public void watchGame(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
||||||
public void stopWatching(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
public void stopWatching(UUID gameId, UUID sessionId) throws RemoteException, MageException;
|
||||||
|
|
|
@ -31,7 +31,7 @@ public interface CardPlugin extends Plugin {
|
||||||
void downloadImages(Set<Card> allCards);
|
void downloadImages(Set<Card> allCards);
|
||||||
void downloadSymbols();
|
void downloadSymbols();
|
||||||
Image getManaSymbolImage(String symbol);
|
Image getManaSymbolImage(String symbol);
|
||||||
void onAddCard(MagePermanent card);
|
void onAddCard(MagePermanent card, int count);
|
||||||
void onRemoveCard(MagePermanent card);
|
void onRemoveCard(MagePermanent card, int count);
|
||||||
JComponent getCardInfoPane();
|
JComponent getCardInfoPane();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class AbilityView extends CardView {
|
||||||
this.sourceName = sourceName;
|
this.sourceName = sourceName;
|
||||||
this.sourceCard = sourceCard;
|
this.sourceCard = sourceCard;
|
||||||
this.rules = new ArrayList<String>();
|
this.rules = new ArrayList<String>();
|
||||||
rules.add(formatRule(ability.getRule()));
|
rules.add(ability.getRule(sourceName));
|
||||||
this.power = "";
|
this.power = "";
|
||||||
this.toughness = "";
|
this.toughness = "";
|
||||||
this.loyalty = "";
|
this.loyalty = "";
|
||||||
|
@ -60,13 +60,6 @@ public class AbilityView extends CardView {
|
||||||
this.art = "";
|
this.art = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String formatRule(String rule) {
|
|
||||||
String newRule = rule.replace("{this}", this.sourceName);
|
|
||||||
newRule.replace("{source}", this.sourceName);
|
|
||||||
return newRule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardView getSourceCard() {
|
public CardView getSourceCard() {
|
||||||
return this.sourceCard;
|
return this.sourceCard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class CardView implements Serializable {
|
||||||
public CardView(Card card) {
|
public CardView(Card card) {
|
||||||
this.id = card.getId();
|
this.id = card.getId();
|
||||||
this.name = card.getName();
|
this.name = card.getName();
|
||||||
this.rules = formatRules(card.getRules());
|
this.rules = card.getRules();
|
||||||
if (card instanceof Permanent) {
|
if (card instanceof Permanent) {
|
||||||
this.power = Integer.toString(card.getPower().getValue());
|
this.power = Integer.toString(card.getPower().getValue());
|
||||||
this.toughness = Integer.toString(card.getToughness().getValue());
|
this.toughness = Integer.toString(card.getToughness().getValue());
|
||||||
|
@ -118,7 +118,7 @@ public class CardView implements Serializable {
|
||||||
CardView(Token token) {
|
CardView(Token token) {
|
||||||
this.id = token.getId();
|
this.id = token.getId();
|
||||||
this.name = token.getName();
|
this.name = token.getName();
|
||||||
this.rules = formatRules(token.getAbilities().getRules());
|
this.rules = token.getAbilities().getRules(this.name);
|
||||||
this.power = token.getPower().toString();
|
this.power = token.getPower().toString();
|
||||||
this.toughness = token.getToughness().toString();
|
this.toughness = token.getToughness().toString();
|
||||||
this.loyalty = token.getLoyalty().toString();
|
this.loyalty = token.getLoyalty().toString();
|
||||||
|
@ -143,19 +143,19 @@ public class CardView implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> formatRules(List<String> rules) {
|
// protected List<String> formatRules(List<String> rules) {
|
||||||
List<String> newRules = new ArrayList<String>();
|
// List<String> newRules = new ArrayList<String>();
|
||||||
for (String rule: rules) {
|
// for (String rule: rules) {
|
||||||
newRules.add(formatRule(rule));
|
// newRules.add(formatRule(rule));
|
||||||
}
|
// }
|
||||||
return newRules;
|
// return newRules;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected String formatRule(String rule) {
|
// protected String formatRule(String rule) {
|
||||||
String replace = rule.replace("{this}", this.name);
|
// String replace = rule.replace("{this}", this.name);
|
||||||
replace = replace.replace("{source}", this.name);
|
// replace = replace.replace("{source}", this.name);
|
||||||
return replace;
|
// return replace;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
package mage.view;
|
package mage.view;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import mage.game.GameType;
|
import mage.game.match.MatchType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -45,7 +45,7 @@ public class GameTypeView implements Serializable {
|
||||||
private boolean useRange;
|
private boolean useRange;
|
||||||
private boolean useAttackOption;
|
private boolean useAttackOption;
|
||||||
|
|
||||||
public GameTypeView(GameType gameType) {
|
public GameTypeView(MatchType gameType) {
|
||||||
this.name = gameType.getName();
|
this.name = gameType.getName();
|
||||||
this.minPlayers = gameType.getMinPlayers();
|
this.minPlayers = gameType.getMinPlayers();
|
||||||
this.maxPlayers = gameType.getMaxPlayers();
|
this.maxPlayers = gameType.getMaxPlayers();
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class StackAbilityView extends CardView {
|
||||||
this.sourceName = sourceName;
|
this.sourceName = sourceName;
|
||||||
this.sourceCard = sourceCard;
|
this.sourceCard = sourceCard;
|
||||||
this.rules = new ArrayList<String>();
|
this.rules = new ArrayList<String>();
|
||||||
rules.add(formatRule(ability.getRule()));
|
rules.add(ability.getRule(sourceName));
|
||||||
this.power = ability.getPower().toString();
|
this.power = ability.getPower().toString();
|
||||||
this.toughness = ability.getToughness().toString();
|
this.toughness = ability.getToughness().toString();
|
||||||
this.loyalty = ability.getLoyalty().toString();
|
this.loyalty = ability.getLoyalty().toString();
|
||||||
|
@ -60,13 +60,6 @@ public class StackAbilityView extends CardView {
|
||||||
setTargets(ability.getTargets());
|
setTargets(ability.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String formatRule(String rule) {
|
|
||||||
String newRule = rule.replace("{this}", this.sourceName);
|
|
||||||
newRule.replace("{source}", this.sourceName);
|
|
||||||
return newRule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardView getSourceCard() {
|
public CardView getSourceCard() {
|
||||||
return this.sourceCard;
|
return this.sourceCard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,63 +26,46 @@
|
||||||
* or implied, of BetaSteward_at_googlemail.com.
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mage.game;
|
package mage.view;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.UUID;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.players.Player;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class MatchImpl implements Match {
|
public class TableClientMessage implements Serializable {
|
||||||
|
|
||||||
protected List<MatchPlayer> players = new ArrayList<MatchPlayer>();
|
private Deck deck;
|
||||||
protected List<Game> games = new ArrayList<Game>();
|
private UUID tableId;
|
||||||
protected int winsNeeded;
|
private UUID gameId;
|
||||||
protected int maxPlayers;
|
private UUID playerId;
|
||||||
protected int minPlayers;
|
|
||||||
|
|
||||||
public MatchImpl(int winsNeeded) {
|
public TableClientMessage(Deck deck, UUID tableId) {
|
||||||
this.winsNeeded = winsNeeded;
|
this.deck = deck;
|
||||||
|
this.tableId = tableId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public TableClientMessage(UUID gameId, UUID playerId) {
|
||||||
public List<MatchPlayer> getPlayers() {
|
this.gameId = gameId;
|
||||||
return players;
|
this.playerId = playerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Deck getDeck() {
|
||||||
public void addPlayer(Player player, Deck deck) {
|
return deck;
|
||||||
MatchPlayer mPlayer = new MatchPlayer(player, deck);
|
|
||||||
players.add(mPlayer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public UUID getTableId() {
|
||||||
public void startMatch() {
|
return tableId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public UUID getGameId() {
|
||||||
public boolean isMatchOver() {
|
return gameId;
|
||||||
for (MatchPlayer player: players) {
|
|
||||||
if (player.getWins() >= winsNeeded) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public UUID getPlayerId() {
|
||||||
public int getMaxPlayers() {
|
return playerId;
|
||||||
return this.maxPlayers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinPlayers() {
|
|
||||||
return this.minPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -287,8 +287,11 @@ abstract public class Animation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void showCard(final MagePermanent card) {
|
static public void showCard(final MagePermanent card, int count) {
|
||||||
new Animation(600) {
|
if (count == 0) {
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
new Animation(600 / count) {
|
||||||
protected void start () {
|
protected void start () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,8 +307,11 @@ abstract public class Animation {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void hideCard(final MagePermanent card) {
|
static public void hideCard(final MagePermanent card, int count) {
|
||||||
new Animation(600) {
|
if (count == 0) {
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
new Animation(600 / count) {
|
||||||
protected void start () {
|
protected void start () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
static private final float rotCenterToBottomCorner = 0.7071067811865475244008443621048f;
|
static private final float rotCenterToBottomCorner = 0.7071067811865475244008443621048f;
|
||||||
|
|
||||||
public CardView gameCard;
|
public CardView gameCard;
|
||||||
public PermanentView gamePermanent;
|
//public List<CardPanel> attachedPanels = new ArrayList();
|
||||||
public CardPanel attachedToPanel;
|
private List<MagePermanent> links = new ArrayList<MagePermanent>();
|
||||||
public List<CardPanel> attachedPanels = new ArrayList();
|
|
||||||
public double tappedAngle = 0;
|
public double tappedAngle = 0;
|
||||||
public ScaledImagePanel imagePanel;
|
public ScaledImagePanel imagePanel;
|
||||||
public ImagePanel overlayPanel;
|
public ImagePanel overlayPanel;
|
||||||
|
@ -101,8 +100,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
this.isPermanent = this.gameCard instanceof PermanentView;
|
this.isPermanent = this.gameCard instanceof PermanentView;
|
||||||
|
|
||||||
if (isPermanent) {
|
if (isPermanent) {
|
||||||
this.gamePermanent = (PermanentView) this.gameCard;
|
this.hasSickness = ((PermanentView) this.gameCard).hasSummoningSickness();
|
||||||
this.hasSickness = this.gamePermanent.hasSummoningSickness();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//for container debug (don't remove)
|
//for container debug (don't remove)
|
||||||
|
@ -416,6 +414,13 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
@Override
|
@Override
|
||||||
public void setAlpha(float alpha) {
|
public void setAlpha(float alpha) {
|
||||||
this.alpha = alpha;
|
this.alpha = alpha;
|
||||||
|
if (alpha == 0) {
|
||||||
|
this.ptText.setVisible(false);
|
||||||
|
this.titleText.setVisible(false);
|
||||||
|
} else if (alpha == 1.0f) {
|
||||||
|
this.ptText.setVisible(true);
|
||||||
|
this.titleText.setVisible(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAlpha() {
|
public float getAlpha() {
|
||||||
|
@ -449,12 +454,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MagePermanent> getLinks() {
|
public List<MagePermanent> getLinks() {
|
||||||
List<MagePermanent> list = new ArrayList<MagePermanent>();
|
return links;
|
||||||
if (attachedPanels == null) return list;
|
|
||||||
for (MagePermanent p : attachedPanels) {
|
|
||||||
list.add(p);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -438,9 +438,9 @@ public class CardPluginImpl implements CardPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAddCard(MagePermanent card) {
|
public void onAddCard(MagePermanent card, int count) {
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
Animation.showCard((CardPanel) card);
|
Animation.showCard((CardPanel) card, count > 0 ? count : 1);
|
||||||
try {
|
try {
|
||||||
while ((card).getAlpha() + 0.05f < 1) {
|
while ((card).getAlpha() + 0.05f < 1) {
|
||||||
Thread.sleep(30);
|
Thread.sleep(30);
|
||||||
|
@ -452,9 +452,9 @@ public class CardPluginImpl implements CardPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoveCard(MagePermanent card) {
|
public void onRemoveCard(MagePermanent card, int count) {
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
Animation.hideCard((CardPanel) card);
|
Animation.hideCard((CardPanel) card, count > 0 ? count : 1);
|
||||||
try {
|
try {
|
||||||
while ((card).getAlpha() - 0.05f > 0) {
|
while ((card).getAlpha() - 0.05f > 0) {
|
||||||
Thread.sleep(30);
|
Thread.sleep(30);
|
||||||
|
|
|
@ -26,7 +26,6 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
||||||
UI.setHTMLEditorKit(this);
|
UI.setHTMLEditorKit(this);
|
||||||
setEditable(false);
|
setEditable(false);
|
||||||
setBackground(Color.white);
|
setBackground(Color.white);
|
||||||
setSize(170, Integer.MAX_VALUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCard(final CardView card) {
|
public void setCard(final CardView card) {
|
||||||
|
@ -76,12 +75,12 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
||||||
buffer.append("px'>");
|
buffer.append("px'>");
|
||||||
buffer.append(castingCost);
|
buffer.append(castingCost);
|
||||||
buffer.append("</td></tr></table>");
|
buffer.append("</td></tr></table>");
|
||||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'><tr><td>");
|
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'><tr><td style='margin-left: 1px'>");
|
||||||
buffer.append(getTypes(card));
|
buffer.append(getTypes(card));
|
||||||
buffer.append("</td><td align='right'>");
|
buffer.append("</td><td align='right'>");
|
||||||
switch (card.getRarity()) {
|
switch (card.getRarity()) {
|
||||||
case RARE:
|
case RARE:
|
||||||
buffer.append("<b color='#E1D519'>");
|
buffer.append("<b color='#FFBF00'>");
|
||||||
break;
|
break;
|
||||||
case UNCOMMON:
|
case UNCOMMON:
|
||||||
buffer.append("<b color='silver'>");
|
buffer.append("<b color='silver'>");
|
||||||
|
@ -96,6 +95,20 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
||||||
buffer.append(card.getExpansionSetCode().toUpperCase());
|
buffer.append(card.getExpansionSetCode().toUpperCase());
|
||||||
buffer.append("</td></tr></table>");
|
buffer.append("</td></tr></table>");
|
||||||
|
|
||||||
|
String pt = "";
|
||||||
|
if (CardUtil.isCreature(card)) {
|
||||||
|
pt = card.getPower() + "/" + card.getToughness();
|
||||||
|
} else if (CardUtil.isPlaneswalker(card)) {
|
||||||
|
pt = card.getLoyalty().toString();
|
||||||
|
}
|
||||||
|
if (pt.length() > 0) {
|
||||||
|
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%' valign='bottom'><tr><td>");
|
||||||
|
buffer.append("<b>");
|
||||||
|
buffer.append(pt);
|
||||||
|
buffer.append("</b>");
|
||||||
|
buffer.append("</td></tr></table>");
|
||||||
|
}
|
||||||
|
|
||||||
String legal = "";
|
String legal = "";
|
||||||
if (rulings.size() > 0) {
|
if (rulings.size() > 0) {
|
||||||
legal = legal.replaceAll("#([^#]+)#", "<i>$1</i>");
|
legal = legal.replaceAll("#([^#]+)#", "<i>$1</i>");
|
||||||
|
@ -110,27 +123,12 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legal.length() > 0) {
|
if (legal.length() > 0) {
|
||||||
buffer.append("<br>");
|
//buffer.append("<br>");
|
||||||
legal = legal.replaceAll("\\{this\\}", card.getName());
|
legal = legal.replaceAll("\\{this\\}", card.getName());
|
||||||
legal = legal.replaceAll("\\{source\\}", card.getName());
|
legal = legal.replaceAll("\\{source\\}", card.getName());
|
||||||
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, smallImages));
|
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, smallImages));
|
||||||
}
|
}
|
||||||
|
|
||||||
String pt = "";
|
|
||||||
if (CardUtil.isCreature(card)) {
|
|
||||||
pt = card.getPower() + "/" + card.getToughness();
|
|
||||||
} else if (CardUtil.isPlaneswalker(card)) {
|
|
||||||
pt = card.getLoyalty().toString();
|
|
||||||
}
|
|
||||||
if (pt.length() > 0) {
|
|
||||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%' valign='bottom'><tr><td>");
|
|
||||||
buffer.append("</td><td align='right'>");
|
|
||||||
buffer.append("<b>");
|
|
||||||
buffer.append(pt);
|
|
||||||
buffer.append("</b>");
|
|
||||||
buffer.append("</td></tr></table>");
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.append("<br></body></html>");
|
buffer.append("<br></body></html>");
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -59,7 +60,7 @@ public class FreeForAll extends GameImpl<FreeForAll> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GameType getGameType() {
|
public MatchType getGameType() {
|
||||||
return new FreeForAllType();
|
return new FreeForAllType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchImpl;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class FreeForAllMatch extends MatchImpl<FreeForAll> {
|
||||||
|
|
||||||
|
public FreeForAllMatch(MatchOptions options) {
|
||||||
|
super(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startGame() throws GameException {
|
||||||
|
FreeForAll game = new FreeForAll(options.getAttackOption(), options.getRange());
|
||||||
|
initGame(game);
|
||||||
|
games.add(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,11 +28,13 @@
|
||||||
|
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class FreeForAllType extends GameType {
|
public class FreeForAllType extends MatchType<FreeForAllType> {
|
||||||
|
|
||||||
public FreeForAllType() {
|
public FreeForAllType() {
|
||||||
this.name = "Free For All";
|
this.name = "Free For All";
|
||||||
|
@ -42,4 +44,13 @@ public class FreeForAllType extends GameType {
|
||||||
this.useAttackOption = true;
|
this.useAttackOption = true;
|
||||||
this.useRange = true;
|
this.useRange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected FreeForAllType(final FreeForAllType matchType) {
|
||||||
|
super(matchType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FreeForAllType copy() {
|
||||||
|
return new FreeForAllType(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchType;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -39,7 +40,7 @@ import mage.game.turn.TurnMod;
|
||||||
public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
||||||
|
|
||||||
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
||||||
super(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL);
|
super(attackOption, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TwoPlayerDuel(final TwoPlayerDuel game) {
|
public TwoPlayerDuel(final TwoPlayerDuel game) {
|
||||||
|
@ -47,7 +48,7 @@ public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GameType getGameType() {
|
public MatchType getGameType() {
|
||||||
return new TwoPlayerDuelType();
|
return new TwoPlayerDuelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +63,8 @@ public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
protected void init(UUID choosingPlayerId) {
|
||||||
super.init();
|
super.init(choosingPlayerId);
|
||||||
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
|
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,13 @@
|
||||||
|
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class TwoPlayerDuelType extends GameType {
|
public class TwoPlayerDuelType extends MatchType<TwoPlayerDuelType> {
|
||||||
|
|
||||||
public TwoPlayerDuelType() {
|
public TwoPlayerDuelType() {
|
||||||
this.name = "Two Player Duel";
|
this.name = "Two Player Duel";
|
||||||
|
@ -43,4 +45,13 @@ public class TwoPlayerDuelType extends GameType {
|
||||||
this.useRange = false;
|
this.useRange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TwoPlayerDuelType(final TwoPlayerDuelType matchType) {
|
||||||
|
super(matchType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TwoPlayerDuelType copy() {
|
||||||
|
return new TwoPlayerDuelType(this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.game;
|
||||||
|
|
||||||
|
import mage.game.match.MatchImpl;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class TwoPlayerMatch extends MatchImpl<TwoPlayerDuel> {
|
||||||
|
|
||||||
|
public TwoPlayerMatch(MatchOptions options) {
|
||||||
|
super(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startGame() throws GameException {
|
||||||
|
TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange());
|
||||||
|
initGame(game);
|
||||||
|
games.add(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -86,6 +86,7 @@ import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.common.FilterLandCard;
|
import mage.filter.common.FilterLandCard;
|
||||||
import mage.filter.common.FilterNonlandCard;
|
import mage.filter.common.FilterNonlandCard;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.Table;
|
||||||
import mage.game.combat.CombatGroup;
|
import mage.game.combat.CombatGroup;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -111,7 +112,6 @@ import mage.util.TreeNode;
|
||||||
public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> implements Player {
|
public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> implements Player {
|
||||||
|
|
||||||
private final static transient Logger logger = Logging.getLogger(ComputerPlayer.class.getName());
|
private final static transient Logger logger = Logging.getLogger(ComputerPlayer.class.getName());
|
||||||
private boolean abort;
|
|
||||||
private transient Map<Mana, Card> unplayable = new TreeMap<Mana, Card>();
|
private transient Map<Mana, Card> unplayable = new TreeMap<Mana, Card>();
|
||||||
private transient List<Card> playableNonInstant = new ArrayList<Card>();
|
private transient List<Card> playableNonInstant = new ArrayList<Card>();
|
||||||
private transient List<Card> playableInstant = new ArrayList<Card>();
|
private transient List<Card> playableInstant = new ArrayList<Card>();
|
||||||
|
@ -128,7 +128,6 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
||||||
|
|
||||||
public ComputerPlayer(final ComputerPlayer player) {
|
public ComputerPlayer(final ComputerPlayer player) {
|
||||||
super(player);
|
super(player);
|
||||||
this.abort = player.abort;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -768,6 +767,12 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
||||||
return super.getAvailableManaProducers(game);
|
return super.getAvailableManaProducers(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sideboard(Table table) {
|
||||||
|
//TODO: improve this
|
||||||
|
table.fireSubmitDeckEvent(playerId, deck);
|
||||||
|
}
|
||||||
|
|
||||||
protected Attackers getPotentialAttackers(Game game) {
|
protected Attackers getPotentialAttackers(Game game) {
|
||||||
logger.fine("getAvailableAttackers");
|
logger.fine("getAvailableAttackers");
|
||||||
Attackers attackers = new Attackers();
|
Attackers attackers = new Attackers();
|
||||||
|
|
|
@ -53,6 +53,7 @@ import mage.cards.decks.Deck;
|
||||||
import mage.choices.ChoiceImpl;
|
import mage.choices.ChoiceImpl;
|
||||||
import mage.filter.common.FilterCreatureForCombat;
|
import mage.filter.common.FilterCreatureForCombat;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.Table;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.TargetAmount;
|
import mage.target.TargetAmount;
|
||||||
|
@ -71,8 +72,6 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
|
|
||||||
final transient PlayerResponse response = new PlayerResponse();
|
final transient PlayerResponse response = new PlayerResponse();
|
||||||
|
|
||||||
private boolean abort;
|
|
||||||
|
|
||||||
protected static FilterCreatureForCombat filter = new FilterCreatureForCombat();
|
protected static FilterCreatureForCombat filter = new FilterCreatureForCombat();
|
||||||
protected static Choice replacementEffectChoice = new ChoiceImpl(true);
|
protected static Choice replacementEffectChoice = new ChoiceImpl(true);
|
||||||
|
|
||||||
|
@ -89,7 +88,6 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
|
|
||||||
public HumanPlayer(final HumanPlayer player) {
|
public HumanPlayer(final HumanPlayer player) {
|
||||||
super(player);
|
super(player);
|
||||||
this.abort = player.abort;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void waitForResponse() {
|
protected void waitForResponse() {
|
||||||
|
@ -474,6 +472,11 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
return response.getInteger();
|
return response.getInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sideboard(Table table) {
|
||||||
|
table.fireSideboardEvent(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
protected void specialAction(Game game) {
|
protected void specialAction(Game game) {
|
||||||
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId);
|
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId);
|
||||||
game.fireGetChoiceEvent(playerId, name, specialActions.values());
|
game.fireGetChoiceEvent(playerId, name, specialActions.values());
|
||||||
|
@ -540,6 +543,8 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HumanPlayer copy() {
|
public HumanPlayer copy() {
|
||||||
return new HumanPlayer(this);
|
return new HumanPlayer(this);
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
<playerType name="Computer - minimax hybrid" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>
|
<playerType name="Computer - minimax hybrid" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>
|
||||||
</playerTypes>
|
</playerTypes>
|
||||||
<gameTypes>
|
<gameTypes>
|
||||||
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerDuel" typeName="mage.game.TwoPlayerDuelType"/>
|
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>
|
||||||
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAll" typeName="mage.game.FreeForAllType"/>
|
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
|
||||||
</gameTypes>
|
</gameTypes>
|
||||||
<deckTypes>
|
<deckTypes>
|
||||||
<deckType name="Constructed" jar="mage-deck-constructed.jar" className="mage.deck.Constructed"/>
|
<deckType name="Constructed" jar="mage-deck-constructed.jar" className="mage.deck.Constructed"/>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -35,7 +35,7 @@ import java.io.FilenameFilter;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import mage.game.GameType;
|
import mage.game.match.MatchType;
|
||||||
import mage.server.game.DeckValidatorFactory;
|
import mage.server.game.DeckValidatorFactory;
|
||||||
import mage.server.game.GameFactory;
|
import mage.server.game.GameFactory;
|
||||||
import mage.server.game.PlayerFactory;
|
import mage.server.game.PlayerFactory;
|
||||||
|
@ -119,11 +119,11 @@ public class Main {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameType loadGameType(GamePlugin plugin) {
|
private static MatchType loadGameType(GamePlugin plugin) {
|
||||||
try {
|
try {
|
||||||
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
||||||
logger.info("Loading game type: " + plugin.getClassName());
|
logger.info("Loading game type: " + plugin.getClassName());
|
||||||
return (GameType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
logger.log(Level.SEVERE, "Game type not found:" + plugin.getJar() + " - check plugin folder");
|
logger.log(Level.SEVERE, "Game type not found:" + plugin.getJar() + " - check plugin folder");
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
|
|
@ -39,11 +39,10 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
import mage.interfaces.MageException;
|
import mage.interfaces.MageException;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.interfaces.Server;
|
import mage.interfaces.Server;
|
||||||
import mage.interfaces.ServerState;
|
import mage.interfaces.ServerState;
|
||||||
import mage.interfaces.callback.ClientCallback;
|
import mage.interfaces.callback.ClientCallback;
|
||||||
|
@ -56,7 +55,6 @@ import mage.server.game.ReplayManager;
|
||||||
import mage.server.game.TableManager;
|
import mage.server.game.TableManager;
|
||||||
import mage.server.util.ThreadExecutor;
|
import mage.server.util.ThreadExecutor;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.view.CardView;
|
|
||||||
import mage.view.ChatMessage.MessageColor;
|
import mage.view.ChatMessage.MessageColor;
|
||||||
import mage.view.GameView;
|
import mage.view.GameView;
|
||||||
import mage.view.TableView;
|
import mage.view.TableView;
|
||||||
|
@ -117,9 +115,9 @@ public class ServerImpl extends RemoteServer implements Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) throws MageException {
|
public TableView createTable(UUID sessionId, UUID roomId, MatchOptions options) throws MageException {
|
||||||
try {
|
try {
|
||||||
TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, gameType, deckType, playerTypes, attackOption, range);
|
TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, options);
|
||||||
logger.info("Table " + table.getTableId() + " created");
|
logger.info("Table " + table.getTableId() + " created");
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +159,21 @@ public class ServerImpl extends RemoteServer implements Server {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException {
|
||||||
|
try {
|
||||||
|
boolean ret = TableManager.getInstance().submitDeck(sessionId, tableId, deckList);
|
||||||
|
logger.info("Session " + sessionId + " submitted deck");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
if (ex instanceof GameException)
|
||||||
|
throw (GameException)ex;
|
||||||
|
handleException(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TableView> getTables(UUID roomId) throws MageException {
|
public List<TableView> getTables(UUID roomId) throws MageException {
|
||||||
try {
|
try {
|
||||||
|
@ -202,13 +215,13 @@ public class ServerImpl extends RemoteServer implements Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startGame(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
|
public void startMatch(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
|
||||||
try {
|
try {
|
||||||
rmiExecutor.execute(
|
rmiExecutor.execute(
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
TableManager.getInstance().startGame(sessionId, roomId, tableId);
|
TableManager.getInstance().startMatch(sessionId, roomId, tableId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -31,11 +31,13 @@ package mage.server;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import mage.cards.decks.Deck;
|
||||||
import mage.interfaces.callback.CallbackServerSession;
|
import mage.interfaces.callback.CallbackServerSession;
|
||||||
import mage.interfaces.callback.ClientCallback;
|
import mage.interfaces.callback.ClientCallback;
|
||||||
import mage.server.game.GameManager;
|
import mage.server.game.GameManager;
|
||||||
import mage.server.game.TableManager;
|
import mage.server.game.TableManager;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
|
import mage.view.TableClientMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -90,7 +92,11 @@ public class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gameStarted(final UUID gameId, final UUID playerId) {
|
public void gameStarted(final UUID gameId, final UUID playerId) {
|
||||||
fireCallback(new ClientCallback("startGame", new UUID[] {gameId, playerId}));
|
fireCallback(new ClientCallback("startGame", new TableClientMessage(gameId, playerId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sideboard(final Deck deck, final UUID tableId) {
|
||||||
|
fireCallback(new ClientCallback("sideboard", new TableClientMessage(deck, tableId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void watchGame(final UUID gameId) {
|
public void watchGame(final UUID gameId) {
|
||||||
|
|
|
@ -82,15 +82,17 @@ public class GameController implements GameCallback {
|
||||||
private Game game;
|
private Game game;
|
||||||
private UUID chatId;
|
private UUID chatId;
|
||||||
private UUID tableId;
|
private UUID tableId;
|
||||||
|
private UUID choosingPlayerId;
|
||||||
private Future<?> gameFuture;
|
private Future<?> gameFuture;
|
||||||
|
|
||||||
|
|
||||||
public GameController(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
|
public GameController(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId, UUID choosingPlayerId) {
|
||||||
gameSessionId = UUID.randomUUID();
|
gameSessionId = UUID.randomUUID();
|
||||||
this.sessionPlayerMap = sessionPlayerMap;
|
this.sessionPlayerMap = sessionPlayerMap;
|
||||||
chatId = ChatManager.getInstance().createChatSession();
|
chatId = ChatManager.getInstance().createChatSession();
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.tableId = tableId;
|
this.tableId = tableId;
|
||||||
|
this.choosingPlayerId = choosingPlayerId;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +188,7 @@ public class GameController implements GameCallback {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GameWorker worker = new GameWorker(game, this);
|
GameWorker worker = new GameWorker(game, choosingPlayerId, this);
|
||||||
gameFuture = gameExecutor.submit(worker);
|
gameFuture = gameExecutor.submit(worker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,17 +30,15 @@ package mage.server.game;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
import mage.game.match.Match;
|
||||||
import mage.Constants.RangeOfInfluence;
|
import mage.game.match.MatchOptions;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.game.GameType;
|
import mage.game.match.MatchType;
|
||||||
import mage.view.GameTypeView;
|
import mage.view.GameTypeView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,8 +50,8 @@ public class GameFactory {
|
||||||
private final static GameFactory INSTANCE = new GameFactory();
|
private final static GameFactory INSTANCE = new GameFactory();
|
||||||
private final static Logger logger = Logging.getLogger(GameFactory.class.getName());
|
private final static Logger logger = Logging.getLogger(GameFactory.class.getName());
|
||||||
|
|
||||||
private Map<String, Class<Game>> games = new HashMap<String, Class<Game>>();
|
private Map<String, Class<Match>> games = new HashMap<String, Class<Match>>();
|
||||||
private Map<String, GameType> gameTypes = new HashMap<String, GameType>();
|
private Map<String, MatchType> gameTypes = new HashMap<String, MatchType>();
|
||||||
private List<GameTypeView> gameTypeViews = new ArrayList<GameTypeView>();
|
private List<GameTypeView> gameTypeViews = new ArrayList<GameTypeView>();
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,31 +61,31 @@ public class GameFactory {
|
||||||
|
|
||||||
private GameFactory() {}
|
private GameFactory() {}
|
||||||
|
|
||||||
public Game createGame(String gameType, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public Match createMatch(String gameType, MatchOptions options) {
|
||||||
|
|
||||||
Game game;
|
Match match;
|
||||||
Constructor<Game> con;
|
Constructor<Match> con;
|
||||||
try {
|
try {
|
||||||
con = games.get(gameType).getConstructor(new Class[]{MultiplayerAttackOption.class, RangeOfInfluence.class});
|
con = games.get(gameType).getConstructor(new Class[]{MatchOptions.class});
|
||||||
game = con.newInstance(new Object[] {attackOption, range});
|
match = con.newInstance(new Object[] {options});
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
logger.info("Game created: " + game.getId().toString());
|
logger.info("Game created: " + gameType); // + game.getId().toString());
|
||||||
|
|
||||||
return game;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GameTypeView> getGameTypes() {
|
public List<GameTypeView> getGameTypes() {
|
||||||
return gameTypeViews;
|
return gameTypeViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGameType(String name, GameType gameType, Class game) {
|
public void addGameType(String name, MatchType matchType, Class game) {
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
this.games.put(name, game);
|
this.games.put(name, game);
|
||||||
this.gameTypes.put(name, gameType);
|
this.gameTypes.put(name, matchType);
|
||||||
this.gameTypeViews.add(new GameTypeView(gameType));
|
this.gameTypeViews.add(new GameTypeView(matchType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ public class GameManager {
|
||||||
|
|
||||||
private ConcurrentHashMap<UUID, GameController> gameControllers = new ConcurrentHashMap<UUID, GameController>();
|
private ConcurrentHashMap<UUID, GameController> gameControllers = new ConcurrentHashMap<UUID, GameController>();
|
||||||
|
|
||||||
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
|
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId, UUID choosingPlayerId) {
|
||||||
GameController gameController = new GameController(game, sessionPlayerMap, tableId);
|
GameController gameController = new GameController(game, sessionPlayerMap, tableId, choosingPlayerId);
|
||||||
gameControllers.put(game.getId(), gameController);
|
gameControllers.put(game.getId(), gameController);
|
||||||
return gameController.getSessionId();
|
return gameController.getSessionId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
package mage.server.game;
|
package mage.server.game;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -44,16 +45,18 @@ public class GameWorker implements Callable {
|
||||||
|
|
||||||
private GameCallback result;
|
private GameCallback result;
|
||||||
private Game game;
|
private Game game;
|
||||||
|
private UUID choosingPlayerId;
|
||||||
|
|
||||||
public GameWorker(Game game, GameCallback result) {
|
public GameWorker(Game game, UUID choosingPlayerId, GameCallback result) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
this.choosingPlayerId = choosingPlayerId;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call() {
|
public Object call() {
|
||||||
try {
|
try {
|
||||||
game.start();
|
game.start(choosingPlayerId);
|
||||||
result.gameResult(game.getWinner());
|
result.gameResult(game.getWinner());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
|
|
|
@ -30,10 +30,9 @@ package mage.server.game;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.view.TableView;
|
import mage.view.TableView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +43,7 @@ public interface GamesRoom extends Room {
|
||||||
|
|
||||||
public List<TableView> getTables();
|
public List<TableView> getTables();
|
||||||
public boolean joinTable(UUID sessionId, UUID tableId, String name, DeckCardLists deckList) throws GameException;
|
public boolean joinTable(UUID sessionId, UUID tableId, String name, DeckCardLists deckList) throws GameException;
|
||||||
public TableView createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range);
|
public TableView createTable(UUID sessionId, MatchOptions options);
|
||||||
public void removeTable(UUID sessionId, UUID tableId);
|
public void removeTable(UUID sessionId, UUID tableId);
|
||||||
public TableView getTable(UUID tableId);
|
public TableView getTable(UUID tableId);
|
||||||
public void leaveTable(UUID sessionId, UUID tableId);
|
public void leaveTable(UUID sessionId, UUID tableId);
|
||||||
|
|
|
@ -35,10 +35,9 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.view.TableView;
|
import mage.view.TableView;
|
||||||
|
|
||||||
|
@ -71,8 +70,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableView createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public TableView createTable(UUID sessionId, MatchOptions options) {
|
||||||
Table table = TableManager.getInstance().createTable(sessionId, gameType, deckType, playerTypes, attackOption, range);
|
Table table = TableManager.getInstance().createTable(sessionId, options);
|
||||||
tables.put(table.getId(), table);
|
tables.put(table.getId(), table);
|
||||||
return new TableView(table);
|
return new TableView(table);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ import java.io.ObjectInput;
|
||||||
import java.io.ObjectOutput;
|
import java.io.ObjectOutput;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -47,15 +46,18 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.Constants.TableState;
|
import mage.Constants.TableState;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
import mage.game.GameStates;
|
import mage.game.GameStates;
|
||||||
|
import mage.game.match.Match;
|
||||||
import mage.game.Seat;
|
import mage.game.Seat;
|
||||||
|
import mage.game.events.Listener;
|
||||||
|
import mage.game.events.TableEvent;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
|
import mage.game.match.MatchPlayer;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.server.ChatManager;
|
import mage.server.ChatManager;
|
||||||
import mage.server.Main;
|
import mage.server.Main;
|
||||||
|
@ -73,17 +75,36 @@ public class TableController {
|
||||||
|
|
||||||
private UUID sessionId;
|
private UUID sessionId;
|
||||||
private UUID chatId;
|
private UUID chatId;
|
||||||
private UUID gameId;
|
|
||||||
private Table table;
|
private Table table;
|
||||||
private Game game;
|
private Match match;
|
||||||
|
private MatchOptions options;
|
||||||
private ConcurrentHashMap<UUID, UUID> sessionPlayerMap = new ConcurrentHashMap<UUID, UUID>();
|
private ConcurrentHashMap<UUID, UUID> sessionPlayerMap = new ConcurrentHashMap<UUID, UUID>();
|
||||||
|
|
||||||
public TableController(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public TableController(UUID sessionId, MatchOptions options) {
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
chatId = ChatManager.getInstance().createChatSession();
|
chatId = ChatManager.getInstance().createChatSession();
|
||||||
game = GameFactory.getInstance().createGame(gameType, attackOption, range);
|
this.options = options;
|
||||||
gameId = game.getId();
|
match = GameFactory.getInstance().createMatch(options.getGameType(), options);
|
||||||
table = new Table(gameType, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes);
|
table = new Table(options.getGameType(), options.getName(), DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes());
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
table.addTableEventListener(
|
||||||
|
new Listener<TableEvent> () {
|
||||||
|
@Override
|
||||||
|
public void event(TableEvent event) {
|
||||||
|
switch (event.getEventType()) {
|
||||||
|
case SIDEBOARD:
|
||||||
|
sideboard(event.getPlayerId());
|
||||||
|
break;
|
||||||
|
case SUBMIT_DECK:
|
||||||
|
submitDeck(event.getPlayerId(), event.getDeck());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean joinTable(UUID sessionId, String name, DeckCardLists deckList) throws GameException {
|
public synchronized boolean joinTable(UUID sessionId, String name, DeckCardLists deckList) throws GameException {
|
||||||
|
@ -100,8 +121,7 @@ public class TableController {
|
||||||
}
|
}
|
||||||
|
|
||||||
Player player = createPlayer(name, deck, seat.getPlayerType());
|
Player player = createPlayer(name, deck, seat.getPlayerType());
|
||||||
game.loadCards(deck.getCards(), player.getId());
|
match.addPlayer(player, deck);
|
||||||
game.loadCards(deck.getSideboard(), player.getId());
|
|
||||||
table.joinTable(player, seat);
|
table.joinTable(player, seat);
|
||||||
logger.info("player joined " + player.getId());
|
logger.info("player joined " + player.getId());
|
||||||
//only add human players to sessionPlayerMap
|
//only add human players to sessionPlayerMap
|
||||||
|
@ -112,11 +132,29 @@ public class TableController {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized boolean submitDeck(UUID sessionId, DeckCardLists deckList) throws GameException {
|
||||||
|
if (table.getState() != TableState.SIDEBOARDING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MatchPlayer player = match.getPlayer(sessionPlayerMap.get(sessionId));
|
||||||
|
Deck deck = Deck.load(deckList);
|
||||||
|
if (!Main.server.isTestMode() && !validDeck(deck)) {
|
||||||
|
throw new GameException(player.getPlayer().getName() + " has an invalid deck for this format");
|
||||||
|
}
|
||||||
|
submitDeck(sessionPlayerMap.get(sessionId), deck);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitDeck(UUID playerId, Deck deck) {
|
||||||
|
MatchPlayer player = match.getPlayer(playerId);
|
||||||
|
player.submitDeck(deck);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean watchTable(UUID sessionId) {
|
public boolean watchTable(UUID sessionId) {
|
||||||
if (table.getState() != TableState.DUELING) {
|
if (table.getState() != TableState.DUELING) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SessionManager.getInstance().getSession(sessionId).watchGame(game.getId());
|
SessionManager.getInstance().getSession(sessionId).watchGame(match.getGame().getId());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +179,7 @@ public class TableController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Player createPlayer(String name, Deck deck, String playerType) {
|
private Player createPlayer(String name, Deck deck, String playerType) {
|
||||||
Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck, game.getRangeOfInfluence());
|
Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck, options.getRange());
|
||||||
logger.info("Player created " + player.getId());
|
logger.info("Player created " + player.getId());
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
@ -151,26 +189,66 @@ public class TableController {
|
||||||
table.leaveTable(sessionPlayerMap.get(sessionId));
|
table.leaveTable(sessionPlayerMap.get(sessionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void startGame(UUID sessionId) {
|
public synchronized void startMatch(UUID sessionId) {
|
||||||
if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) {
|
if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) {
|
||||||
try {
|
try {
|
||||||
table.initGame(game);
|
match.startMatch();
|
||||||
|
startGame(null);
|
||||||
} catch (GameException ex) {
|
} catch (GameException ex) {
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
GameManager.getInstance().createGameSession(game, sessionPlayerMap, table.getId());
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startGame(UUID choosingPlayerId) throws GameException {
|
||||||
|
match.startGame();
|
||||||
|
table.initGame();
|
||||||
|
GameManager.getInstance().createGameSession(match.getGame(), sessionPlayerMap, table.getId(), choosingPlayerId);
|
||||||
SessionManager sessionManager = SessionManager.getInstance();
|
SessionManager sessionManager = SessionManager.getInstance();
|
||||||
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
|
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
|
||||||
sessionManager.getSession(entry.getKey()).gameStarted(game.getId(), entry.getValue());
|
sessionManager.getSession(entry.getKey()).gameStarted(match.getGame().getId(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sideboard() {
|
||||||
|
table.sideboard();
|
||||||
|
for (MatchPlayer player: match.getPlayers()) {
|
||||||
|
player.setSideboarding();
|
||||||
|
player.getPlayer().sideboard(table);
|
||||||
|
}
|
||||||
|
while (!match.isDoneSideboarding()){}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sideboard(UUID playerId) {
|
||||||
|
SessionManager sessionManager = SessionManager.getInstance();
|
||||||
|
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
|
||||||
|
if (entry.getValue().equals(playerId)) {
|
||||||
|
MatchPlayer player = match.getPlayer(entry.getValue());
|
||||||
|
sessionManager.getSession(entry.getKey()).sideboard(player.getDeck(), table.getId());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void endGame() {
|
public void endGame() {
|
||||||
|
UUID choosingPlayerId = match.getChooser();
|
||||||
|
match.endGame();
|
||||||
table.endGame();
|
table.endGame();
|
||||||
saveGame();
|
saveGame();
|
||||||
GameManager.getInstance().removeGame(game.getId());
|
GameManager.getInstance().removeGame(match.getGame().getId());
|
||||||
game = null;
|
try {
|
||||||
|
if (!match.isMatchOver()) {
|
||||||
|
sideboard();
|
||||||
|
startGame(choosingPlayerId);
|
||||||
|
}
|
||||||
|
} catch (GameException ex) {
|
||||||
|
logger.log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
endMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endMatch() {
|
||||||
|
match = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapSeats(int seatNum1, int seatNum2) {
|
public void swapSeats(int seatNum1, int seatNum2) {
|
||||||
|
@ -188,17 +266,17 @@ public class TableController {
|
||||||
|
|
||||||
private void saveGame() {
|
private void saveGame() {
|
||||||
try {
|
try {
|
||||||
OutputStream file = new FileOutputStream("saved/" + game.getId().toString() + ".game");
|
OutputStream file = new FileOutputStream("saved/" + match.getGame().getId().toString() + ".game");
|
||||||
OutputStream buffer = new BufferedOutputStream(file);
|
OutputStream buffer = new BufferedOutputStream(file);
|
||||||
ObjectOutput output = new ObjectOutputStream(new GZIPOutputStream(buffer));
|
ObjectOutput output = new ObjectOutputStream(new GZIPOutputStream(buffer));
|
||||||
try {
|
try {
|
||||||
output.writeObject(game);
|
output.writeObject(match.getGame());
|
||||||
output.writeObject(game.getGameStates());
|
output.writeObject(match.getGame().getGameStates());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
logger.log(Level.INFO, "Saved game:" + game.getId());
|
logger.log(Level.INFO, "Saved game:" + match.getGame().getId());
|
||||||
}
|
}
|
||||||
catch(IOException ex) {
|
catch(IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Cannot save game.", ex);
|
logger.log(Level.SEVERE, "Cannot save game.", ex);
|
||||||
|
@ -207,7 +285,7 @@ public class TableController {
|
||||||
|
|
||||||
private Game loadGame() {
|
private Game loadGame() {
|
||||||
try{
|
try{
|
||||||
InputStream file = new FileInputStream("saved/" + gameId.toString() + ".game");
|
InputStream file = new FileInputStream("saved/" + match.getGame().toString() + ".game");
|
||||||
InputStream buffer = new BufferedInputStream(file);
|
InputStream buffer = new BufferedInputStream(file);
|
||||||
ObjectInput input = new CopierObjectInputStream(Main.classLoader, new GZIPInputStream(buffer));
|
ObjectInput input = new CopierObjectInputStream(Main.classLoader, new GZIPInputStream(buffer));
|
||||||
try {
|
try {
|
||||||
|
@ -224,7 +302,7 @@ public class TableController {
|
||||||
logger.log(Level.SEVERE, "Cannot load game. Class not found.", ex);
|
logger.log(Level.SEVERE, "Cannot load game. Class not found.", ex);
|
||||||
}
|
}
|
||||||
catch(IOException ex) {
|
catch(IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Cannot load game:" + game.getId(), ex);
|
logger.log(Level.SEVERE, "Cannot load game:" + match.getGame().getId(), ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,12 @@ package mage.server.game;
|
||||||
|
|
||||||
import mage.game.Table;
|
import mage.game.Table;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import mage.Constants.MultiplayerAttackOption;
|
|
||||||
import mage.Constants.RangeOfInfluence;
|
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,8 +54,8 @@ public class TableManager {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
public Table createTable(UUID sessionId, MatchOptions options) {
|
||||||
TableController tableController = new TableController(sessionId, gameType, deckType, playerTypes, attackOption, range);
|
TableController tableController = new TableController(sessionId, options);
|
||||||
controllers.put(tableController.getTable().getId(), tableController);
|
controllers.put(tableController.getTable().getId(), tableController);
|
||||||
tables.put(tableController.getTable().getId(), tableController.getTable());
|
tables.put(tableController.getTable().getId(), tableController.getTable());
|
||||||
return tableController.getTable();
|
return tableController.getTable();
|
||||||
|
@ -75,6 +73,10 @@ public class TableManager {
|
||||||
return controllers.get(tableId).joinTable(sessionId, name, deckList);
|
return controllers.get(tableId).joinTable(sessionId, name, deckList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws GameException {
|
||||||
|
return controllers.get(tableId).submitDeck(sessionId, deckList);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeSession(UUID sessionId) {
|
public void removeSession(UUID sessionId) {
|
||||||
// TODO: search through tables and remove session
|
// TODO: search through tables and remove session
|
||||||
}
|
}
|
||||||
|
@ -100,8 +102,8 @@ public class TableManager {
|
||||||
return controllers.get(tableId).getChatId();
|
return controllers.get(tableId).getChatId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startGame(UUID sessionId, UUID roomId, UUID tableId) {
|
public void startMatch(UUID sessionId, UUID roomId, UUID tableId) {
|
||||||
controllers.get(tableId).startGame(sessionId);
|
controllers.get(tableId).startMatch(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean watchTable(UUID sessionId, UUID tableId) {
|
public boolean watchTable(UUID sessionId, UUID tableId) {
|
||||||
|
|
|
@ -31,11 +31,7 @@ package mage.sets;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
@ -51,6 +47,7 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
||||||
|
|
||||||
private static final Sets fINSTANCE = new Sets();
|
private static final Sets fINSTANCE = new Sets();
|
||||||
private static Set<String> names;
|
private static Set<String> names;
|
||||||
|
protected static Random rnd = new Random();
|
||||||
|
|
||||||
public static Sets getInstance() {
|
public static Sets getInstance() {
|
||||||
return fINSTANCE;
|
return fINSTANCE;
|
||||||
|
@ -94,6 +91,24 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String findCard(String name, boolean random) {
|
||||||
|
if (!random) {
|
||||||
|
return findCard(name);
|
||||||
|
} else {
|
||||||
|
List<String> cards = new ArrayList<String>();
|
||||||
|
for (ExpansionSet set: fINSTANCE.values()) {
|
||||||
|
String cardName = set.findCard(name, true);
|
||||||
|
if (cardName != null) {
|
||||||
|
cards.add(cardName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cards.size() > 0) {
|
||||||
|
return cards.get(rnd.nextInt(cards.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static ExpansionSet findSet(String code) {
|
public static ExpansionSet findSet(String code) {
|
||||||
for (ExpansionSet set: fINSTANCE.values()) {
|
for (ExpansionSet set: fINSTANCE.values()) {
|
||||||
if (set.getCode().equals(code))
|
if (set.getCode().equals(code))
|
||||||
|
|
|
@ -42,11 +42,10 @@ import mage.abilities.common.EntersBattlefieldAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.PreventionEffectImpl;
|
import mage.abilities.effects.PreventionEffectImpl;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
|
||||||
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
|
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.counters.PlusOneCounter;
|
import mage.counters.common.PlusOneCounter;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.GameEvent.EventType;
|
import mage.game.events.GameEvent.EventType;
|
||||||
|
|
80
Mage.Sets/src/mage/sets/scarsofmirrodin/AcidWebSpider.java
Normal file
80
Mage.Sets/src/mage/sets/scarsofmirrodin/AcidWebSpider.java
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
|
import mage.abilities.keyword.ReachAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.filter.Filter;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class AcidWebSpider extends CardImpl<AcidWebSpider> {
|
||||||
|
private static FilterPermanent filter = new FilterPermanent("Equipment");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.getSubtype().add("Equipment");
|
||||||
|
filter.setScopeSubtype(Filter.ComparisonScope.Any);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AcidWebSpider (UUID ownerId) {
|
||||||
|
super(ownerId, 108, "Acid Web Spider", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Spider");
|
||||||
|
this.color.setGreen(true);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
this.addAbility(ReachAbility.getInstance());
|
||||||
|
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), true);
|
||||||
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AcidWebSpider (final AcidWebSpider card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AcidWebSpider copy() {
|
||||||
|
return new AcidWebSpider(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
103
Mage.Sets/src/mage/sets/scarsofmirrodin/ArgentumArmor.java
Normal file
103
Mage.Sets/src/mage/sets/scarsofmirrodin/ArgentumArmor.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.common.BoostEquippedEffect;
|
||||||
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
|
import mage.abilities.keyword.EquipAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class ArgentumArmor extends CardImpl<ArgentumArmor> {
|
||||||
|
|
||||||
|
public ArgentumArmor (UUID ownerId) {
|
||||||
|
super(ownerId, 137, "Argentum Armor", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{6}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Equipment");
|
||||||
|
this.addAbility(new EquipAbility(Constants.Outcome.AddAbility, new GenericManaCost(6)));
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(6, 6)));
|
||||||
|
this.addAbility(new ArgentumArmorAbiltity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArgentumArmor (final ArgentumArmor card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArgentumArmor copy() {
|
||||||
|
return new ArgentumArmor(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArgentumArmorAbiltity extends TriggeredAbilityImpl<ArgentumArmorAbiltity> {
|
||||||
|
public ArgentumArmorAbiltity() {
|
||||||
|
super(Zone.BATTLEFIELD, new DestroyTargetEffect());
|
||||||
|
this.addTarget(new TargetPermanent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArgentumArmorAbiltity(final ArgentumArmorAbiltity abiltity) {
|
||||||
|
super(abiltity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArgentumArmorAbiltity copy() {
|
||||||
|
return new ArgentumArmorAbiltity(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
Permanent equipment = game.getPermanent(this.sourceId);
|
||||||
|
if (equipment != null && equipment.getAttachedTo() != null && event.getType() == GameEvent.EventType.ATTACKER_DECLARED && event.getSourceId().equals(equipment.getAttachedTo())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Whenever equipped creature attacks, destroy target permanent.";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.common.BoostEquippedEffect;
|
||||||
|
import mage.abilities.keyword.EquipAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class BarbedBattlegear extends CardImpl<BarbedBattlegear> {
|
||||||
|
|
||||||
|
public BarbedBattlegear (UUID ownerId) {
|
||||||
|
super(ownerId, 139, "Barbed Battlegear", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Equipment");
|
||||||
|
this.addAbility(new EquipAbility(Constants.Outcome.AddAbility, new GenericManaCost(2)));
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(4, -1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarbedBattlegear (final BarbedBattlegear card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BarbedBattlegear copy() {
|
||||||
|
return new BarbedBattlegear(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
69
Mage.Sets/src/mage/sets/scarsofmirrodin/BladedPinions.java
Normal file
69
Mage.Sets/src/mage/sets/scarsofmirrodin/BladedPinions.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.common.GainAbilityAttachedEffect;
|
||||||
|
import mage.abilities.keyword.EquipAbility;
|
||||||
|
import mage.abilities.keyword.FirstStrikeAbility;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class BladedPinions extends CardImpl<BladedPinions> {
|
||||||
|
|
||||||
|
public BladedPinions (UUID ownerId) {
|
||||||
|
super(ownerId, 140, "Bladed Pinions", Rarity.COMMON, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Equipment");
|
||||||
|
this.addAbility(new EquipAbility(Constants.Outcome.AddAbility, new GenericManaCost(2)));
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance())));
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BladedPinions (final BladedPinions card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BladedPinions copy() {
|
||||||
|
return new BladedPinions(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
Mage.Sets/src/mage/sets/scarsofmirrodin/BlightMamba.java
Normal file
70
Mage.Sets/src/mage/sets/scarsofmirrodin/BlightMamba.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.RegenerateSourceEffect;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.sets.magic2011.InfernoTitan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class BlightMamba extends CardImpl<BlightMamba> {
|
||||||
|
|
||||||
|
public BlightMamba (UUID ownerId) {
|
||||||
|
super(ownerId, 112, "Blight Mamba", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Snake");
|
||||||
|
this.color.setGreen(true);
|
||||||
|
this.power = new MageInt(1);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{G}")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlightMamba (final BlightMamba card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlightMamba copy() {
|
||||||
|
return new BlightMamba(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
Mage.Sets/src/mage/sets/scarsofmirrodin/ContagiousNim.java
Normal file
63
Mage.Sets/src/mage/sets/scarsofmirrodin/ContagiousNim.java
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class ContagiousNim extends CardImpl<ContagiousNim> {
|
||||||
|
|
||||||
|
public ContagiousNim (UUID ownerId) {
|
||||||
|
super(ownerId, 58, "Contagious Nim", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Zombie");
|
||||||
|
this.color.setBlack(true);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContagiousNim (final ContagiousNim card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContagiousNim copy() {
|
||||||
|
return new ContagiousNim(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
Mage.Sets/src/mage/sets/scarsofmirrodin/Cystbearer.java
Normal file
70
Mage.Sets/src/mage/sets/scarsofmirrodin/Cystbearer.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.StaticAbility;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cystbearer
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class Cystbearer extends CardImpl<Cystbearer> {
|
||||||
|
|
||||||
|
public Cystbearer(UUID ownerId) {
|
||||||
|
super(ownerId, 117, "Cystbearer", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Beast");
|
||||||
|
|
||||||
|
this.color.setGreen(true);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cystbearer(final Cystbearer card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cystbearer copy() {
|
||||||
|
return new Cystbearer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
133
Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java
Normal file
133
Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.LoyaltyAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.game.permanent.PermanentToken;
|
||||||
|
import mage.game.permanent.token.SoldierToken;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class ElspethTirel extends CardImpl<ElspethTirel> {
|
||||||
|
|
||||||
|
public ElspethTirel (UUID ownerId) {
|
||||||
|
super(ownerId, 6, "Elspeth Tirel", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{W}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Elspeth");
|
||||||
|
this.color.setWhite(true);
|
||||||
|
this.loyalty = new MageInt(4);
|
||||||
|
this.addAbility(new LoyaltyAbility(new ElspethTirelFirstEffect(), 2));
|
||||||
|
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken(), 3), -2));
|
||||||
|
this.addAbility(new LoyaltyAbility(new ElspethTirelThirdEffect(), -5));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElspethTirel (final ElspethTirel card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElspethTirel copy() {
|
||||||
|
return new ElspethTirel(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElspethTirelFirstEffect extends OneShotEffect<ElspethTirelFirstEffect> {
|
||||||
|
public ElspethTirelFirstEffect() {
|
||||||
|
super(Constants.Outcome.GainLife);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElspethTirelFirstEffect(final ElspethTirelFirstEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
int amount = game.getBattlefield().countAll(new FilterCreaturePermanent(), source.getControllerId());
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player != null) {
|
||||||
|
player.gainLife(amount, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElspethTirelFirstEffect copy() {
|
||||||
|
return new ElspethTirelFirstEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "You gain 1 life for each creature you control";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElspethTirelThirdEffect extends OneShotEffect<ElspethTirelThirdEffect> {
|
||||||
|
public ElspethTirelThirdEffect() {
|
||||||
|
super(Constants.Outcome.DestroyPermanent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElspethTirelThirdEffect(final ElspethTirelThirdEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||||
|
if (!perm.getId().equals(source.getSourceId()) && !(perm instanceof PermanentToken) && ! (perm.getCardType().contains(CardType.LAND)))
|
||||||
|
perm.destroy(source.getId(), game, false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElspethTirelThirdEffect copy() {
|
||||||
|
return new ElspethTirelThirdEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "Destroy all other permanents except for lands and tokens";
|
||||||
|
}
|
||||||
|
}
|
222
Mage.Sets/src/mage/sets/scarsofmirrodin/KothoftheHammer.java
Normal file
222
Mage.Sets/src/mage/sets/scarsofmirrodin/KothoftheHammer.java
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.LoyaltyAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
import mage.abilities.effects.common.ManaEffect;
|
||||||
|
import mage.abilities.effects.common.UntapTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.filter.Filter;
|
||||||
|
import mage.filter.common.FilterLandPermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.common.TargetCreatureOrPlayer;
|
||||||
|
import mage.target.common.TargetLandPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class KothoftheHammer extends CardImpl<KothoftheHammer> {
|
||||||
|
static FilterLandPermanent filter = new FilterLandPermanent("Mountain");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.getSubtype().add("Mountain");
|
||||||
|
filter.setScopeSubtype(Filter.ComparisonScope.Any);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KothoftheHammer (UUID ownerId) {
|
||||||
|
super(ownerId, 94, "Koth of the Hammer", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{R}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Koth");
|
||||||
|
this.color.setRed(true);
|
||||||
|
this.loyalty = new MageInt(3);
|
||||||
|
Ability ability = new LoyaltyAbility(new UntapTargetEffect(), 1);
|
||||||
|
ability.addEffect(new KothoftheHammerFirstEffect());
|
||||||
|
ability.addTarget(new TargetLandPermanent(filter));
|
||||||
|
this.addAbility(ability);
|
||||||
|
this.addAbility(new LoyaltyAbility(new KothoftheHammerSecondEffect(), -2));
|
||||||
|
this.addAbility(new LoyaltyAbility(new KothoftheHammerThirdEffect(), -5));
|
||||||
|
}
|
||||||
|
|
||||||
|
public KothoftheHammer (final KothoftheHammer card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KothoftheHammer copy() {
|
||||||
|
return new KothoftheHammer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KothoftheHammerFirstEffect extends ContinuousEffectImpl<KothoftheHammerFirstEffect> {
|
||||||
|
|
||||||
|
public KothoftheHammerFirstEffect() {
|
||||||
|
super(Duration.EndOfTurn, Constants.Outcome.BecomeCreature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KothoftheHammerFirstEffect(final KothoftheHammerFirstEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Constants.Layer layer, Constants.SubLayer sublayer, Ability source, Game game) {
|
||||||
|
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||||
|
if (permanent != null) {
|
||||||
|
switch (layer) {
|
||||||
|
case TypeChangingEffects_4:
|
||||||
|
if (sublayer == Constants.SubLayer.NA) {
|
||||||
|
permanent.getCardType().add(CardType.CREATURE);
|
||||||
|
permanent.getSubtype().add("Elemental");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ColorChangingEffects_5:
|
||||||
|
if (sublayer == Constants.SubLayer.NA) {
|
||||||
|
permanent.getColor().setRed(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PTChangingEffects_7:
|
||||||
|
if (sublayer == Constants.SubLayer.SetPT_7b) {
|
||||||
|
permanent.getPower().setValue(4);
|
||||||
|
permanent.getToughness().setValue(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KothoftheHammerFirstEffect copy() {
|
||||||
|
return new KothoftheHammerFirstEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLayer(Constants.Layer layer) {
|
||||||
|
return layer == Constants.Layer.PTChangingEffects_7 || layer == Constants.Layer.ColorChangingEffects_5 || layer == layer.TypeChangingEffects_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "It becomes a 4/4 red Elemental creature until end of turn. It's still a land";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KothoftheHammerSecondEffect extends OneShotEffect<KothoftheHammerSecondEffect> {
|
||||||
|
public KothoftheHammerSecondEffect() {
|
||||||
|
super(Constants.Outcome.PutManaInPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KothoftheHammerSecondEffect(final KothoftheHammerSecondEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
int count = game.getBattlefield().count(KothoftheHammer.filter, source.getControllerId(), game);
|
||||||
|
int current = game.getPlayer(source.getControllerId()).getManaPool().getRed();
|
||||||
|
game.getPlayer(source.getControllerId()).getManaPool().setRed(count + current);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KothoftheHammerSecondEffect copy() {
|
||||||
|
return new KothoftheHammerSecondEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "Add {R} to your mana pool for each Mountain you control";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KothoftheHammerThirdEffect extends ContinuousEffectImpl<KothoftheHammerThirdEffect> {
|
||||||
|
public KothoftheHammerThirdEffect() {
|
||||||
|
super(Duration.EndOfGame, Constants.Outcome.AddAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KothoftheHammerThirdEffect(final KothoftheHammerThirdEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Constants.Layer layer, Constants.SubLayer sublayer, Ability source, Game game) {
|
||||||
|
switch (layer) {
|
||||||
|
case AbilityAddingRemovingEffects_6:
|
||||||
|
if (sublayer == Constants.SubLayer.NA) {
|
||||||
|
for (Permanent p : game.getBattlefield().getActivePermanents(KothoftheHammer.filter, source.getControllerId(), game)) {
|
||||||
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost());
|
||||||
|
ability.addTarget(new TargetCreatureOrPlayer());
|
||||||
|
p.addAbility(ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KothoftheHammerThirdEffect copy() {
|
||||||
|
return new KothoftheHammerThirdEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLayer(Constants.Layer layer) {
|
||||||
|
return layer == Constants.Layer.AbilityAddingRemovingEffects_6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Ability source) {
|
||||||
|
return "You get an emblem with \"Mountains you control have '{T}: This land deals 1 damage to target creature or player.'\"";
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.effects.common.AddCountersSourceEffect;
|
import mage.abilities.effects.common.AddCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.counters.CounterType;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -51,9 +52,9 @@ public class LuxCannon extends CardImpl<LuxCannon> {
|
||||||
public LuxCannon (UUID ownerId) {
|
public LuxCannon (UUID ownerId) {
|
||||||
super(ownerId, 173, "Lux Cannon", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT}, "{4}");
|
super(ownerId, 173, "Lux Cannon", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||||
this.expansionSetCode = "SOM";
|
this.expansionSetCode = "SOM";
|
||||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect("charge", 1), new TapSourceCost()));
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.getName(), 1), new TapSourceCost()));
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost());
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost());
|
||||||
ability.addCost(new RemoveCountersSourceCost("charge", 3));
|
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.getName(), 3));
|
||||||
ability.addTarget(new TargetPermanent());
|
ability.addTarget(new TargetPermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
71
Mage.Sets/src/mage/sets/scarsofmirrodin/PlagueStinger.java
Normal file
71
Mage.Sets/src/mage/sets/scarsofmirrodin/PlagueStinger.java
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.OnEventTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class PlagueStinger extends CardImpl<PlagueStinger> {
|
||||||
|
|
||||||
|
public PlagueStinger (UUID ownerId) {
|
||||||
|
super(ownerId, 75, "Plague Stinger", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Insect");
|
||||||
|
this.subtype.add("Horror");
|
||||||
|
this.color.setBlack(true);
|
||||||
|
this.power = new MageInt(1);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlagueStinger (final PlagueStinger card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlagueStinger copy() {
|
||||||
|
return new PlagueStinger(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
69
Mage.Sets/src/mage/sets/scarsofmirrodin/Putrefax.java
Normal file
69
Mage.Sets/src/mage/sets/scarsofmirrodin/Putrefax.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.OnEventTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class Putrefax extends CardImpl<Putrefax> {
|
||||||
|
|
||||||
|
public Putrefax (UUID ownerId) {
|
||||||
|
super(ownerId, 126, "Putrefax", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Horror");
|
||||||
|
this.color.setGreen(true);
|
||||||
|
this.power = new MageInt(5);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
this.addAbility(TrampleAbility.getInstance());
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", new SacrificeSourceEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Putrefax (final Putrefax card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Putrefax copy() {
|
||||||
|
return new Putrefax(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.GainAbilitySourceEffect;
|
||||||
|
import mage.abilities.effects.common.RegenerateSourceEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.HasteAbility;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class SkithiryxtheBlightDragon extends CardImpl<SkithiryxtheBlightDragon> {
|
||||||
|
|
||||||
|
public SkithiryxtheBlightDragon (UUID ownerId) {
|
||||||
|
super(ownerId, 79, "Skithiryx, the Blight Dragon", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.supertype.add("Legendary");
|
||||||
|
this.subtype.add("Dragon");
|
||||||
|
this.subtype.add("Skeleton");
|
||||||
|
this.color.setBlack(true);
|
||||||
|
this.power = new MageInt(4);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
this.addAbility(InfectAbility.getInstance());
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{B}")));
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}{B}")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkithiryxtheBlightDragon (final SkithiryxtheBlightDragon card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkithiryxtheBlightDragon copy() {
|
||||||
|
return new SkithiryxtheBlightDragon(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
Mage.Sets/src/mage/sets/scarsofmirrodin/TaintedStrike.java
Normal file
66
Mage.Sets/src/mage/sets/scarsofmirrodin/TaintedStrike.java
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.effects.common.BoostTargetEffect;
|
||||||
|
import mage.abilities.effects.common.GainAbilityTargetEffect;
|
||||||
|
import mage.abilities.keyword.InfectAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class TaintedStrike extends CardImpl<TaintedStrike> {
|
||||||
|
|
||||||
|
public TaintedStrike (UUID ownerId) {
|
||||||
|
super(ownerId, 80, "Tainted Strike", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.color.setBlack(true);
|
||||||
|
this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0, Duration.EndOfTurn));
|
||||||
|
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(InfectAbility.getInstance(), Duration.EndOfTurn));
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaintedStrike (final TaintedStrike card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaintedStrike copy() {
|
||||||
|
return new TaintedStrike(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.BoostTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class VulshokHeartstoker extends CardImpl<VulshokHeartstoker> {
|
||||||
|
|
||||||
|
public VulshokHeartstoker (UUID ownerId) {
|
||||||
|
super(ownerId, 107, "Vulshok Heartstoker", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Human");
|
||||||
|
this.subtype.add("Shaman");
|
||||||
|
this.color.setRed(true);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0, Duration.EndOfTurn));
|
||||||
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VulshokHeartstoker (final VulshokHeartstoker card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VulshokHeartstoker copy() {
|
||||||
|
return new VulshokHeartstoker(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
96
Mage.Sets/src/mage/sets/scarsofmirrodin/WurmcoilEngine.java
Normal file
96
Mage.Sets/src/mage/sets/scarsofmirrodin/WurmcoilEngine.java
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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.sets.scarsofmirrodin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Duration;
|
||||||
|
import mage.Constants.Rarity;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.PutIntoGraveFromBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.abilities.keyword.DeathtouchAbility;
|
||||||
|
import mage.abilities.keyword.LifelinkAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.game.permanent.token.Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class WurmcoilEngine extends CardImpl<WurmcoilEngine> {
|
||||||
|
|
||||||
|
public WurmcoilEngine (UUID ownerId) {
|
||||||
|
super(ownerId, 223, "Wurmcoil Engine", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
|
||||||
|
this.expansionSetCode = "SOM";
|
||||||
|
this.subtype.add("Wurm");
|
||||||
|
this.power = new MageInt(6);
|
||||||
|
this.toughness = new MageInt(6);
|
||||||
|
this.addAbility(DeathtouchAbility.getInstance());
|
||||||
|
this.addAbility(LifelinkAbility.getInstance());
|
||||||
|
Ability ability = new PutIntoGraveFromBattlefieldTriggeredAbility(new CreateTokenEffect(new Wurm1Token()), false);
|
||||||
|
ability.addEffect(new CreateTokenEffect(new Wurm2Token()));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WurmcoilEngine (final WurmcoilEngine card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WurmcoilEngine copy() {
|
||||||
|
return new WurmcoilEngine(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wurm1Token extends Token {
|
||||||
|
public Wurm1Token() {
|
||||||
|
super("Wurm", "a 3/3 colorless Wurm artifact creature token with deathtouch");
|
||||||
|
cardType.add(CardType.CREATURE);
|
||||||
|
subtype.add("Wurm");
|
||||||
|
power = new MageInt(3);
|
||||||
|
toughness = new MageInt(3);
|
||||||
|
this.addAbility(DeathtouchAbility.getInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wurm2Token extends Token {
|
||||||
|
public Wurm2Token() {
|
||||||
|
super("Wurm", "a 3/3 colorless Wurm artifact creature token with lifelink");
|
||||||
|
cardType.add(CardType.CREATURE);
|
||||||
|
subtype.add("Wurm");
|
||||||
|
power = new MageInt(3);
|
||||||
|
toughness = new MageInt(3);
|
||||||
|
this.addAbility(LifelinkAbility.getInstance());
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ import mage.abilities.effects.common.ManaEffect;
|
||||||
import mage.abilities.keyword.MultikickerAbility;
|
import mage.abilities.keyword.MultikickerAbility;
|
||||||
import mage.abilities.mana.ManaAbility;
|
import mage.abilities.mana.ManaAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +56,7 @@ public class EverflowingChalice extends CardImpl<EverflowingChalice> {
|
||||||
public EverflowingChalice(UUID ownerId) {
|
public EverflowingChalice(UUID ownerId) {
|
||||||
super(ownerId, 123, "Everflowing Chalice", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{0}");
|
super(ownerId, 123, "Everflowing Chalice", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{0}");
|
||||||
this.expansionSetCode = "WWK";
|
this.expansionSetCode = "WWK";
|
||||||
Ability ability1 = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect("charge", 1));
|
Ability ability1 = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.CHARGE.getName(), 1));
|
||||||
MultikickerAbility ability = new MultikickerAbility(new GainAbilitySourceEffect(ability1, Duration.WhileOnBattlefield), false);
|
MultikickerAbility ability = new MultikickerAbility(new GainAbilitySourceEffect(ability1, Duration.WhileOnBattlefield), false);
|
||||||
ability.addManaCost(new GenericManaCost(2));
|
ability.addManaCost(new GenericManaCost(2));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
@ -120,7 +121,7 @@ class EverflowingChaliceEffect extends ManaEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
this.mana.clear();
|
this.mana.clear();
|
||||||
this.mana.setColorless(game.getPermanent(source.getSourceId()).getCounters().getCount("charge"));
|
this.mana.setColorless(game.getPermanent(source.getSourceId()).getCounters().getCount(CounterType.CHARGE));
|
||||||
return super.apply(game, source);
|
return super.apply(game, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.mana.GreenManaAbility;
|
import mage.abilities.mana.GreenManaAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.counters.PlusOneCounter;
|
import mage.counters.common.PlusOneCounter;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
|
@ -21,6 +21,9 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import mage.Constants.MultiplayerAttackOption;
|
||||||
|
import mage.Constants.RangeOfInfluence;
|
||||||
|
import mage.game.match.MatchOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base for starting Mage server.
|
* Base for starting Mage server.
|
||||||
|
@ -64,14 +67,18 @@ public class MageBase {
|
||||||
connect("player", "localhost", 17171);
|
connect("player", "localhost", 17171);
|
||||||
UUID roomId = server.getMainRoomId();
|
UUID roomId = server.getMainRoomId();
|
||||||
|
|
||||||
List<String> playerTypes = new ArrayList<String>();
|
MatchOptions options = new MatchOptions("1", "Two Player Duel");
|
||||||
playerTypes.add("Human");
|
options.getPlayerTypes().add("Human");
|
||||||
playerTypes.add("Computer - default");
|
options.getPlayerTypes().add("Computer - default");
|
||||||
TableView table = server.createTable(sessionId, roomId, "Two Player Duel", "Limited", playerTypes, null, null);
|
options.setDeckType("Limited");
|
||||||
|
options.setAttackOption(MultiplayerAttackOption.LEFT);
|
||||||
|
options.setRange(RangeOfInfluence.ALL);
|
||||||
|
options.setWinsNeeded(1);
|
||||||
|
TableView table = server.createTable(sessionId, roomId, options);
|
||||||
System.out.println("Cards in the deck: " + Sets.loadDeck("UW Control.dck").getCards().size());
|
System.out.println("Cards in the deck: " + Sets.loadDeck("UW Control.dck").getCards().size());
|
||||||
server.joinTable(sessionId, roomId, table.getTableId(), "Human", Sets.loadDeck("UW Control.dck"));
|
server.joinTable(sessionId, roomId, table.getTableId(), "Human", Sets.loadDeck("UW Control.dck"));
|
||||||
server.joinTable(sessionId, roomId, table.getTableId(), "Computer", Sets.loadDeck("UW Control.dck"));
|
server.joinTable(sessionId, roomId, table.getTableId(), "Computer", Sets.loadDeck("UW Control.dck"));
|
||||||
server.startGame(sessionId, roomId, table.getTableId());
|
server.startMatch(sessionId, roomId, table.getTableId());
|
||||||
|
|
||||||
synchronized (syncStart) {
|
synchronized (syncStart) {
|
||||||
int waitTime = 7000;
|
int waitTime = 7000;
|
||||||
|
|
|
@ -39,7 +39,7 @@ import mage.filter.FilterAbility;
|
||||||
|
|
||||||
public interface Abilities<T extends Ability> extends List<T>, Serializable {
|
public interface Abilities<T extends Ability> extends List<T>, Serializable {
|
||||||
|
|
||||||
public List<String> getRules();
|
public List<String> getRules(String source);
|
||||||
public Abilities<ActivatedAbility> getActivatedAbilities(Zone zone);
|
public Abilities<ActivatedAbility> getActivatedAbilities(Zone zone);
|
||||||
public Abilities<ActivatedAbility> getActivatedAbilities(Zone zone, FilterAbility filter);
|
public Abilities<ActivatedAbility> getActivatedAbilities(Zone zone, FilterAbility filter);
|
||||||
public Abilities<ManaAbility> getManaAbilities(Zone zone);
|
public Abilities<ManaAbility> getManaAbilities(Zone zone);
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRules() {
|
public List<String> getRules(String source) {
|
||||||
List<String> rules = new ArrayList<String>();
|
List<String> rules = new ArrayList<String>();
|
||||||
|
|
||||||
for (T ability:this) {
|
for (T ability:this) {
|
||||||
|
|
|
@ -73,6 +73,7 @@ public interface Ability extends Serializable {
|
||||||
public Zone getZone();
|
public Zone getZone();
|
||||||
public boolean isUsesStack();
|
public boolean isUsesStack();
|
||||||
public String getRule();
|
public String getRule();
|
||||||
|
public String getRule(String source);
|
||||||
public boolean activate(Game game, boolean noMana);
|
public boolean activate(Game game, boolean noMana);
|
||||||
public boolean resolve(Game game);
|
public boolean resolve(Game game);
|
||||||
public void reset(Game game);
|
public void reset(Game game);
|
||||||
|
|
|
@ -302,6 +302,17 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
||||||
return sbRule.toString();
|
return sbRule.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule(String source) {
|
||||||
|
return formatRule(getRule(), source);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String formatRule(String rule, String source) {
|
||||||
|
String replace = rule.replace("{this}", source);
|
||||||
|
replace = replace.replace("{source}", source);
|
||||||
|
return replace;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCost(Cost cost) {
|
public void addCost(Cost cost) {
|
||||||
if (cost != null) {
|
if (cost != null) {
|
||||||
|
|
|
@ -81,10 +81,13 @@ public abstract class TriggeredAbilityImpl<T extends TriggeredAbilityImpl<T>> ex
|
||||||
Player player = game.getPlayer(this.getControllerId());
|
Player player = game.getPlayer(this.getControllerId());
|
||||||
MageObject object = game.getObject(sourceId);
|
MageObject object = game.getObject(sourceId);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Use ").append(this.getRule()).append("ability");
|
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
|
sb.append("Use ").append(this.getRule(object.getName())).append("ability");
|
||||||
sb.append(" from ").append(object.getName());
|
sb.append(" from ").append(object.getName());
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
sb.append("Use ").append(this.getRule()).append("ability");
|
||||||
|
}
|
||||||
sb.append("?");
|
sb.append("?");
|
||||||
if (!player.chooseUse(this.effects.get(0).getOutcome(), sb.toString(), game)) {
|
if (!player.chooseUse(this.effects.get(0).getOutcome(), sb.toString(), game)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package mage.abilities.condition.common;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
|
||||||
|
public class ControlsPermanent implements Condition {
|
||||||
|
private FilterPermanent filter;
|
||||||
|
|
||||||
|
public ControlsPermanent(FilterPermanent filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return game.getBattlefield().countAll(filter, source.getControllerId()) > 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package mage.abilities.effects;
|
||||||
|
|
||||||
|
import mage.Constants;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.game.Game;
|
||||||
|
|
||||||
|
public abstract class WhileConditionContiniousEffect<T extends WhileConditionContiniousEffect<T>> extends ContinuousEffectImpl<T> {
|
||||||
|
protected Condition condition;
|
||||||
|
|
||||||
|
public WhileConditionContiniousEffect(Constants.Duration duration, Constants.Layer layer, Constants.SubLayer sublayer, Condition condition, Constants.Outcome outcome) {
|
||||||
|
super(duration, outcome);
|
||||||
|
this.condition = condition;
|
||||||
|
this.layer = layer;
|
||||||
|
this.sublayer = sublayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WhileConditionContiniousEffect(final WhileConditionContiniousEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.condition = effect.condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
if (condition.apply(game, source)) {
|
||||||
|
return applyEffect(game, source);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean applyEffect(Game game, Ability source);
|
||||||
|
}
|
|
@ -31,7 +31,7 @@ package mage.abilities.effects.common;
|
||||||
import mage.Constants.Outcome;
|
import mage.Constants.Outcome;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.counters.PlusOneCounter;
|
import mage.counters.common.PlusOneCounter;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ package mage.abilities.effects.common;
|
||||||
import mage.Constants.Outcome;
|
import mage.Constants.Outcome;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.counters.PlusOneCounter;
|
import mage.counters.common.PlusOneCounter;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
|
@ -31,7 +31,7 @@ package mage.abilities.effects.common;
|
||||||
import mage.Constants.Outcome;
|
import mage.Constants.Outcome;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.counters.PlusOneCounter;
|
import mage.counters.common.PlusOneCounter;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
|
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
import mage.abilities.effects.WhileControlsContinuousEffect;
|
import mage.abilities.condition.common.ControlsPermanent;
|
||||||
|
import mage.abilities.effects.WhileConditionContiniousEffect;
|
||||||
import mage.Constants.Duration;
|
import mage.Constants.Duration;
|
||||||
import mage.Constants.Layer;
|
import mage.Constants.Layer;
|
||||||
import mage.Constants.Outcome;
|
import mage.Constants.Outcome;
|
||||||
|
@ -38,25 +39,32 @@ import mage.filter.FilterPermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class BoostSourceWhileControlsEffect extends WhileControlsContinuousEffect<BoostSourceWhileControlsEffect> {
|
public class BoostSourceWhileControlsEffect extends WhileConditionContiniousEffect<BoostSourceWhileControlsEffect> {
|
||||||
|
|
||||||
private int power;
|
private int power;
|
||||||
private int toughness;
|
private int toughness;
|
||||||
|
private List<String> filterDescription;
|
||||||
|
|
||||||
public BoostSourceWhileControlsEffect(FilterPermanent filter, int power, int toughness) {
|
public BoostSourceWhileControlsEffect(FilterPermanent filter, int power, int toughness) {
|
||||||
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, filter, Outcome.BoostCreature);
|
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, new ControlsPermanent(filter), Outcome.BoostCreature);
|
||||||
this.power = power;
|
this.power = power;
|
||||||
this.toughness = toughness;
|
this.toughness = toughness;
|
||||||
|
this.filterDescription = filter.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoostSourceWhileControlsEffect(final BoostSourceWhileControlsEffect effect) {
|
public BoostSourceWhileControlsEffect(final BoostSourceWhileControlsEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
this.power = effect.power;
|
this.power = effect.power;
|
||||||
this.toughness = effect.toughness;
|
this.toughness = effect.toughness;
|
||||||
|
this.filterDescription = new ArrayList<String>();
|
||||||
|
this.filterDescription.addAll(effect.filterDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,6 +84,6 @@ public class BoostSourceWhileControlsEffect extends WhileControlsContinuousEffec
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText(Ability source) {
|
public String getText(Ability source) {
|
||||||
return "{this} gets " + String.format("%1$+d/%2$+d", power, toughness) + " as long as you control a " + filter.getName();
|
return "{this} gets " + String.format("%1$+d/%2$+d", power, toughness) + " as long as you control a " + filterDescription;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,16 +30,18 @@ public class SacrificeSourceUnlessPaysEffect extends OneShotEffect<SacrificeSour
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null && player.chooseUse(Outcome.Benefit, cost.getText() + " or sacrifice {this}?", game)) {
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
|
if (player != null && permanent != null) {
|
||||||
|
if (player.chooseUse(Outcome.Benefit, cost.getText() + " or sacrifice " + permanent.getName() + "?", game)) {
|
||||||
cost.clearPaid();
|
cost.clearPaid();
|
||||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null)
|
|
||||||
permanent.sacrifice(source.getSourceId(), game);
|
permanent.sacrifice(source.getSourceId(), game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SacrificeSourceUnlessPaysEffect copy() {
|
public SacrificeSourceUnlessPaysEffect copy() {
|
||||||
|
@ -48,6 +50,6 @@ public class SacrificeSourceUnlessPaysEffect extends OneShotEffect<SacrificeSour
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText(Ability source) {
|
public String getText(Ability source) {
|
||||||
return "sacrifice it unless you pay " + cost.getText();
|
return "sacrifice {this} unless you pay " + cost.getText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,16 +57,18 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect<TapSourceUnlessPays
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null && player.chooseUse(Outcome.Benefit, cost.getText() + " or {this} comes into play tapped?", game)) {
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
|
if (player != null && permanent != null) {
|
||||||
|
if (player.chooseUse(Outcome.Benefit, cost.getText() + " or " + permanent.getName() + " comes into play tapped?", game)) {
|
||||||
cost.clearPaid();
|
cost.clearPaid();
|
||||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null)
|
|
||||||
permanent.setTapped(true);
|
permanent.setTapped(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TapSourceUnlessPaysEffect copy() {
|
public TapSourceUnlessPaysEffect copy() {
|
||||||
|
|
84
Mage/src/mage/abilities/keyword/InfectAbility.java
Normal file
84
Mage/src/mage/abilities/keyword/InfectAbility.java
Normal file
|
@ -0,0 +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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.abilities.keyword;
|
||||||
|
|
||||||
|
import java.io.ObjectStreamException;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.StaticAbility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 702.87. Infect
|
||||||
|
*
|
||||||
|
* 702.87a. Infect is a static ability.
|
||||||
|
*
|
||||||
|
* 702.87b. Damage dealt to a player by a source with infect doesn't cause that player to lose life. Rather, it causes the player to get that many poison counters. See rule 119.3.
|
||||||
|
*
|
||||||
|
* 702.87c. Damage dealt to a creature by a source with infect isn't marked on that creature. Rather, it causes that many -1/-1 counters to be put on that creature. See rule 119.3.
|
||||||
|
*
|
||||||
|
* 702.87d. If a permanent leaves the battlefield before an effect causes it to deal damage, its last known information
|
||||||
|
* (Last Known Information: Information about an object that's no longer in the zone it's expected to be in, or information about a player that's no longer in the game. This information captures that object's last existence in that zone or that player's last existence in the game....)
|
||||||
|
* 112.7a. Once activated or triggered, an ability exists on the stack independently of its source. Destruction or removal of the source after that time won't affect the ability. Note that some abilities cause a source to do something (for example, "Prodigal Sorcerer deals 1 damage...
|
||||||
|
* 608.2b. If the spell or ability specifies targets, it checks whether the targets are still legal. A target that's no longer in the zone it was in when it was targeted is illegal. Other changes to the game state may cause a target to no longer be legal; for example, its...
|
||||||
|
* 608.2g. If an effect requires information from the game (such as the number of creatures on the battlefield), the answer is determined only once, when the effect is applied. If the effect requires information from a specific object, including the source of the ability itself or a...
|
||||||
|
* 800.4f. If an effect requires information about a specific player, the effect uses the current information about that player if he or she is still in the game; otherwise, the effect uses the last known information about that player before he or she left the game.
|
||||||
|
* is used to determine whether it had infect.
|
||||||
|
*
|
||||||
|
* 702.87e. The infect rules function no matter what zone an object with infect deals damage from.
|
||||||
|
*
|
||||||
|
* 702.87f. Multiple instances of infect on the same object are redundant.
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class InfectAbility extends StaticAbility<InfectAbility> {
|
||||||
|
|
||||||
|
private static final InfectAbility fINSTANCE = new InfectAbility();
|
||||||
|
|
||||||
|
private Object readResolve() throws ObjectStreamException {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InfectAbility getInstance() {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfectAbility() {
|
||||||
|
super(Zone.ALL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Infect";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfectAbility copy() {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -93,7 +93,7 @@ public class LevelAbility extends StaticAbility<LevelAbility> {
|
||||||
else
|
else
|
||||||
sb.append("-").append(level2);
|
sb.append("-").append(level2);
|
||||||
sb.append(": ").append(power).append("/").append(toughness).append(" ");
|
sb.append(": ").append(power).append("/").append(toughness).append(" ");
|
||||||
for (String rule: abilities.getRules()) {
|
for (String rule: abilities.getRules("{this}")) {
|
||||||
sb.append(rule).append(" ");
|
sb.append(rule).append(" ");
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
75
Mage/src/mage/abilities/keyword/WitherAbility.java
Normal file
75
Mage/src/mage/abilities/keyword/WitherAbility.java
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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.abilities.keyword;
|
||||||
|
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.StaticAbility;
|
||||||
|
|
||||||
|
import java.io.ObjectStreamException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 702.77. Wither
|
||||||
|
*
|
||||||
|
* 702.77a. Wither is a static ability. Damage dealt to a creature by a source with wither isn't marked on that creature. Rather, it causes that many -1/-1 counters to be put on that creature. See rule 119.3.
|
||||||
|
*
|
||||||
|
* 702.77b. If a permanent leaves the battlefield before an effect causes it to deal damage, its last known information is used to determine whether it had wither.
|
||||||
|
*
|
||||||
|
* 702.77c. The wither rules function no matter what zone an object with wither deals damage from.
|
||||||
|
*
|
||||||
|
* 702.77d. Multiple instances of wither on the same object are redundant.
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class WitherAbility extends StaticAbility<WitherAbility> {
|
||||||
|
|
||||||
|
private static final WitherAbility fINSTANCE = new WitherAbility();
|
||||||
|
|
||||||
|
private Object readResolve() throws ObjectStreamException {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WitherAbility getInstance() {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WitherAbility() {
|
||||||
|
super(Zone.ALL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Wither";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WitherAbility copy() {
|
||||||
|
return fINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -130,9 +130,9 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRules() {
|
public List<String> getRules() {
|
||||||
List<String> rules = abilities.getRules();
|
List<String> rules = abilities.getRules(this.name);
|
||||||
if (cardType.contains(CardType.INSTANT) || cardType.contains(CardType.SORCERY)) {
|
if (cardType.contains(CardType.INSTANT) || cardType.contains(CardType.SORCERY)) {
|
||||||
rules.add(0, getSpellAbility().getRule());
|
rules.add(0, getSpellAbility().getRule(this.name));
|
||||||
}
|
}
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,19 @@ public abstract class ExpansionSet implements Serializable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String findCard(String name, boolean random) {
|
||||||
|
List<String> cards = new ArrayList<String>();
|
||||||
|
for (Card card: createCards()) {
|
||||||
|
if (name.equals(card.getName())) {
|
||||||
|
cards.add(card.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cards.size() > 0) {
|
||||||
|
return cards.get(rnd.nextInt(cards.size()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public String findCard(int cardNum) {
|
public String findCard(int cardNum) {
|
||||||
for (Card card: createCards()) {
|
for (Card card: createCards()) {
|
||||||
if (card.getCardNumber() == cardNum)
|
if (card.getCardNumber() == cardNum)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue