mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +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 javax.imageio.ImageIO;
|
||||
import javax.swing.Box;
|
||||
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.*;
|
||||
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.components.MageComponents;
|
||||
import mage.client.components.MageJDesktop;
|
||||
import mage.client.components.MageRoundPane;
|
||||
import mage.client.components.arcane.ManaSymbols;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.client.dialog.*;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.remote.Session;
|
||||
|
@ -122,7 +116,8 @@ public class MageFrame extends javax.swing.JFrame {
|
|||
});
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||
UIManager.put("desktop", new Color(0,0,0,0));
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||
//MageSynthStyleFactory f = new MageSynthStyleFactory(SynthLookAndFeel.getStyleFactory());
|
||||
//SynthLookAndFeel.setStyleFactory(f);
|
||||
} catch (Exception ex) {
|
||||
|
@ -145,61 +140,13 @@ public class MageFrame extends javax.swing.JFrame {
|
|||
desktopPane.add(pickNumber, JLayeredPane.POPUP_LAYER);
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
addTooltipContainer();
|
||||
setBackground();
|
||||
addMageLabel();
|
||||
setAppIcon();
|
||||
|
||||
desktopPane.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.DRAG_LAYER);
|
||||
|
||||
desktopPane.addComponentListener(new ComponentAdapter(){
|
||||
|
@ -270,6 +217,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) {
|
||||
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
|
||||
private void initComponents() {
|
||||
|
||||
desktopPane = new javax.swing.JDesktopPane();
|
||||
desktopPane = new MageJDesktop();
|
||||
tablesPane = new mage.client.table.TablesPane();
|
||||
gamePane = new mage.client.game.GamePane();
|
||||
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
|
||||
this.gamePane.setVisible(false);
|
||||
this.tablesPane.setVisible(false);
|
||||
this.deckEditorPane.setVisible(true);
|
||||
this.deckEditorPane.showTables();
|
||||
showDeckEditor(DeckEditorMode.Constructed, null, null);
|
||||
}//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[]{});
|
||||
}
|
||||
|
||||
|
@ -546,6 +563,11 @@ public class MageFrame extends javax.swing.JFrame {
|
|||
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() {
|
||||
return combat;
|
||||
}
|
||||
|
@ -595,7 +617,7 @@ public class MageFrame extends javax.swing.JFrame {
|
|||
private javax.swing.JButton btnExit;
|
||||
private javax.swing.JButton btnGames;
|
||||
private mage.client.deckeditor.DeckEditorPane deckEditorPane;
|
||||
private static javax.swing.JDesktopPane desktopPane;
|
||||
private static MageJDesktop desktopPane;
|
||||
private mage.client.game.GamePane gamePane;
|
||||
private javax.swing.JToolBar.Separator jSeparator1;
|
||||
private javax.swing.JToolBar.Separator jSeparator2;
|
||||
|
|
|
@ -6,7 +6,8 @@ public enum MageComponents {
|
|||
NEW_TABLE_OK_BUTTON("btnOK"),
|
||||
TABLE_WAITING_START_BUTTON("btnStart"),
|
||||
DESKTOP_PANE("desktopPane"),
|
||||
CARD_INFO_PANE("cardInfoPane");
|
||||
CARD_INFO_PANE("cardInfoPane"),
|
||||
POPUP_CONTAINER("popupContainer");
|
||||
|
||||
private 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 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 MAX_NON_BASIC_SOURCE = DECK_LANDS / 2;
|
||||
|
||||
private static final boolean GENERATE_RANDOM_BASIC_LAND = true;
|
||||
|
||||
private static Deck deck = new Deck();
|
||||
private static String manaSource;
|
||||
|
||||
|
@ -283,19 +285,19 @@ public class DeckGenerator {
|
|||
private static Card getBestBasicLand(ColoredManaSymbol color) {
|
||||
manaSource = color.toString();
|
||||
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)) {
|
||||
return CardImpl.createCard(Sets.findCard("Mountain"));
|
||||
return CardImpl.createCard(Sets.findCard("Mountain", GENERATE_RANDOM_BASIC_LAND));
|
||||
}
|
||||
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)) {
|
||||
return CardImpl.createCard(Sets.findCard("Island"));
|
||||
return CardImpl.createCard(Sets.findCard("Island", GENERATE_RANDOM_BASIC_LAND));
|
||||
}
|
||||
if (color.equals(ColoredManaSymbol.W)) {
|
||||
return CardImpl.createCard(Sets.findCard("Plains"));
|
||||
return CardImpl.createCard(Sets.findCard("Plains", GENERATE_RANDOM_BASIC_LAND));
|
||||
}
|
||||
|
||||
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">
|
||||
<SyntheticProperties>
|
||||
|
|
|
@ -37,10 +37,13 @@ package mage.client.deckeditor;
|
|||
import java.awt.Component;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import mage.cards.decks.Deck;
|
||||
|
||||
import mage.client.MagePane;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
|
||||
/**
|
||||
|
@ -70,8 +73,8 @@ public class DeckEditorPane extends MagePane {
|
|||
}
|
||||
}
|
||||
|
||||
public void showTables() {
|
||||
this.deckEditorPanel1.showDeckEditor();
|
||||
public void show(DeckEditorMode mode, Deck deck, UUID tableId) {
|
||||
this.deckEditorPanel1.showDeckEditor(mode, deck, tableId);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ package mage.client.deckeditor;
|
|||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.util.Event;
|
||||
|
@ -49,14 +48,13 @@ import mage.view.CardsView;
|
|||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.sets.Sets;
|
||||
|
||||
/**
|
||||
|
@ -69,6 +67,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
private JFileChooser fcImportDeck;
|
||||
private Deck deck = new Deck();
|
||||
private boolean isShowCardInfo = false;
|
||||
private UUID tableId;
|
||||
|
||||
/** Creates new form DeckEditorPanel */
|
||||
public DeckEditorPanel() {
|
||||
|
@ -85,10 +84,18 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
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.setVisible(true);
|
||||
this.jPanel1.setVisible(true);
|
||||
this.btnSubmit.setVisible(mode == DeckEditorMode.Sideboard);
|
||||
this.cardSelector.getCardsList().clearCardEventListeners();
|
||||
this.cardSelector.getCardsList().addCardEventListener(
|
||||
new Listener<Event> () {
|
||||
|
@ -132,6 +139,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
}
|
||||
);
|
||||
refreshDeck();
|
||||
this.setVisible(true);
|
||||
this.repaint();
|
||||
}
|
||||
|
@ -172,6 +180,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
btnNew = new javax.swing.JButton();
|
||||
btnExit = new javax.swing.JButton();
|
||||
btnImport = new javax.swing.JButton();
|
||||
btnSubmit = new javax.swing.JButton();
|
||||
|
||||
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||
jSplitPane1.setResizeWeight(0.5);
|
||||
|
@ -229,7 +238,15 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
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);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
@ -253,7 +270,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
.addComponent(btnExit))
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(btnImport)))
|
||||
.addComponent(btnImport)
|
||||
.addContainerGap()
|
||||
.addComponent(btnSubmit)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
|
@ -270,7 +289,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
.addComponent(btnNew)
|
||||
.addComponent(btnExit))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnImport)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnImport)
|
||||
.addComponent(btnSubmit))
|
||||
.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(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);
|
||||
}//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) {
|
||||
if (file.toLowerCase().endsWith("dec"))
|
||||
return new DecDeckImporter();
|
||||
|
@ -410,6 +436,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private JComponent cardInfoPane;
|
||||
private javax.swing.JButton btnSubmit;
|
||||
}
|
||||
|
||||
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
|
||||
Session session = MageFrame.getSession();
|
||||
try {
|
||||
PhaseManager.getInstance().setName(this.newPlayerPanel.getPlayerName());
|
||||
joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), Sets.loadDeck(this.newPlayerPanel.getDeckFile()));
|
||||
} catch (Exception ex) {
|
||||
handleError(ex);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" 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"/>
|
||||
<EmptySpace 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">
|
||||
<EmptySpace 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 type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
|
@ -41,17 +41,22 @@
|
|||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" 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>
|
||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<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>
|
||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" 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>
|
||||
<Component id="lblGameType" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -61,34 +66,34 @@
|
|||
</Group>
|
||||
<Group type="102" alignment="1" 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"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace 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 type="102" alignment="0" 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"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace 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 type="102" alignment="0" 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"/>
|
||||
</Group>
|
||||
<Component id="pnlOtherPlayers" alignment="0" min="-2" pref="486" max="-2" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" 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"/>
|
||||
</Group>
|
||||
</Group>
|
||||
|
@ -105,25 +110,32 @@
|
|||
<Component id="lblGameType" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="cbGameType" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" 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">
|
||||
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="spnNumPlayers" min="-2" 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="102" alignment="1" attributes="0">
|
||||
<Component id="lblNumPlayers" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="spnNumPlayers" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="lblRange" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="cbRange" min="-2" max="-2" attributes="0"/>
|
||||
</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>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="lblRange" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblNumWins" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="cbRange" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spnNumWins" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -132,21 +144,21 @@
|
|||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" 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"/>
|
||||
<Component id="jSeparator1" pref="4" max="32767" attributes="0"/>
|
||||
<Component id="jSeparator1" pref="19" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnOK" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="223" 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>
|
||||
|
@ -260,5 +272,18 @@
|
|||
<Property name="text" type="java.lang.String" value="Other Players"/>
|
||||
</Properties>
|
||||
</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>
|
||||
</Form>
|
||||
|
|
|
@ -53,6 +53,7 @@ import mage.client.remote.Session;
|
|||
import mage.client.table.TablePlayerPanel;
|
||||
import mage.client.util.Event;
|
||||
import mage.client.util.Listener;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.sets.Sets;
|
||||
import mage.util.Logging;
|
||||
import mage.view.GameTypeView;
|
||||
|
@ -77,6 +78,7 @@ public class NewTableDialog extends MageDialog {
|
|||
/** Creates new form NewTableDialog */
|
||||
public NewTableDialog() {
|
||||
initComponents();
|
||||
this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1));
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
|
@ -107,6 +109,8 @@ public class NewTableDialog extends MageDialog {
|
|||
jLabel1 = new javax.swing.JLabel();
|
||||
jSeparator3 = new javax.swing.JSeparator();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
lblNumWins = new javax.swing.JLabel();
|
||||
spnNumWins = new javax.swing.JSpinner();
|
||||
|
||||
setTitle("New Table");
|
||||
|
||||
|
@ -157,12 +161,21 @@ public class NewTableDialog extends MageDialog {
|
|||
jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));
|
||||
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());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap(358, Short.MAX_VALUE)
|
||||
.addContainerGap(395, Short.MAX_VALUE)
|
||||
.addComponent(btnOK)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnCancel)
|
||||
|
@ -170,7 +183,7 @@ public class NewTableDialog extends MageDialog {
|
|||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(lbDeckType)
|
||||
.addContainerGap(426, Short.MAX_VALUE))
|
||||
.addContainerGap(463, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
|
@ -178,43 +191,47 @@ public class NewTableDialog extends MageDialog {
|
|||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblNumPlayers)
|
||||
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblRange)
|
||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.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(cbDeckType, 0, 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()
|
||||
.addContainerGap()
|
||||
.addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1)
|
||||
.addContainerGap(396, Short.MAX_VALUE))
|
||||
.addContainerGap(433, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
||||
.addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel2)
|
||||
.addContainerGap(399, Short.MAX_VALUE))
|
||||
.addContainerGap(436, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 486, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
|
||||
.addContainerGap()))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
|
@ -229,19 +246,24 @@ public class NewTableDialog extends MageDialog {
|
|||
.addGap(0, 0, 0)
|
||||
.addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblNumPlayers)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblRange)
|
||||
.addGap(0, 0, 0)
|
||||
.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(lblAttack)
|
||||
.addComponent(lblNumWins)
|
||||
.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(lblNumPlayers)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblRange)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
|
@ -251,19 +273,19 @@ public class NewTableDialog extends MageDialog {
|
|||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jLabel2)
|
||||
.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)
|
||||
.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)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnCancel)
|
||||
.addComponent(btnOK))
|
||||
.addGap(0, 0, 0))
|
||||
.addGap(6, 6, 6))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(223, 223, 223)
|
||||
.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();
|
||||
|
@ -277,18 +299,16 @@ public class NewTableDialog extends MageDialog {
|
|||
|
||||
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
||||
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
||||
List<String> playerTypes = new ArrayList<String>();
|
||||
playerTypes.add("Human");
|
||||
MatchOptions options = new MatchOptions("Quick Start Game", gameType.getName());
|
||||
options.getPlayerTypes().add("Human");
|
||||
for (TablePlayerPanel player: players) {
|
||||
playerTypes.add(player.getPlayerType());
|
||||
options.getPlayerTypes().add(player.getPlayerType());
|
||||
}
|
||||
table = session.createTable(
|
||||
roomId,
|
||||
gameType.getName(),
|
||||
(String)this.cbDeckType.getSelectedItem(),
|
||||
playerTypes,
|
||||
(MultiplayerAttackOption)this.cbAttackOption.getSelectedItem(),
|
||||
(RangeOfInfluence)this.cbRange.getSelectedItem());
|
||||
options.setDeckType((String) this.cbDeckType.getSelectedItem());
|
||||
options.setAttackOption((MultiplayerAttackOption) this.cbAttackOption.getSelectedItem());
|
||||
options.setRange((RangeOfInfluence) this.cbRange.getSelectedItem());
|
||||
options.setWinsNeeded((Integer)this.spnNumWins.getValue());
|
||||
table = session.createTable(roomId, options);
|
||||
try {
|
||||
if (session.joinTable(roomId, table.getTableId(), this.player1Panel.getPlayerName(), Sets.loadDeck(this.player1Panel.getDeckFile()))) {
|
||||
for (TablePlayerPanel player: players) {
|
||||
|
@ -325,6 +345,10 @@ public class NewTableDialog extends MageDialog {
|
|||
createPlayers(numPlayers);
|
||||
}//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() {
|
||||
GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem();
|
||||
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 lblGameType;
|
||||
private javax.swing.JLabel lblNumPlayers;
|
||||
private javax.swing.JLabel lblNumWins;
|
||||
private javax.swing.JLabel lblRange;
|
||||
private mage.client.table.NewPlayerPanel player1Panel;
|
||||
private javax.swing.JPanel pnlOtherPlayers;
|
||||
private javax.swing.JSpinner spnNumPlayers;
|
||||
private javax.swing.JSpinner spnNumWins;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
|
|
|
@ -96,14 +96,14 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
|||
}
|
||||
|
||||
public void update(Map<UUID, PermanentView> battlefield) {
|
||||
boolean changed = false;
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
List<PermanentView> permanentsToAdd = new ArrayList<PermanentView>();
|
||||
for (PermanentView permanent: battlefield.values()) {
|
||||
if (!permanents.containsKey(permanent.getId())) {
|
||||
addPermanent(permanent);
|
||||
permanentsToAdd.add(permanent);
|
||||
changed = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
MagePermanent p = permanents.get(permanent.getId());
|
||||
if (!changed) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
int count = permanentsToAdd.size();
|
||||
for (PermanentView permanent : permanentsToAdd) {
|
||||
addPermanent(permanent, count);
|
||||
}
|
||||
|
||||
for (Iterator<Entry<UUID, MagePermanent>> i = permanents.entrySet().iterator(); i.hasNext();) {
|
||||
Entry<UUID, MagePermanent> entry = i.next();
|
||||
if (!battlefield.containsKey(entry.getKey())) {
|
||||
removePermanent(entry.getKey());
|
||||
removePermanent(entry.getKey(), 1);
|
||||
i.remove();
|
||||
changed = true;
|
||||
}
|
||||
|
@ -150,12 +155,12 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
|||
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);
|
||||
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
||||
perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight)));
|
||||
} else {
|
||||
perm.setAlpha(0);
|
||||
//perm.setAlpha(0);
|
||||
}
|
||||
permanents.put(permanent.getId(), perm);
|
||||
|
||||
|
@ -164,15 +169,16 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
|||
moveToFront(perm);
|
||||
perm.update(permanent);
|
||||
} else {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
Plugins.getInstance().onAddCard(perm, 1);
|
||||
/*Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Plugins.getInstance().onAddCard(perm);
|
||||
Plugins.getInstance().onAddCard(perm, count);
|
||||
}
|
||||
});
|
||||
synchronized (this) {
|
||||
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()) {
|
||||
final Component comp = c;
|
||||
if (comp instanceof Permanent) {
|
||||
|
@ -220,7 +226,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
|||
Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Plugins.getInstance().onRemoveCard((MagePermanent)comp);
|
||||
Plugins.getInstance().onRemoveCard((MagePermanent)comp, count);
|
||||
BattlefieldPanel.this.remove(comp);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ public interface MagePlugins {
|
|||
int getGamesPlayed();
|
||||
void addGamesPlayed();
|
||||
Image getManaSymbolImage(String symbol);
|
||||
void onAddCard(MagePermanent card);
|
||||
void onRemoveCard(MagePermanent card);
|
||||
void onAddCard(MagePermanent card, int count);
|
||||
void onRemoveCard(MagePermanent card, int count);
|
||||
JComponent getCardInfoPane();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.awt.*;
|
|||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -16,6 +17,7 @@ import mage.cards.action.TransferData;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.cards.BigCard;
|
||||
import mage.client.components.MageComponents;
|
||||
import mage.client.components.MageRoundPane;
|
||||
import mage.client.game.PlayAreaPanel;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.remote.Session;
|
||||
|
@ -31,95 +33,95 @@ import org.jdesktop.swingx.JXPanel;
|
|||
|
||||
public class MageActionCallback implements ActionCallback {
|
||||
|
||||
private Popup popup;
|
||||
private Popup popup;
|
||||
private JPopupMenu jPopupMenu;
|
||||
private BigCard bigCard;
|
||||
protected static DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
|
||||
protected static Session session = MageFrame.getSession();
|
||||
private CardView popupCard;
|
||||
private Thread t;
|
||||
private int state = 0;
|
||||
private BigCard bigCard;
|
||||
protected static DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
|
||||
protected static Session session = MageFrame.getSession();
|
||||
private CardView popupCard;
|
||||
private Thread t;
|
||||
private int state = 0;
|
||||
private JComponent cardInfoPane;
|
||||
|
||||
public MageActionCallback() {
|
||||
}
|
||||
|
||||
public void setCardPreviewComponent(BigCard bigCard) {
|
||||
this.bigCard = bigCard;
|
||||
}
|
||||
|
||||
public void refreshSession() {
|
||||
if (session == null) {
|
||||
session = MageFrame.getSession();
|
||||
}
|
||||
|
||||
public MageActionCallback() {
|
||||
}
|
||||
|
||||
public void setCardPreviewComponent(BigCard bigCard) {
|
||||
this.bigCard = bigCard;
|
||||
}
|
||||
|
||||
public void refreshSession() {
|
||||
if (session == null) {
|
||||
session = MageFrame.getSession();
|
||||
}
|
||||
if (cardInfoPane == null) {
|
||||
cardInfoPane = Plugins.getInstance().getCardInfoPane();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e, TransferData data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e, TransferData data) {
|
||||
data.component.requestFocusInWindow();
|
||||
defaultCallback.mouseClicked(e, data.gameId, session, data.card);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e, final TransferData data) {
|
||||
hidePopup();
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e, TransferData data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e, TransferData data) {
|
||||
data.component.requestFocusInWindow();
|
||||
defaultCallback.mouseClicked(e, data.gameId, session, data.card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e, final TransferData data) {
|
||||
hidePopup();
|
||||
this.popupCard = data.card;
|
||||
|
||||
Component parentComponent = SwingUtilities.getRoot(data.component);
|
||||
Point parentPoint = parentComponent.getLocationOnScreen();
|
||||
|
||||
// Draw Arrows for targets
|
||||
List<UUID> targets = data.card.getTargets();
|
||||
if (targets != null) {
|
||||
Point me = new Point(data.locationOnScreen);
|
||||
me.translate(-parentPoint.x, -parentPoint.y);
|
||||
for (UUID uuid : targets) {
|
||||
//System.out.println("Getting play area panel for uuid: " + uuid);
|
||||
|
||||
PlayAreaPanel p = session.getGame().getPlayers().get(uuid);
|
||||
if (p != null) {
|
||||
Point target = p.getLocationOnScreen();
|
||||
target.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() - 40, Color.red);
|
||||
} else {
|
||||
for (PlayAreaPanel pa : session.getGame().getPlayers().values()) {
|
||||
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
|
||||
if (permanent != null) {
|
||||
Point target = permanent.getLocationOnScreen();
|
||||
target.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() + 10, Color.red);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Arrows for source
|
||||
if (data.card.isAbility()) {
|
||||
Point me = new Point(data.locationOnScreen);
|
||||
me.translate(-parentPoint.x, -parentPoint.y);
|
||||
UUID uuid = data.card.getParentId();
|
||||
for (PlayAreaPanel pa : session.getGame().getPlayers().values()) {
|
||||
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
|
||||
if (permanent != null) {
|
||||
Point source = permanent.getLocationOnScreen();
|
||||
source.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int)source.getX() + 40, (int)source.getY() + 10, (int)me.getX() + 35, (int)me.getY() + 20, Color.blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showPopup(data, parentComponent, parentPoint);
|
||||
}
|
||||
// Draw Arrows for targets
|
||||
List<UUID> targets = data.card.getTargets();
|
||||
if (targets != null) {
|
||||
Point me = new Point(data.locationOnScreen);
|
||||
me.translate(-parentPoint.x, -parentPoint.y);
|
||||
for (UUID uuid : targets) {
|
||||
//System.out.println("Getting play area panel for uuid: " + uuid);
|
||||
|
||||
private void showPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
|
||||
PlayAreaPanel p = session.getGame().getPlayers().get(uuid);
|
||||
if (p != null) {
|
||||
Point target = p.getLocationOnScreen();
|
||||
target.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() - 40, Color.red);
|
||||
} else {
|
||||
for (PlayAreaPanel pa : session.getGame().getPlayers().values()) {
|
||||
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
|
||||
if (permanent != null) {
|
||||
Point target = permanent.getLocationOnScreen();
|
||||
target.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() + 10, Color.red);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Arrows for source
|
||||
if (data.card.isAbility()) {
|
||||
Point me = new Point(data.locationOnScreen);
|
||||
me.translate(-parentPoint.x, -parentPoint.y);
|
||||
UUID uuid = data.card.getParentId();
|
||||
for (PlayAreaPanel pa : session.getGame().getPlayers().values()) {
|
||||
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
|
||||
if (permanent != null) {
|
||||
Point source = permanent.getLocationOnScreen();
|
||||
source.translate(-parentPoint.x, -parentPoint.y);
|
||||
ArrowBuilder.addArrow((int) source.getX() + 40, (int) source.getY() + 10, (int) me.getX() + 35, (int) me.getY() + 20, Color.blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showPopup(data, parentComponent, parentPoint);
|
||||
}
|
||||
|
||||
private void showPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
|
||||
if (cardInfoPane == null) {
|
||||
PopupFactory factory = PopupFactory.getSharedInstance();
|
||||
popup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40);
|
||||
|
@ -133,72 +135,73 @@ public class MageActionCallback implements ActionCallback {
|
|||
ThreadUtils.threadPool2.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ThreadUtils.threadPool2.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ThreadUtils.sleep(700);
|
||||
ThreadUtils.sleep(700);
|
||||
|
||||
if (!popupCard.equals(data.card)) {
|
||||
return;
|
||||
}
|
||||
if (!popupCard.equals(data.card)) {
|
||||
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 {
|
||||
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
||||
((CardInfoPane)popup2).setCard(data.card);
|
||||
Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40);
|
||||
location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, popup2, parentComponent);
|
||||
location.translate(-parentPoint.x, -parentPoint.y);
|
||||
popup2.setLocation(location);
|
||||
ThreadUtils.sleep(200);
|
||||
popup2.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
final Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
|
||||
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
||||
((CardInfoPane) popup2).setCard(data.card);
|
||||
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.translate(-parentPoint.x, -parentPoint.y);
|
||||
popupContainer.setLocation(location);
|
||||
ThreadUtils.sleep(200);
|
||||
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) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e, TransferData data) {
|
||||
if (!Plugins.getInstance().isCardPluginLoaded()) {return;}
|
||||
if (bigCard == null) {return;}
|
||||
|
||||
MageCard card = (MageCard) data.component;
|
||||
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
||||
synchronized (MageActionCallback.class) {
|
||||
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
||||
Image image = card.getImage();
|
||||
if (image != null && image instanceof BufferedImage) {
|
||||
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth(), bigCard.getHeight());
|
||||
bigCard.setCard(card.getOriginal().getId(), image, card.getOriginal().getRules());
|
||||
bigCard.showTextComponent();
|
||||
if (card.getOriginal().isAbility()) {
|
||||
bigCard.showTextComponent();
|
||||
} else {
|
||||
bigCard.hideTextComponent();
|
||||
};
|
||||
} else {
|
||||
JXPanel panel = GuiDisplayUtil.getDescription(card.getOriginal(), bigCard.getWidth(), bigCard.getHeight());
|
||||
panel.setVisible(true);
|
||||
bigCard.hideTextComponent();
|
||||
bigCard.addJXPanel(card.getOriginal().getId(), panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e, TransferData data) {
|
||||
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
||||
return;
|
||||
}
|
||||
if (bigCard == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
MageCard card = (MageCard) data.component;
|
||||
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
||||
synchronized (MageActionCallback.class) {
|
||||
if (card.getOriginal().getId() != bigCard.getCardId()) {
|
||||
Image image = card.getImage();
|
||||
if (image != null && image instanceof BufferedImage) {
|
||||
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth(), bigCard.getHeight());
|
||||
bigCard.setCard(card.getOriginal().getId(), image, card.getOriginal().getRules());
|
||||
bigCard.showTextComponent();
|
||||
if (card.getOriginal().isAbility()) {
|
||||
bigCard.showTextComponent();
|
||||
} else {
|
||||
bigCard.hideTextComponent();
|
||||
}
|
||||
;
|
||||
} else {
|
||||
JXPanel panel = GuiDisplayUtil.getDescription(card.getOriginal(), bigCard.getWidth(), bigCard.getHeight());
|
||||
panel.setVisible(true);
|
||||
bigCard.hideTextComponent();
|
||||
bigCard.addJXPanel(card.getOriginal().getId(), panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hidePopup() {
|
||||
this.popupCard = null;
|
||||
|
@ -209,17 +212,17 @@ public class MageActionCallback implements ActionCallback {
|
|||
jPopupMenu.setVisible(false);
|
||||
}
|
||||
try {
|
||||
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
|
||||
popup2.setVisible(false);
|
||||
Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
|
||||
popupContainer.setVisible(false);
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();;
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e, final TransferData data) {
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e, final TransferData data) {
|
||||
hidePopup();
|
||||
ArrowBuilder.removeAllArrows();
|
||||
}
|
||||
ArrowBuilder.removeAllArrows();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -169,16 +169,16 @@ public class Plugins implements MagePlugins {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAddCard(MagePermanent card) {
|
||||
public void onAddCard(MagePermanent card, int count) {
|
||||
if (this.cardPlugin != null) {
|
||||
this.cardPlugin.onAddCard(card);
|
||||
this.cardPlugin.onAddCard(card, count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveCard(MagePermanent card) {
|
||||
public void onRemoveCard(MagePermanent card, int count) {
|
||||
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.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.chat.ChatPanel;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.util.GameManager;
|
||||
import mage.interfaces.callback.CallbackClient;
|
||||
import mage.interfaces.callback.ClientCallback;
|
||||
import mage.util.Logging;
|
||||
|
@ -43,6 +46,7 @@ import mage.view.AbilityPickerView;
|
|||
import mage.view.ChatMessage;
|
||||
import mage.view.GameClientMessage;
|
||||
import mage.view.GameView;
|
||||
import mage.view.TableClientMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -72,8 +76,9 @@ public class Client implements CallbackClient {
|
|||
logger.info(callback.getMessageId() + " - " + callback.getMethod());
|
||||
try {
|
||||
if (callback.getMethod().equals("startGame")) {
|
||||
UUID[] data = (UUID[]) callback.getData();
|
||||
gameStarted(data[0], data[1]);
|
||||
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||
GameManager.getInstance().setCurrentPlayerUUID(message.getPlayerId());
|
||||
gameStarted(message.getGameId(), message.getPlayerId());
|
||||
}
|
||||
else if (callback.getMethod().equals("replayGame")) {
|
||||
replayGame();
|
||||
|
@ -152,6 +157,10 @@ public class Client implements CallbackClient {
|
|||
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();
|
||||
}
|
||||
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) {
|
||||
logger.log(Level.SEVERE, "Client error\n", ex);
|
||||
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.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.chat.ChatPanel;
|
||||
|
@ -50,6 +48,7 @@ import mage.client.game.GamePanel;
|
|||
import mage.client.util.Config;
|
||||
import mage.game.GameException;
|
||||
import mage.interfaces.MageException;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.interfaces.Server;
|
||||
import mage.interfaces.ServerState;
|
||||
import mage.interfaces.callback.CallbackClientDaemon;
|
||||
|
@ -396,9 +395,9 @@ public class Session {
|
|||
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 {
|
||||
return server.createTable(sessionId, roomId, gameType, deckType, playerTypes, attackOption, range);
|
||||
return server.createTable(sessionId, roomId, matchOptions);
|
||||
} catch (RemoteException ex) {
|
||||
handleRemoteException(ex);
|
||||
} catch (MageException ex) {
|
||||
|
@ -456,7 +455,7 @@ public class Session {
|
|||
|
||||
public boolean startGame(UUID roomId, UUID tableId) {
|
||||
try {
|
||||
server.startGame(sessionId, roomId, tableId);
|
||||
server.startMatch(sessionId, roomId, tableId);
|
||||
return true;
|
||||
} catch (RemoteException ex) {
|
||||
handleRemoteException(ex);
|
||||
|
@ -466,6 +465,20 @@ public class Session {
|
|||
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) {
|
||||
try {
|
||||
server.concedeGame(gameId, sessionId);
|
||||
|
|
|
@ -37,9 +37,7 @@ package mage.client.table;
|
|||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
@ -53,8 +51,9 @@ import javax.swing.JComponent;
|
|||
import javax.swing.JOptionPane;
|
||||
import javax.swing.Timer;
|
||||
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.components.MageComponents;
|
||||
import mage.client.dialog.JoinTableDialog;
|
||||
|
@ -63,6 +62,7 @@ import mage.client.dialog.TableWaitingDialog;
|
|||
import mage.client.remote.MageRemoteException;
|
||||
import mage.client.remote.Session;
|
||||
import mage.client.util.ButtonColumn;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.sets.Sets;
|
||||
import mage.util.Logging;
|
||||
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
|
||||
TableView table;
|
||||
try {
|
||||
List<String> playerTypes = new ArrayList<String>();
|
||||
playerTypes.add("Human");
|
||||
playerTypes.add("Computer - default");
|
||||
table = session.createTable(
|
||||
roomId,
|
||||
"Two Player Duel",
|
||||
"Constructed",
|
||||
playerTypes,
|
||||
null, null
|
||||
);
|
||||
MatchOptions options = new MatchOptions("1", "Two Player Duel");
|
||||
options.getPlayerTypes().add("Human");
|
||||
options.getPlayerTypes().add("Computer - default");
|
||||
options.setDeckType("Limited");
|
||||
options.setAttackOption(MultiplayerAttackOption.LEFT);
|
||||
options.setRange(RangeOfInfluence.ALL);
|
||||
options.setWinsNeeded(1);
|
||||
table = session.createTable(roomId, options);
|
||||
session.joinTable(
|
||||
roomId,
|
||||
table.getTableId(),
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mage.client.util;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Controls game state on client side.
|
||||
*
|
||||
|
@ -7,15 +9,27 @@ package mage.client.util;
|
|||
*/
|
||||
public class GameManager {
|
||||
private static GameManager fInstance = new GameManager();
|
||||
|
||||
public static GameManager getInstance() {
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
public void setStackSize(int stackSize) {
|
||||
this.stackSize = stackSize;
|
||||
}
|
||||
|
||||
public int getStackSize() {
|
||||
return 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.view.GameView;
|
||||
import mage.view.PlayerView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class PhaseManager {
|
||||
|
@ -51,21 +53,27 @@ public class PhaseManager {
|
|||
put("End Turn - play instants and activated abilities.", END_OF_TURN_OTHERS);
|
||||
}};
|
||||
|
||||
private String yourName;
|
||||
|
||||
public static PhaseManager getInstance() {
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
public void setName(String yourName) {
|
||||
this.yourName = yourName;
|
||||
}
|
||||
|
||||
public boolean isSkip(GameView gameView, String message) {
|
||||
if (GameManager.getInstance().getStackSize() > 0) {
|
||||
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()) {
|
||||
if (message.equals(entry.getKey())) {
|
||||
Preferences prefs = MageFrame.getPreferences();
|
||||
|
|
|
@ -14,7 +14,8 @@ import org.jdesktop.swingx.JXPanel;
|
|||
|
||||
public class GuiDisplayUtil {
|
||||
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) {
|
||||
JXPanel descriptionPanel = new JXPanel();
|
||||
|
@ -127,12 +128,12 @@ public class GuiDisplayUtil {
|
|||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
l.y = Math.max(10, dy - c.getHeight());
|
||||
}
|
||||
|
|
|
@ -28,16 +28,14 @@
|
|||
|
||||
package mage.interfaces;
|
||||
|
||||
import mage.game.match.MatchOptions;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.interfaces.callback.CallbackServer;
|
||||
import mage.view.GameTypeView;
|
||||
import mage.view.TableView;
|
||||
import mage.view.GameView;
|
||||
|
||||
|
@ -54,8 +52,9 @@ public interface Server extends Remote, CallbackServer {
|
|||
public ServerState getServerState() throws RemoteException, MageException;
|
||||
|
||||
//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 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 replayTable(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;
|
||||
|
||||
//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 watchGame(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 downloadSymbols();
|
||||
Image getManaSymbolImage(String symbol);
|
||||
void onAddCard(MagePermanent card);
|
||||
void onRemoveCard(MagePermanent card);
|
||||
void onAddCard(MagePermanent card, int count);
|
||||
void onRemoveCard(MagePermanent card, int count);
|
||||
JComponent getCardInfoPane();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public class AbilityView extends CardView {
|
|||
this.sourceName = sourceName;
|
||||
this.sourceCard = sourceCard;
|
||||
this.rules = new ArrayList<String>();
|
||||
rules.add(formatRule(ability.getRule()));
|
||||
rules.add(ability.getRule(sourceName));
|
||||
this.power = "";
|
||||
this.toughness = "";
|
||||
this.loyalty = "";
|
||||
|
@ -60,13 +60,6 @@ public class AbilityView extends CardView {
|
|||
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() {
|
||||
return this.sourceCard;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public class CardView implements Serializable {
|
|||
public CardView(Card card) {
|
||||
this.id = card.getId();
|
||||
this.name = card.getName();
|
||||
this.rules = formatRules(card.getRules());
|
||||
this.rules = card.getRules();
|
||||
if (card instanceof Permanent) {
|
||||
this.power = Integer.toString(card.getPower().getValue());
|
||||
this.toughness = Integer.toString(card.getToughness().getValue());
|
||||
|
@ -118,7 +118,7 @@ public class CardView implements Serializable {
|
|||
CardView(Token token) {
|
||||
this.id = token.getId();
|
||||
this.name = token.getName();
|
||||
this.rules = formatRules(token.getAbilities().getRules());
|
||||
this.rules = token.getAbilities().getRules(this.name);
|
||||
this.power = token.getPower().toString();
|
||||
this.toughness = token.getToughness().toString();
|
||||
this.loyalty = token.getLoyalty().toString();
|
||||
|
@ -143,19 +143,19 @@ public class CardView implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
protected List<String> formatRules(List<String> rules) {
|
||||
List<String> newRules = new ArrayList<String>();
|
||||
for (String rule: rules) {
|
||||
newRules.add(formatRule(rule));
|
||||
}
|
||||
return newRules;
|
||||
}
|
||||
|
||||
protected String formatRule(String rule) {
|
||||
String replace = rule.replace("{this}", this.name);
|
||||
replace = replace.replace("{source}", this.name);
|
||||
return replace;
|
||||
}
|
||||
// protected List<String> formatRules(List<String> rules) {
|
||||
// List<String> newRules = new ArrayList<String>();
|
||||
// for (String rule: rules) {
|
||||
// newRules.add(formatRule(rule));
|
||||
// }
|
||||
// return newRules;
|
||||
// }
|
||||
//
|
||||
// protected String formatRule(String rule) {
|
||||
// String replace = rule.replace("{this}", this.name);
|
||||
// replace = replace.replace("{source}", this.name);
|
||||
// return replace;
|
||||
// }
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
package mage.view;
|
||||
|
||||
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 useAttackOption;
|
||||
|
||||
public GameTypeView(GameType gameType) {
|
||||
public GameTypeView(MatchType gameType) {
|
||||
this.name = gameType.getName();
|
||||
this.minPlayers = gameType.getMinPlayers();
|
||||
this.maxPlayers = gameType.getMaxPlayers();
|
||||
|
|
|
@ -47,7 +47,7 @@ public class StackAbilityView extends CardView {
|
|||
this.sourceName = sourceName;
|
||||
this.sourceCard = sourceCard;
|
||||
this.rules = new ArrayList<String>();
|
||||
rules.add(formatRule(ability.getRule()));
|
||||
rules.add(ability.getRule(sourceName));
|
||||
this.power = ability.getPower().toString();
|
||||
this.toughness = ability.getToughness().toString();
|
||||
this.loyalty = ability.getLoyalty().toString();
|
||||
|
@ -60,13 +60,6 @@ public class StackAbilityView extends CardView {
|
|||
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() {
|
||||
return this.sourceCard;
|
||||
}
|
||||
|
|
|
@ -26,63 +26,46 @@
|
|||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game;
|
||||
package mage.view;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class MatchImpl implements Match {
|
||||
public class TableClientMessage implements Serializable {
|
||||
|
||||
protected List<MatchPlayer> players = new ArrayList<MatchPlayer>();
|
||||
protected List<Game> games = new ArrayList<Game>();
|
||||
protected int winsNeeded;
|
||||
protected int maxPlayers;
|
||||
protected int minPlayers;
|
||||
|
||||
public MatchImpl(int winsNeeded) {
|
||||
this.winsNeeded = winsNeeded;
|
||||
private Deck deck;
|
||||
private UUID tableId;
|
||||
private UUID gameId;
|
||||
private UUID playerId;
|
||||
|
||||
public TableClientMessage(Deck deck, UUID tableId) {
|
||||
this.deck = deck;
|
||||
this.tableId = tableId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MatchPlayer> getPlayers() {
|
||||
return players;
|
||||
public TableClientMessage(UUID gameId, UUID playerId) {
|
||||
this.gameId = gameId;
|
||||
this.playerId = playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayer(Player player, Deck deck) {
|
||||
MatchPlayer mPlayer = new MatchPlayer(player, deck);
|
||||
players.add(mPlayer);
|
||||
public Deck getDeck() {
|
||||
return deck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMatch() {
|
||||
|
||||
public UUID getTableId() {
|
||||
return tableId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
for (MatchPlayer player: players) {
|
||||
if (player.getWins() >= winsNeeded) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public UUID getGameId() {
|
||||
return gameId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPlayers() {
|
||||
return this.maxPlayers;
|
||||
public UUID getPlayerId() {
|
||||
return playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinPlayers() {
|
||||
return this.minPlayers;
|
||||
}
|
||||
|
||||
}
|
|
@ -287,8 +287,11 @@ abstract public class Animation {
|
|||
}
|
||||
}
|
||||
|
||||
static public void showCard(final MagePermanent card) {
|
||||
new Animation(600) {
|
||||
static public void showCard(final MagePermanent card, int count) {
|
||||
if (count == 0) {
|
||||
count = 1;
|
||||
}
|
||||
new Animation(600 / count) {
|
||||
protected void start () {
|
||||
}
|
||||
|
||||
|
@ -304,8 +307,11 @@ abstract public class Animation {
|
|||
};
|
||||
}
|
||||
|
||||
static public void hideCard(final MagePermanent card) {
|
||||
new Animation(600) {
|
||||
static public void hideCard(final MagePermanent card, int count) {
|
||||
if (count == 0) {
|
||||
count = 1;
|
||||
}
|
||||
new Animation(600 / count) {
|
||||
protected void start () {
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
static private final float rotCenterToBottomCorner = 0.7071067811865475244008443621048f;
|
||||
|
||||
public CardView gameCard;
|
||||
public PermanentView gamePermanent;
|
||||
public CardPanel attachedToPanel;
|
||||
public List<CardPanel> attachedPanels = new ArrayList();
|
||||
//public List<CardPanel> attachedPanels = new ArrayList();
|
||||
private List<MagePermanent> links = new ArrayList<MagePermanent>();
|
||||
public double tappedAngle = 0;
|
||||
public ScaledImagePanel imagePanel;
|
||||
public ImagePanel overlayPanel;
|
||||
|
@ -101,8 +100,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
this.isPermanent = this.gameCard instanceof PermanentView;
|
||||
|
||||
if (isPermanent) {
|
||||
this.gamePermanent = (PermanentView) this.gameCard;
|
||||
this.hasSickness = this.gamePermanent.hasSummoningSickness();
|
||||
this.hasSickness = ((PermanentView) this.gameCard).hasSummoningSickness();
|
||||
}
|
||||
|
||||
//for container debug (don't remove)
|
||||
|
@ -416,6 +414,13 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
@Override
|
||||
public void setAlpha(float 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() {
|
||||
|
@ -449,12 +454,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
|||
|
||||
@Override
|
||||
public List<MagePermanent> getLinks() {
|
||||
List<MagePermanent> list = new ArrayList<MagePermanent>();
|
||||
if (attachedPanels == null) return list;
|
||||
for (MagePermanent p : attachedPanels) {
|
||||
list.add(p);
|
||||
}
|
||||
return list;
|
||||
return links;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -438,9 +438,9 @@ public class CardPluginImpl implements CardPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAddCard(MagePermanent card) {
|
||||
public void onAddCard(MagePermanent card, int count) {
|
||||
if (card != null) {
|
||||
Animation.showCard((CardPanel) card);
|
||||
Animation.showCard((CardPanel) card, count > 0 ? count : 1);
|
||||
try {
|
||||
while ((card).getAlpha() + 0.05f < 1) {
|
||||
Thread.sleep(30);
|
||||
|
@ -452,9 +452,9 @@ public class CardPluginImpl implements CardPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveCard(MagePermanent card) {
|
||||
public void onRemoveCard(MagePermanent card, int count) {
|
||||
if (card != null) {
|
||||
Animation.hideCard((CardPanel) card);
|
||||
Animation.hideCard((CardPanel) card, count > 0 ? count : 1);
|
||||
try {
|
||||
while ((card).getAlpha() - 0.05f > 0) {
|
||||
Thread.sleep(30);
|
||||
|
|
|
@ -24,98 +24,77 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
|||
|
||||
public CardInfoPaneImpl() {
|
||||
UI.setHTMLEditorKit(this);
|
||||
setEditable(false);
|
||||
setBackground(Color.white);
|
||||
setSize(170, Integer.MAX_VALUE);
|
||||
setEditable(false);
|
||||
setBackground(Color.white);
|
||||
}
|
||||
|
||||
public void setCard (final CardView card) {
|
||||
public void setCard(final CardView card) {
|
||||
if (card == null) return;
|
||||
if (isCurrentCard(card)) return;
|
||||
currentCard = card;
|
||||
if (isCurrentCard(card)) return;
|
||||
currentCard = card;
|
||||
|
||||
ThreadUtils.threadPool.submit(new Runnable() {
|
||||
public void run () {
|
||||
if (!card.equals(currentCard)) return;
|
||||
public void run() {
|
||||
if (!card.equals(currentCard)) return;
|
||||
|
||||
String manaCost = "";
|
||||
for (String m : card.getManaCost()) {
|
||||
manaCost += m;
|
||||
}
|
||||
String castingCost = UI.getDisplayManaCost(manaCost);
|
||||
castingCost = ManaSymbols.replaceSymbolsWithHTML(castingCost, false);
|
||||
castingCost = ManaSymbols.replaceSymbolsWithHTML(castingCost, false);
|
||||
|
||||
int symbolCount = 0;
|
||||
int offset = 0;
|
||||
while ((offset = castingCost.indexOf("<img", offset) + 1) != 0)
|
||||
symbolCount++;
|
||||
int offset = 0;
|
||||
while ((offset = castingCost.indexOf("<img", offset) + 1) != 0)
|
||||
symbolCount++;
|
||||
|
||||
List<String> rulings = card.getRules();
|
||||
|
||||
boolean smallImages = true;
|
||||
int fontSize = 11;
|
||||
int fontSize = 11;
|
||||
|
||||
String fontFamily = "tahoma";
|
||||
/*if (prefs.fontFamily == CardFontFamily.arial)
|
||||
fontFamily = "arial";
|
||||
else if (prefs.fontFamily == CardFontFamily.verdana) {
|
||||
fontFamily = "verdana";
|
||||
}*/
|
||||
String fontFamily = "tahoma";
|
||||
/*if (prefs.fontFamily == CardFontFamily.arial)
|
||||
fontFamily = "arial";
|
||||
else if (prefs.fontFamily == CardFontFamily.verdana) {
|
||||
fontFamily = "verdana";
|
||||
}*/
|
||||
|
||||
final StringBuffer buffer = new StringBuffer(512);
|
||||
buffer.append("<html><body style='font-family:");
|
||||
buffer.append(fontFamily);
|
||||
buffer.append(";font-size:");
|
||||
buffer.append(fontSize);
|
||||
buffer.append("pt;margin:0px 1px 0px 1px'>");
|
||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'>");
|
||||
buffer.append("<tr><td valign='top'><b>");
|
||||
buffer.append(card.getName());
|
||||
buffer.append("</b></td><td align='right' valign='top' style='width:");
|
||||
buffer.append(symbolCount * 11 + 1);
|
||||
buffer.append("px'>");
|
||||
buffer.append(castingCost);
|
||||
buffer.append("</td></tr></table>");
|
||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'><tr><td>");
|
||||
buffer.append(getTypes(card));
|
||||
final StringBuffer buffer = new StringBuffer(512);
|
||||
buffer.append("<html><body style='font-family:");
|
||||
buffer.append(fontFamily);
|
||||
buffer.append(";font-size:");
|
||||
buffer.append(fontSize);
|
||||
buffer.append("pt;margin:0px 1px 0px 1px'>");
|
||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'>");
|
||||
buffer.append("<tr><td valign='top'><b>");
|
||||
buffer.append(card.getName());
|
||||
buffer.append("</b></td><td align='right' valign='top' style='width:");
|
||||
buffer.append(symbolCount * 11 + 1);
|
||||
buffer.append("px'>");
|
||||
buffer.append(castingCost);
|
||||
buffer.append("</td></tr></table>");
|
||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'><tr><td style='margin-left: 1px'>");
|
||||
buffer.append(getTypes(card));
|
||||
buffer.append("</td><td align='right'>");
|
||||
switch (card.getRarity()) {
|
||||
case RARE:
|
||||
buffer.append("<b color='#E1D519'>");
|
||||
break;
|
||||
case UNCOMMON:
|
||||
buffer.append("<b color='silver'>");
|
||||
break;
|
||||
case COMMON:
|
||||
buffer.append("<b color='black'>");
|
||||
break;
|
||||
case RARE:
|
||||
buffer.append("<b color='#FFBF00'>");
|
||||
break;
|
||||
case UNCOMMON:
|
||||
buffer.append("<b color='silver'>");
|
||||
break;
|
||||
case COMMON:
|
||||
buffer.append("<b color='black'>");
|
||||
break;
|
||||
case MYTHIC:
|
||||
buffer.append("<b color='#D5330B'>");
|
||||
break;
|
||||
}
|
||||
buffer.append(card.getExpansionSetCode().toUpperCase());
|
||||
buffer.append("<b color='#D5330B'>");
|
||||
break;
|
||||
}
|
||||
buffer.append(card.getExpansionSetCode().toUpperCase());
|
||||
buffer.append("</td></tr></table>");
|
||||
|
||||
String legal = "";
|
||||
if (rulings.size() > 0) {
|
||||
legal = legal.replaceAll("#([^#]+)#", "<i>$1</i>");
|
||||
legal = legal.replaceAll("\\s*//\\s*", "<hr width='50%'>");
|
||||
legal = legal.replace("\r\n", "<div style='font-size:5pt'></div>");
|
||||
legal += "<br>";
|
||||
for (String ruling : rulings) {
|
||||
legal += "<p style='margin: 2px'>";
|
||||
legal += ruling;
|
||||
legal += "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
if (legal.length() > 0) {
|
||||
buffer.append("<br>");
|
||||
legal = legal.replaceAll("\\{this\\}", card.getName());
|
||||
legal = legal.replaceAll("\\{source\\}", card.getName());
|
||||
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, smallImages));
|
||||
}
|
||||
|
||||
String pt = "";
|
||||
if (CardUtil.isCreature(card)) {
|
||||
pt = card.getPower() + "/" + card.getToughness();
|
||||
|
@ -124,23 +103,42 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
|||
}
|
||||
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("<b>");
|
||||
buffer.append(pt);
|
||||
buffer.append("</b>");
|
||||
buffer.append("</td></tr></table>");
|
||||
}
|
||||
|
||||
String legal = "";
|
||||
if (rulings.size() > 0) {
|
||||
legal = legal.replaceAll("#([^#]+)#", "<i>$1</i>");
|
||||
legal = legal.replaceAll("\\s*//\\s*", "<hr width='50%'>");
|
||||
legal = legal.replace("\r\n", "<div style='font-size:5pt'></div>");
|
||||
legal += "<br>";
|
||||
for (String ruling : rulings) {
|
||||
legal += "<p style='margin: 2px'>";
|
||||
legal += ruling;
|
||||
legal += "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
if (legal.length() > 0) {
|
||||
//buffer.append("<br>");
|
||||
legal = legal.replaceAll("\\{this\\}", card.getName());
|
||||
legal = legal.replaceAll("\\{source\\}", card.getName());
|
||||
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, smallImages));
|
||||
}
|
||||
|
||||
buffer.append("<br></body></html>");
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run () {
|
||||
if (!card.equals(currentCard)) return;
|
||||
setText(buffer.toString());
|
||||
public void run() {
|
||||
if (!card.equals(currentCard)) return;
|
||||
setText(buffer.toString());
|
||||
//System.out.println(buffer.toString());
|
||||
setCaretPosition(0);
|
||||
}
|
||||
});
|
||||
setCaretPosition(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -162,7 +160,7 @@ public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane {
|
|||
return types.trim();
|
||||
}
|
||||
|
||||
public boolean isCurrentCard (CardView card) {
|
||||
return currentCard != null && card.equals(currentCard);
|
||||
}
|
||||
public boolean isCurrentCard(CardView card) {
|
||||
return currentCard != null && card.equals(currentCard);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import mage.game.match.MatchType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -59,7 +60,7 @@ public class FreeForAll extends GameImpl<FreeForAll> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
public MatchType getGameType() {
|
||||
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;
|
||||
|
||||
import mage.game.match.MatchType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class FreeForAllType extends GameType {
|
||||
public class FreeForAllType extends MatchType<FreeForAllType> {
|
||||
|
||||
public FreeForAllType() {
|
||||
this.name = "Free For All";
|
||||
|
@ -42,4 +44,13 @@ public class FreeForAllType extends GameType {
|
|||
this.useAttackOption = 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;
|
||||
|
||||
import mage.game.match.MatchType;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
@ -39,7 +40,7 @@ import mage.game.turn.TurnMod;
|
|||
public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
||||
|
||||
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
||||
super(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL);
|
||||
super(attackOption, range);
|
||||
}
|
||||
|
||||
public TwoPlayerDuel(final TwoPlayerDuel game) {
|
||||
|
@ -47,7 +48,7 @@ public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
public MatchType getGameType() {
|
||||
return new TwoPlayerDuelType();
|
||||
}
|
||||
|
||||
|
@ -62,8 +63,8 @@ public class TwoPlayerDuel extends GameImpl<TwoPlayerDuel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
protected void init(UUID choosingPlayerId) {
|
||||
super.init(choosingPlayerId);
|
||||
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,11 +28,13 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import mage.game.match.MatchType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TwoPlayerDuelType extends GameType {
|
||||
public class TwoPlayerDuelType extends MatchType<TwoPlayerDuelType> {
|
||||
|
||||
public TwoPlayerDuelType() {
|
||||
this.name = "Two Player Duel";
|
||||
|
@ -43,4 +45,13 @@ public class TwoPlayerDuelType extends GameType {
|
|||
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.FilterNonlandCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.Table;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
@ -111,7 +112,6 @@ import mage.util.TreeNode;
|
|||
public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> implements Player {
|
||||
|
||||
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 List<Card> playableNonInstant = 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) {
|
||||
super(player);
|
||||
this.abort = player.abort;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -768,6 +767,12 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
return super.getAvailableManaProducers(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sideboard(Table table) {
|
||||
//TODO: improve this
|
||||
table.fireSubmitDeckEvent(playerId, deck);
|
||||
}
|
||||
|
||||
protected Attackers getPotentialAttackers(Game game) {
|
||||
logger.fine("getAvailableAttackers");
|
||||
Attackers attackers = new Attackers();
|
||||
|
|
|
@ -53,6 +53,7 @@ import mage.cards.decks.Deck;
|
|||
import mage.choices.ChoiceImpl;
|
||||
import mage.filter.common.FilterCreatureForCombat;
|
||||
import mage.game.Game;
|
||||
import mage.game.Table;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetAmount;
|
||||
|
@ -71,8 +72,6 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
|
||||
final transient PlayerResponse response = new PlayerResponse();
|
||||
|
||||
private boolean abort;
|
||||
|
||||
protected static FilterCreatureForCombat filter = new FilterCreatureForCombat();
|
||||
protected static Choice replacementEffectChoice = new ChoiceImpl(true);
|
||||
|
||||
|
@ -89,7 +88,6 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
|
||||
public HumanPlayer(final HumanPlayer player) {
|
||||
super(player);
|
||||
this.abort = player.abort;
|
||||
}
|
||||
|
||||
protected void waitForResponse() {
|
||||
|
@ -474,6 +472,11 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
return response.getInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sideboard(Table table) {
|
||||
table.fireSideboardEvent(playerId);
|
||||
}
|
||||
|
||||
protected void specialAction(Game game) {
|
||||
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId);
|
||||
game.fireGetChoiceEvent(playerId, name, specialActions.values());
|
||||
|
@ -540,6 +543,8 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public HumanPlayer copy() {
|
||||
return new HumanPlayer(this);
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<playerType name="Computer - minimax hybrid" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>
|
||||
</playerTypes>
|
||||
<gameTypes>
|
||||
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerDuel" typeName="mage.game.TwoPlayerDuelType"/>
|
||||
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAll" typeName="mage.game.FreeForAllType"/>
|
||||
<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.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
|
||||
</gameTypes>
|
||||
<deckTypes>
|
||||
<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.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import mage.game.GameType;
|
||||
import mage.game.match.MatchType;
|
||||
import mage.server.game.DeckValidatorFactory;
|
||||
import mage.server.game.GameFactory;
|
||||
import mage.server.game.PlayerFactory;
|
||||
|
@ -119,11 +119,11 @@ public class Main {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static GameType loadGameType(GamePlugin plugin) {
|
||||
private static MatchType loadGameType(GamePlugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
||||
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) {
|
||||
logger.log(Level.SEVERE, "Game type not found:" + plugin.getJar() + " - check plugin folder");
|
||||
} catch (Exception ex) {
|
||||
|
|
|
@ -39,11 +39,10 @@ import java.util.UUID;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.interfaces.MageException;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.interfaces.Server;
|
||||
import mage.interfaces.ServerState;
|
||||
import mage.interfaces.callback.ClientCallback;
|
||||
|
@ -56,7 +55,6 @@ import mage.server.game.ReplayManager;
|
|||
import mage.server.game.TableManager;
|
||||
import mage.server.util.ThreadExecutor;
|
||||
import mage.util.Logging;
|
||||
import mage.view.CardView;
|
||||
import mage.view.ChatMessage.MessageColor;
|
||||
import mage.view.GameView;
|
||||
import mage.view.TableView;
|
||||
|
@ -117,9 +115,9 @@ public class ServerImpl extends RemoteServer implements Server {
|
|||
}
|
||||
|
||||
@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 {
|
||||
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");
|
||||
return table;
|
||||
}
|
||||
|
@ -161,6 +159,21 @@ public class ServerImpl extends RemoteServer implements Server {
|
|||
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
|
||||
public List<TableView> getTables(UUID roomId) throws MageException {
|
||||
try {
|
||||
|
@ -202,13 +215,13 @@ public class ServerImpl extends RemoteServer implements Server {
|
|||
}
|
||||
|
||||
@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 {
|
||||
rmiExecutor.execute(
|
||||
new Runnable() {
|
||||
@Override
|
||||
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.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.interfaces.callback.CallbackServerSession;
|
||||
import mage.interfaces.callback.ClientCallback;
|
||||
import mage.server.game.GameManager;
|
||||
import mage.server.game.TableManager;
|
||||
import mage.util.Logging;
|
||||
import mage.view.TableClientMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -90,7 +92,11 @@ public class Session {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -82,15 +82,17 @@ public class GameController implements GameCallback {
|
|||
private Game game;
|
||||
private UUID chatId;
|
||||
private UUID tableId;
|
||||
private UUID choosingPlayerId;
|
||||
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();
|
||||
this.sessionPlayerMap = sessionPlayerMap;
|
||||
chatId = ChatManager.getInstance().createChatSession();
|
||||
this.game = game;
|
||||
this.tableId = tableId;
|
||||
this.choosingPlayerId = choosingPlayerId;
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -186,7 +188,7 @@ public class GameController implements GameCallback {
|
|||
return;
|
||||
}
|
||||
}
|
||||
GameWorker worker = new GameWorker(game, this);
|
||||
GameWorker worker = new GameWorker(game, choosingPlayerId, this);
|
||||
gameFuture = gameExecutor.submit(worker);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,17 +30,15 @@ package mage.server.game;
|
|||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.game.Game;
|
||||
import mage.game.match.Match;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.util.Logging;
|
||||
import mage.game.GameType;
|
||||
import mage.game.match.MatchType;
|
||||
import mage.view.GameTypeView;
|
||||
|
||||
/**
|
||||
|
@ -52,8 +50,8 @@ public class GameFactory {
|
|||
private final static GameFactory INSTANCE = new GameFactory();
|
||||
private final static Logger logger = Logging.getLogger(GameFactory.class.getName());
|
||||
|
||||
private Map<String, Class<Game>> games = new HashMap<String, Class<Game>>();
|
||||
private Map<String, GameType> gameTypes = new HashMap<String, GameType>();
|
||||
private Map<String, Class<Match>> games = new HashMap<String, Class<Match>>();
|
||||
private Map<String, MatchType> gameTypes = new HashMap<String, MatchType>();
|
||||
private List<GameTypeView> gameTypeViews = new ArrayList<GameTypeView>();
|
||||
|
||||
|
||||
|
@ -63,31 +61,31 @@ public class GameFactory {
|
|||
|
||||
private GameFactory() {}
|
||||
|
||||
public Game createGame(String gameType, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
||||
public Match createMatch(String gameType, MatchOptions options) {
|
||||
|
||||
Game game;
|
||||
Constructor<Game> con;
|
||||
Match match;
|
||||
Constructor<Match> con;
|
||||
try {
|
||||
con = games.get(gameType).getConstructor(new Class[]{MultiplayerAttackOption.class, RangeOfInfluence.class});
|
||||
game = con.newInstance(new Object[] {attackOption, range});
|
||||
con = games.get(gameType).getConstructor(new Class[]{MatchOptions.class});
|
||||
match = con.newInstance(new Object[] {options});
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
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() {
|
||||
return gameTypeViews;
|
||||
}
|
||||
|
||||
public void addGameType(String name, GameType gameType, Class game) {
|
||||
public void addGameType(String name, MatchType matchType, Class game) {
|
||||
if (game != null) {
|
||||
this.games.put(name, game);
|
||||
this.gameTypes.put(name, gameType);
|
||||
this.gameTypeViews.add(new GameTypeView(gameType));
|
||||
this.gameTypes.put(name, matchType);
|
||||
this.gameTypeViews.add(new GameTypeView(matchType));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ public class GameManager {
|
|||
|
||||
private ConcurrentHashMap<UUID, GameController> gameControllers = new ConcurrentHashMap<UUID, GameController>();
|
||||
|
||||
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
|
||||
GameController gameController = new GameController(game, sessionPlayerMap, tableId);
|
||||
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId, UUID choosingPlayerId) {
|
||||
GameController gameController = new GameController(game, sessionPlayerMap, tableId, choosingPlayerId);
|
||||
gameControllers.put(game.getId(), gameController);
|
||||
return gameController.getSessionId();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.server.game;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -44,16 +45,18 @@ public class GameWorker implements Callable {
|
|||
|
||||
private GameCallback result;
|
||||
private Game game;
|
||||
private UUID choosingPlayerId;
|
||||
|
||||
public GameWorker(Game game, GameCallback result) {
|
||||
public GameWorker(Game game, UUID choosingPlayerId, GameCallback result) {
|
||||
this.game = game;
|
||||
this.choosingPlayerId = choosingPlayerId;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call() {
|
||||
try {
|
||||
game.start();
|
||||
game.start(choosingPlayerId);
|
||||
result.gameResult(game.getWinner());
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
|
|
|
@ -30,10 +30,9 @@ package mage.server.game;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.view.TableView;
|
||||
|
||||
/**
|
||||
|
@ -44,7 +43,7 @@ public interface GamesRoom extends Room {
|
|||
|
||||
public List<TableView> getTables();
|
||||
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 TableView getTable(UUID tableId);
|
||||
public void leaveTable(UUID sessionId, UUID tableId);
|
||||
|
|
|
@ -35,10 +35,9 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.util.Logging;
|
||||
import mage.view.TableView;
|
||||
|
||||
|
@ -71,8 +70,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TableView createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
||||
Table table = TableManager.getInstance().createTable(sessionId, gameType, deckType, playerTypes, attackOption, range);
|
||||
public TableView createTable(UUID sessionId, MatchOptions options) {
|
||||
Table table = TableManager.getInstance().createTable(sessionId, options);
|
||||
tables.put(table.getId(), table);
|
||||
return new TableView(table);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ import java.io.ObjectInput;
|
|||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -47,15 +46,18 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.Constants.TableState;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
import mage.game.GameStates;
|
||||
import mage.game.match.Match;
|
||||
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.server.ChatManager;
|
||||
import mage.server.Main;
|
||||
|
@ -73,17 +75,36 @@ public class TableController {
|
|||
|
||||
private UUID sessionId;
|
||||
private UUID chatId;
|
||||
private UUID gameId;
|
||||
private Table table;
|
||||
private Game game;
|
||||
private Match match;
|
||||
private MatchOptions options;
|
||||
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;
|
||||
chatId = ChatManager.getInstance().createChatSession();
|
||||
game = GameFactory.getInstance().createGame(gameType, attackOption, range);
|
||||
gameId = game.getId();
|
||||
table = new Table(gameType, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes);
|
||||
this.options = options;
|
||||
match = GameFactory.getInstance().createMatch(options.getGameType(), options);
|
||||
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 {
|
||||
|
@ -100,8 +121,7 @@ public class TableController {
|
|||
}
|
||||
|
||||
Player player = createPlayer(name, deck, seat.getPlayerType());
|
||||
game.loadCards(deck.getCards(), player.getId());
|
||||
game.loadCards(deck.getSideboard(), player.getId());
|
||||
match.addPlayer(player, deck);
|
||||
table.joinTable(player, seat);
|
||||
logger.info("player joined " + player.getId());
|
||||
//only add human players to sessionPlayerMap
|
||||
|
@ -112,11 +132,29 @@ public class TableController {
|
|||
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) {
|
||||
if (table.getState() != TableState.DUELING) {
|
||||
return false;
|
||||
}
|
||||
SessionManager.getInstance().getSession(sessionId).watchGame(game.getId());
|
||||
SessionManager.getInstance().getSession(sessionId).watchGame(match.getGame().getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -141,7 +179,7 @@ public class TableController {
|
|||
}
|
||||
|
||||
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());
|
||||
return player;
|
||||
}
|
||||
|
@ -151,26 +189,66 @@ public class TableController {
|
|||
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) {
|
||||
try {
|
||||
table.initGame(game);
|
||||
match.startMatch();
|
||||
startGame(null);
|
||||
} catch (GameException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
GameManager.getInstance().createGameSession(game, sessionPlayerMap, table.getId());
|
||||
SessionManager sessionManager = SessionManager.getInstance();
|
||||
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
|
||||
sessionManager.getSession(entry.getKey()).gameStarted(game.getId(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void startGame(UUID choosingPlayerId) throws GameException {
|
||||
match.startGame();
|
||||
table.initGame();
|
||||
GameManager.getInstance().createGameSession(match.getGame(), sessionPlayerMap, table.getId(), choosingPlayerId);
|
||||
SessionManager sessionManager = SessionManager.getInstance();
|
||||
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
|
||||
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() {
|
||||
UUID choosingPlayerId = match.getChooser();
|
||||
match.endGame();
|
||||
table.endGame();
|
||||
saveGame();
|
||||
GameManager.getInstance().removeGame(game.getId());
|
||||
game = null;
|
||||
GameManager.getInstance().removeGame(match.getGame().getId());
|
||||
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) {
|
||||
|
@ -188,17 +266,17 @@ public class TableController {
|
|||
|
||||
private void saveGame() {
|
||||
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);
|
||||
ObjectOutput output = new ObjectOutputStream(new GZIPOutputStream(buffer));
|
||||
try {
|
||||
output.writeObject(game);
|
||||
output.writeObject(game.getGameStates());
|
||||
output.writeObject(match.getGame());
|
||||
output.writeObject(match.getGame().getGameStates());
|
||||
}
|
||||
finally {
|
||||
output.close();
|
||||
}
|
||||
logger.log(Level.INFO, "Saved game:" + game.getId());
|
||||
logger.log(Level.INFO, "Saved game:" + match.getGame().getId());
|
||||
}
|
||||
catch(IOException ex) {
|
||||
logger.log(Level.SEVERE, "Cannot save game.", ex);
|
||||
|
@ -207,7 +285,7 @@ public class TableController {
|
|||
|
||||
private Game loadGame() {
|
||||
try{
|
||||
InputStream file = new FileInputStream("saved/" + gameId.toString() + ".game");
|
||||
InputStream file = new FileInputStream("saved/" + match.getGame().toString() + ".game");
|
||||
InputStream buffer = new BufferedInputStream(file);
|
||||
ObjectInput input = new CopierObjectInputStream(Main.classLoader, new GZIPInputStream(buffer));
|
||||
try {
|
||||
|
@ -224,7 +302,7 @@ public class TableController {
|
|||
logger.log(Level.SEVERE, "Cannot load game. Class not found.", 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;
|
||||
}
|
||||
|
|
|
@ -30,14 +30,12 @@ package mage.server.game;
|
|||
|
||||
import mage.game.Table;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.util.Logging;
|
||||
|
||||
/**
|
||||
|
@ -56,8 +54,8 @@ public class TableManager {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Table createTable(UUID sessionId, String gameType, String deckType, List<String> playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) {
|
||||
TableController tableController = new TableController(sessionId, gameType, deckType, playerTypes, attackOption, range);
|
||||
public Table createTable(UUID sessionId, MatchOptions options) {
|
||||
TableController tableController = new TableController(sessionId, options);
|
||||
controllers.put(tableController.getTable().getId(), tableController);
|
||||
tables.put(tableController.getTable().getId(), tableController.getTable());
|
||||
return tableController.getTable();
|
||||
|
@ -75,6 +73,10 @@ public class TableManager {
|
|||
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) {
|
||||
// TODO: search through tables and remove session
|
||||
}
|
||||
|
@ -100,8 +102,8 @@ public class TableManager {
|
|||
return controllers.get(tableId).getChatId();
|
||||
}
|
||||
|
||||
public void startGame(UUID sessionId, UUID roomId, UUID tableId) {
|
||||
controllers.get(tableId).startGame(sessionId);
|
||||
public void startMatch(UUID sessionId, UUID roomId, UUID tableId) {
|
||||
controllers.get(tableId).startMatch(sessionId);
|
||||
}
|
||||
|
||||
public boolean watchTable(UUID sessionId, UUID tableId) {
|
||||
|
|
|
@ -31,11 +31,7 @@ package mage.sets;
|
|||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import mage.cards.Card;
|
||||
|
@ -51,6 +47,7 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
|||
|
||||
private static final Sets fINSTANCE = new Sets();
|
||||
private static Set<String> names;
|
||||
protected static Random rnd = new Random();
|
||||
|
||||
public static Sets getInstance() {
|
||||
return fINSTANCE;
|
||||
|
@ -93,6 +90,24 @@ public class Sets extends HashMap<String, ExpansionSet> {
|
|||
}
|
||||
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) {
|
||||
for (ExpansionSet set: fINSTANCE.values()) {
|
||||
|
|
|
@ -42,11 +42,10 @@ import mage.abilities.common.EntersBattlefieldAbility;
|
|||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.PreventionEffectImpl;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.counters.common.PlusOneCounter;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
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.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.counters.CounterType;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -51,9 +52,9 @@ public class LuxCannon extends CardImpl<LuxCannon> {
|
|||
public LuxCannon (UUID ownerId) {
|
||||
super(ownerId, 173, "Lux Cannon", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||
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.addCost(new RemoveCountersSourceCost("charge", 3));
|
||||
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.getName(), 3));
|
||||
ability.addTarget(new TargetPermanent());
|
||||
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.mana.ManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
|
@ -55,7 +56,7 @@ public class EverflowingChalice extends CardImpl<EverflowingChalice> {
|
|||
public EverflowingChalice(UUID ownerId) {
|
||||
super(ownerId, 123, "Everflowing Chalice", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{0}");
|
||||
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);
|
||||
ability.addManaCost(new GenericManaCost(2));
|
||||
this.addAbility(ability);
|
||||
|
@ -120,7 +121,7 @@ class EverflowingChaliceEffect extends ManaEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ import mage.abilities.costs.common.TapSourceCost;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.mana.GreenManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.counters.common.PlusOneCounter;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
|
@ -21,6 +21,9 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.game.match.MatchOptions;
|
||||
|
||||
/**
|
||||
* Base for starting Mage server.
|
||||
|
@ -64,14 +67,18 @@ public class MageBase {
|
|||
connect("player", "localhost", 17171);
|
||||
UUID roomId = server.getMainRoomId();
|
||||
|
||||
List<String> playerTypes = new ArrayList<String>();
|
||||
playerTypes.add("Human");
|
||||
playerTypes.add("Computer - default");
|
||||
TableView table = server.createTable(sessionId, roomId, "Two Player Duel", "Limited", playerTypes, null, null);
|
||||
MatchOptions options = new MatchOptions("1", "Two Player Duel");
|
||||
options.getPlayerTypes().add("Human");
|
||||
options.getPlayerTypes().add("Computer - default");
|
||||
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());
|
||||
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.startGame(sessionId, roomId, table.getTableId());
|
||||
server.startMatch(sessionId, roomId, table.getTableId());
|
||||
|
||||
synchronized (syncStart) {
|
||||
int waitTime = 7000;
|
||||
|
|
|
@ -39,7 +39,7 @@ import mage.filter.FilterAbility;
|
|||
|
||||
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, FilterAbility filter);
|
||||
public Abilities<ManaAbility> getManaAbilities(Zone zone);
|
||||
|
|
|
@ -58,7 +58,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRules() {
|
||||
public List<String> getRules(String source) {
|
||||
List<String> rules = new ArrayList<String>();
|
||||
|
||||
for (T ability:this) {
|
||||
|
|
|
@ -73,6 +73,7 @@ public interface Ability extends Serializable {
|
|||
public Zone getZone();
|
||||
public boolean isUsesStack();
|
||||
public String getRule();
|
||||
public String getRule(String source);
|
||||
public boolean activate(Game game, boolean noMana);
|
||||
public boolean resolve(Game game);
|
||||
public void reset(Game game);
|
||||
|
|
|
@ -302,6 +302,17 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
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
|
||||
public void addCost(Cost cost) {
|
||||
if (cost != null) {
|
||||
|
|
|
@ -81,10 +81,13 @@ public abstract class TriggeredAbilityImpl<T extends TriggeredAbilityImpl<T>> ex
|
|||
Player player = game.getPlayer(this.getControllerId());
|
||||
MageObject object = game.getObject(sourceId);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Use ").append(this.getRule()).append("ability");
|
||||
if (object != null) {
|
||||
sb.append("Use ").append(this.getRule(object.getName())).append("ability");
|
||||
sb.append(" from ").append(object.getName());
|
||||
}
|
||||
else {
|
||||
sb.append("Use ").append(this.getRule()).append("ability");
|
||||
}
|
||||
sb.append("?");
|
||||
if (!player.chooseUse(this.effects.get(0).getOutcome(), sb.toString(), game)) {
|
||||
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.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.counters.common.PlusOneCounter;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ package mage.abilities.effects.common;
|
|||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.counters.common.PlusOneCounter;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
|
|
|
@ -31,7 +31,7 @@ package mage.abilities.effects.common;
|
|||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.counters.PlusOneCounter;
|
||||
import mage.counters.common.PlusOneCounter;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
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.Layer;
|
||||
import mage.Constants.Outcome;
|
||||
|
@ -38,25 +39,32 @@ import mage.filter.FilterPermanent;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class BoostSourceWhileControlsEffect extends WhileControlsContinuousEffect<BoostSourceWhileControlsEffect> {
|
||||
public class BoostSourceWhileControlsEffect extends WhileConditionContiniousEffect<BoostSourceWhileControlsEffect> {
|
||||
|
||||
private int power;
|
||||
private int toughness;
|
||||
private List<String> filterDescription;
|
||||
|
||||
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.toughness = toughness;
|
||||
this.filterDescription = filter.getName();
|
||||
}
|
||||
|
||||
public BoostSourceWhileControlsEffect(final BoostSourceWhileControlsEffect effect) {
|
||||
super(effect);
|
||||
this.power = effect.power;
|
||||
this.toughness = effect.toughness;
|
||||
this.filterDescription = new ArrayList<String>();
|
||||
this.filterDescription.addAll(effect.filterDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,6 +84,6 @@ public class BoostSourceWhileControlsEffect extends WhileControlsContinuousEffec
|
|||
|
||||
@Override
|
||||
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,15 +30,17 @@ public class SacrificeSourceUnlessPaysEffect extends OneShotEffect<SacrificeSour
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null && player.chooseUse(Outcome.Benefit, cost.getText() + " or sacrifice {this}?", game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||
return true;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null)
|
||||
if (player != null && permanent != null) {
|
||||
if (player.chooseUse(Outcome.Benefit, cost.getText() + " or sacrifice " + permanent.getName() + "?", game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||
return true;
|
||||
}
|
||||
permanent.sacrifice(source.getSourceId(), game);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,6 +50,6 @@ public class SacrificeSourceUnlessPaysEffect extends OneShotEffect<SacrificeSour
|
|||
|
||||
@Override
|
||||
public String getText(Ability source) {
|
||||
return "sacrifice it unless you pay " + cost.getText();
|
||||
return "sacrifice {this} unless you pay " + cost.getText();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,15 +57,17 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect<TapSourceUnlessPays
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null && player.chooseUse(Outcome.Benefit, cost.getText() + " or {this} comes into play tapped?", game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||
return true;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null)
|
||||
if (player != null && permanent != null) {
|
||||
if (player.chooseUse(Outcome.Benefit, cost.getText() + " or " + permanent.getName() + " comes into play tapped?", game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(game, source.getId(), source.getControllerId(), false))
|
||||
return true;
|
||||
}
|
||||
permanent.setTapped(true);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
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
|
||||
sb.append("-").append(level2);
|
||||
sb.append(": ").append(power).append("/").append(toughness).append(" ");
|
||||
for (String rule: abilities.getRules()) {
|
||||
for (String rule: abilities.getRules("{this}")) {
|
||||
sb.append(rule).append(" ");
|
||||
}
|
||||
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
|
||||
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)) {
|
||||
rules.add(0, getSpellAbility().getRule());
|
||||
rules.add(0, getSpellAbility().getRule(this.name));
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
|
|
@ -143,6 +143,19 @@ public abstract class ExpansionSet implements Serializable {
|
|||
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) {
|
||||
for (Card card: createCards()) {
|
||||
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