Merge branch 'master' into copy_constructor_watchers

This commit is contained in:
Oleg Agafonov 2019-05-18 09:13:42 +04:00
commit 85c6528d2d
724 changed files with 23423 additions and 5250 deletions

1
.gitignore vendored
View file

@ -49,6 +49,7 @@ Mage.Server.Plugins/Mage.Game.FreeForAll/target
Mage.Server.Plugins/Mage.Game.MomirDuel/target Mage.Server.Plugins/Mage.Game.MomirDuel/target
Mage.Server.Plugins/Mage.Game.MomirGame/target/ Mage.Server.Plugins/Mage.Game.MomirGame/target/
Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target
Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/target/
Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/target/ Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/target/
Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/target Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/target
Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/target Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/target

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-client</artifactId> <artifactId>mage-client</artifactId>

View file

@ -16,6 +16,14 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="menuDebugTestModalDialogActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="menuDebugTestModalDialogActionPerformed"/>
</Events> </Events>
</MenuItem> </MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="menuDebugTestCardRenderModesDialog">
<Properties>
<Property name="text" type="java.lang.String" value="Test Card Render Modes"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="menuDebugTestCardRenderModesDialogActionPerformed"/>
</Events>
</MenuItem>
</SubComponents> </SubComponents>
</Container> </Container>
</NonVisualComponents> </NonVisualComponents>

View file

@ -20,6 +20,7 @@ import mage.client.draft.DraftPane;
import mage.client.draft.DraftPanel; import mage.client.draft.DraftPanel;
import mage.client.game.GamePane; import mage.client.game.GamePane;
import mage.client.game.GamePanel; import mage.client.game.GamePanel;
import mage.client.game.PlayAreaPanel;
import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.preference.MagePreferences; import mage.client.preference.MagePreferences;
@ -72,7 +73,7 @@ import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com, JayDi85
*/ */
public class MageFrame extends javax.swing.JFrame implements MageClient { public class MageFrame extends javax.swing.JFrame implements MageClient {
@ -246,8 +247,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
SessionHandler.startSession(this); SessionHandler.startSession(this);
callbackClient = new CallbackClientImpl(this); callbackClient = new CallbackClientImpl(this);
connectDialog = new ConnectDialog(); connectDialog = new ConnectDialog();
try try {
{
whatsNewDialog = new WhatsNewDialog(); whatsNewDialog = new WhatsNewDialog();
} catch (NoClassDefFoundError e) { } catch (NoClassDefFoundError e) {
// JavaFX is not supported on old MacOS with OpenJDK // JavaFX is not supported on old MacOS with OpenJDK
@ -320,10 +320,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
setConnectButtonText(NOT_CONNECTED_TEXT); setConnectButtonText(NOT_CONNECTED_TEXT);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
disableButtons(); disableButtons();
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_CHECK, "false").equals("true")) {
checkForNewImages();
}
updateMemUsageTask.execute(); updateMemUsageTask.execute();
LOGGER.info("Client start up time: " + ((System.currentTimeMillis() - startTime) / 1000 + " seconds")); LOGGER.info("Client start up time: " + ((System.currentTimeMillis() - startTime) / 1000 + " seconds"));
if (autoConnect()) { if (autoConnect()) {
@ -332,7 +328,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
connectDialog.showDialog(); connectDialog.showDialog();
} }
setWindowTitle(); setWindowTitle();
}); });
if (SystemUtil.isMacOSX()) { if (SystemUtil.isMacOSX()) {
@ -354,61 +349,76 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
+ ((SessionHandler.getSession() != null && SessionHandler.isConnected()) ? SessionHandler.getVersionInfo() : NOT_CONNECTED_TEXT)); + ((SessionHandler.getSession() != null && SessionHandler.isConnected()) ? SessionHandler.getVersionInfo() : NOT_CONNECTED_TEXT));
} }
private void updateTooltipContainerSizes() {
JPanel cardPreviewContainer;
BigCard bigCard;
JPanel cardPreviewContainerRotated;
BigCard bigCardRotated;
try {
cardPreviewContainer = (JPanel) UI.getComponent(MageComponents.CARD_PREVIEW_CONTAINER);
bigCard = (BigCard) UI.getComponent(MageComponents.CARD_PREVIEW_PANE);
cardPreviewContainerRotated = (JPanel) UI.getComponent(MageComponents.CARD_PREVIEW_CONTAINER_ROTATED);
bigCardRotated = (BigCard) UI.getComponent(MageComponents.CARD_PREVIEW_PANE_ROTATED);
} catch (InterruptedException e) {
LOGGER.fatal("Can't update tooltip panel sizes");
Thread.currentThread().interrupt();
return;
}
int height = GUISizeHelper.enlargedImageHeight;
int width = (int) ((float) height * (float) 0.64);
bigCard.setSize(width, height);
cardPreviewContainer.setBounds(0, 0, width + 80, height + 30);
bigCardRotated.setSize(height, width + 30);
cardPreviewContainerRotated.setBounds(0, 0, height + 80, width + 100 + 30);
}
private void addTooltipContainer() { private void addTooltipContainer() {
final JEditorPane cardInfoPane = (JEditorPane) Plugins.instance.getCardInfoPane(); JEditorPane cardInfoPane = (JEditorPane) Plugins.instance.getCardInfoPane();
if (cardInfoPane == null) { if (cardInfoPane == null) {
LOGGER.fatal("Can't find card tooltip plugin");
return; return;
} }
cardInfoPane.setLocation(40, 40); cardInfoPane.setLocation(40, 40);
cardInfoPane.setBackground(new Color(0, 0, 0, 0)); cardInfoPane.setBackground(new Color(0, 0, 0, 0));
UI.addComponent(MageComponents.CARD_INFO_PANE, cardInfoPane);
MageRoundPane popupContainer = new MageRoundPane(); MageRoundPane popupContainer = new MageRoundPane();
popupContainer.setLayout(null); popupContainer.setLayout(null);
popupContainer.add(cardInfoPane); popupContainer.add(cardInfoPane);
popupContainer.setVisible(false); popupContainer.setVisible(false);
desktopPane.add(popupContainer, JLayeredPane.POPUP_LAYER); desktopPane.add(popupContainer, JLayeredPane.POPUP_LAYER);
UI.addComponent(MageComponents.CARD_INFO_PANE, cardInfoPane);
UI.addComponent(MageComponents.POPUP_CONTAINER, popupContainer); UI.addComponent(MageComponents.POPUP_CONTAINER, popupContainer);
// preview panel normal
JPanel cardPreviewContainer = new JPanel(); JPanel cardPreviewContainer = new JPanel();
cardPreviewContainer.setOpaque(false); cardPreviewContainer.setOpaque(false);
cardPreviewContainer.setLayout(null); cardPreviewContainer.setLayout(null);
BigCard bigCard = new BigCard();
int height = GUISizeHelper.enlargedImageHeight;
int width = (int) ((float) height * (float) 0.64);
bigCard.setSize(width, height);
bigCard.setLocation(40, 40);
bigCard.setBackground(new Color(0, 0, 0, 0));
cardPreviewContainer.add(bigCard);
cardPreviewContainer.setVisible(false); cardPreviewContainer.setVisible(false);
cardPreviewContainer.setBounds(0, 0, width + 80, height + 30); desktopPane.add(cardPreviewContainer, JLayeredPane.POPUP_LAYER);
UI.addComponent(MageComponents.CARD_PREVIEW_PANE, bigCard);
UI.addComponent(MageComponents.CARD_PREVIEW_CONTAINER, cardPreviewContainer); UI.addComponent(MageComponents.CARD_PREVIEW_CONTAINER, cardPreviewContainer);
desktopPane.add(cardPreviewContainer, JLayeredPane.POPUP_LAYER); BigCard bigCard = new BigCard();
bigCard.setLocation(40, 40);
bigCard.setBackground(new Color(0, 0, 0, 0));
cardPreviewContainer.add(bigCard);
UI.addComponent(MageComponents.CARD_PREVIEW_PANE, bigCard);
// preview panel rotated
JPanel cardPreviewContainerRotated = new JPanel(); JPanel cardPreviewContainerRotated = new JPanel();
cardPreviewContainerRotated.setOpaque(false); cardPreviewContainerRotated.setOpaque(false);
cardPreviewContainerRotated.setLayout(null); cardPreviewContainerRotated.setLayout(null);
bigCard = new BigCard(true);
bigCard.setSize(height, width + 30);
bigCard.setLocation(40, 40);
bigCard.setBackground(new Color(0, 0, 0, 0));
cardPreviewContainerRotated.add(bigCard);
cardPreviewContainerRotated.setVisible(false); cardPreviewContainerRotated.setVisible(false);
cardPreviewContainerRotated.setBounds(0, 0, height + 80, width + 100 + 30); desktopPane.add(cardPreviewContainerRotated, JLayeredPane.POPUP_LAYER);
UI.addComponent(MageComponents.CARD_PREVIEW_PANE_ROTATED, bigCard);
UI.addComponent(MageComponents.CARD_PREVIEW_CONTAINER_ROTATED, cardPreviewContainerRotated); UI.addComponent(MageComponents.CARD_PREVIEW_CONTAINER_ROTATED, cardPreviewContainerRotated);
desktopPane.add(cardPreviewContainerRotated, JLayeredPane.POPUP_LAYER);
BigCard bigCardRotated = new BigCard(true);
bigCardRotated.setLocation(40, 40);
bigCardRotated.setBackground(new Color(0, 0, 0, 0));
cardPreviewContainerRotated.add(bigCardRotated);
UI.addComponent(MageComponents.CARD_PREVIEW_PANE_ROTATED, bigCardRotated);
updateTooltipContainerSizes();
} }
private void setGUISizeTooltipContainer() { private void setGUISizeTooltipContainer() {
@ -563,10 +573,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
menu.show(component, 0, component.getHeight()); menu.show(component, 0, component.getHeight());
} }
private void checkForNewImages() {
// Removed TODO: Remove related pref code
}
public static void setActive(MagePane frame) { public static void setActive(MagePane frame) {
// Always hide not hidden popup window or enlarged card view if a frame is set to active // Always hide not hidden popup window or enlarged card view if a frame is set to active
try { try {
@ -580,8 +586,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
container.repaint(); container.repaint();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.fatal("MageFrame error", e);
Thread.currentThread().interrupt();
} }
// Nothing to do // Nothing to do
if (activeFrame == frame) { if (activeFrame == frame) {
return; return;
@ -758,10 +766,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private boolean performConnect(boolean reconnect) { private boolean performConnect(boolean reconnect) {
if (currentConnection == null || !reconnect) { if (currentConnection == null || !reconnect) {
String server = MagePreferences.getServerAddress(); String server = MagePreferences.getLastServerAddress();
int port = MagePreferences.getServerPort(); int port = MagePreferences.getLastServerPort();
String userName = MagePreferences.getUserName(server); String userName = MagePreferences.getLastServerUser();
String password = MagePreferences.getPassword(server); String password = MagePreferences.getLastServerPassword();
String proxyServer = PREFS.get("proxyAddress", ""); String proxyServer = PREFS.get("proxyAddress", "");
int proxyPort = Integer.parseInt(PREFS.get("proxyPort", "0")); int proxyPort = Integer.parseInt(PREFS.get("proxyPort", "0"));
ProxyType proxyType = ProxyType.valueByText(PREFS.get("proxyType", "None")); ProxyType proxyType = ProxyType.valueByText(PREFS.get("proxyType", "None"));
@ -820,6 +828,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
popupDebug = new javax.swing.JPopupMenu(); popupDebug = new javax.swing.JPopupMenu();
menuDebugTestModalDialog = new javax.swing.JMenuItem(); menuDebugTestModalDialog = new javax.swing.JMenuItem();
menuDebugTestCardRenderModesDialog = new javax.swing.JMenuItem();
desktopPane = new MageJDesktop(); desktopPane = new MageJDesktop();
mageToolbar = new javax.swing.JToolBar(); mageToolbar = new javax.swing.JToolBar();
btnPreferences = new javax.swing.JButton(); btnPreferences = new javax.swing.JButton();
@ -850,6 +859,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}); });
popupDebug.add(menuDebugTestModalDialog); popupDebug.add(menuDebugTestModalDialog);
menuDebugTestCardRenderModesDialog.setText("Test Card Render Modes");
menuDebugTestCardRenderModesDialog.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
menuDebugTestCardRenderModesDialogActionPerformed(evt);
}
});
popupDebug.add(menuDebugTestCardRenderModesDialog);
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(1024, 768)); setMinimumSize(new java.awt.Dimension(1024, 768));
@ -1072,6 +1089,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
popupDebug.show(evt.getComponent(), 0, evt.getComponent().getHeight()); popupDebug.show(evt.getComponent(), 0, evt.getComponent().getHeight());
}//GEN-LAST:event_btnDebugMouseClicked }//GEN-LAST:event_btnDebugMouseClicked
private void menuDebugTestCardRenderModesDialogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuDebugTestCardRenderModesDialogActionPerformed
final TestCardRenderDialog dialog = new TestCardRenderDialog();
dialog.showDialog();
}//GEN-LAST:event_menuDebugTestCardRenderModesDialogActionPerformed
public void downloadImages() { public void downloadImages() {
DownloadPicturesService.startDownload(); DownloadPicturesService.startDownload();
} }
@ -1321,6 +1343,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private javax.swing.JToolBar.Separator jSeparatorImages; private javax.swing.JToolBar.Separator jSeparatorImages;
private javax.swing.JToolBar.Separator jSeparatorSymbols; private javax.swing.JToolBar.Separator jSeparatorSymbols;
private javax.swing.JToolBar mageToolbar; private javax.swing.JToolBar mageToolbar;
private javax.swing.JMenuItem menuDebugTestCardRenderModesDialog;
private javax.swing.JMenuItem menuDebugTestModalDialog; private javax.swing.JMenuItem menuDebugTestModalDialog;
private javax.swing.JPopupMenu popupDebug; private javax.swing.JPopupMenu popupDebug;
private javax.swing.JToolBar.Separator separatorDebug; private javax.swing.JToolBar.Separator separatorDebug;
@ -1365,6 +1388,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
return GAMES.get(gameId); return GAMES.get(gameId);
} }
public static Map<UUID, PlayAreaPanel> getGamePlayers(UUID gameId) {
GamePanel p = GAMES.get(gameId);
return p != null ? p.getPlayers() : new HashMap<>();
}
public static void removeGame(UUID gameId) { public static void removeGame(UUID gameId) {
GAMES.remove(gameId); GAMES.remove(gameId);
} }
@ -1403,23 +1431,25 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
} }
@Override @Override
public void disconnected(final boolean errorCall) { public void disconnected(final boolean askToReconnect) {
if (SwingUtilities.isEventDispatchThread()) { // Returns true if the current thread is an AWT event dispatching thread. if (SwingUtilities.isEventDispatchThread()) { // Returns true if the current thread is an AWT event dispatching thread.
LOGGER.info("DISCONNECTED (Event Dispatch Thread)"); // REMOTE task, e.g. connecting
LOGGER.info("Disconnected from remote task");
setConnectButtonText(NOT_CONNECTED_TEXT); setConnectButtonText(NOT_CONNECTED_TEXT);
disableButtons(); disableButtons();
hideGames(); hideGames();
hideTables(); hideTables();
} else { } else {
LOGGER.info("DISCONNECTED (NO Event Dispatch Thread)"); // USER mode, e.g. user plays and got disconnect
LOGGER.info("Disconnected from user mode");
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
SessionHandler.disconnect(false); // user already disconnected, can't do any online actions like quite chat
setConnectButtonText(NOT_CONNECTED_TEXT); setConnectButtonText(NOT_CONNECTED_TEXT);
disableButtons(); disableButtons();
hideGames(); hideGames();
hideTables(); hideTables();
SessionHandler.disconnect(false); if (askToReconnect) {
if (errorCall) { UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect to " + MagePreferences.getLastServerAddress() + "?");
UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect?");
message.setButton1("No", null); message.setButton1("No", null);
message.setButton2("Yes", PlayerAction.CLIENT_RECONNECT); message.setButton2("Yes", PlayerAction.CLIENT_RECONNECT);
showUserRequestDialog(message); showUserRequestDialog(message);
@ -1583,7 +1613,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
} }
balloonTip.setFont(GUISizeHelper.balloonTooltipFont); balloonTip.setFont(GUISizeHelper.balloonTooltipFont);
addTooltipContainer(); updateTooltipContainerSizes();
} }
public void showWhatsNewDialog(boolean forceToShowPage) { public void showWhatsNewDialog(boolean forceToShowPage) {

View file

@ -1,10 +1,3 @@
/*
* Card.java
*
* Created on 17-Dec-2009, 9:20:50 PM
*/
package mage.client.cards; package mage.client.cards;
import mage.cards.CardDimensions; import mage.cards.CardDimensions;
@ -37,7 +30,6 @@ import java.util.UUID;
import static mage.client.constants.Constants.*; import static mage.client.constants.Constants.*;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
@ -132,7 +124,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
gSmall.drawImage(ImageHelper.scaleImage(image, Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight()), 0, 0, this); gSmall.drawImage(ImageHelper.scaleImage(image, Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight()), 0, 0, this);
gImage.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE)); gImage.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE));
gImage.drawString(card.getName()+"TEST", CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET); gImage.drawString(card.getName() + "TEST", CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET);
if (card.isCreature()) { if (card.isCreature()) {
gImage.drawString(card.getPower() + '/' + card.getToughness(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP); gImage.drawString(card.getPower() + '/' + card.getToughness(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP);
} else if (card.isPlanesWalker()) { } else if (card.isPlanesWalker()) {
@ -146,7 +138,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
gImage.dispose(); gImage.dispose();
gSmall.setFont(new Font("Arial", Font.PLAIN, Config.dimensions.getNameFontSize())); gSmall.setFont(new Font("Arial", Font.PLAIN, Config.dimensions.getNameFontSize()));
gSmall.drawString(card.getName()+"TEST2", Config.dimensions.getContentXOffset(), Config.dimensions.getNameYOffset()); gSmall.drawString(card.getName() + "TEST2", Config.dimensions.getContentXOffset(), Config.dimensions.getNameYOffset());
if (card.isCreature()) { if (card.isCreature()) {
gSmall.drawString(card.getPower() + "/-/" + card.getToughness(), Config.dimensions.getPowBoxTextLeft(), Config.dimensions.getPowBoxTextTop()); gSmall.drawString(card.getPower() + "/-/" + card.getToughness(), Config.dimensions.getPowBoxTextLeft(), Config.dimensions.getPowBoxTextTop());
} else if (card.isPlanesWalker()) { } else if (card.isPlanesWalker()) {
@ -309,7 +301,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
@Override @Override
public void paintComponent(Graphics graphics) { public void paintComponent(Graphics graphics) {
drawDetailed((Graphics2D)graphics); drawDetailed((Graphics2D) graphics);
/* /*
Graphics2D g2 = (Graphics2D) graphics; Graphics2D g2 = (Graphics2D) graphics;
g2.drawImage(small, 0, 0, this); g2.drawImage(small, 0, 0, this);
@ -367,13 +359,13 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
List<UUID> targets = card.getTargets(); List<UUID> targets = card.getTargets();
if (targets != null) { if (targets != null) {
for (UUID uuid : targets) { for (UUID uuid : targets) {
PlayAreaPanel playAreaPanel = MageFrame.getGame(gameId).getPlayers().get(uuid); PlayAreaPanel playAreaPanel = MageFrame.getGamePlayers(gameId).get(uuid);
if (playAreaPanel != null) { if (playAreaPanel != null) {
Point target = playAreaPanel.getLocationOnScreen(); Point target = playAreaPanel.getLocationOnScreen();
Point me = this.getLocationOnScreen(); Point me = this.getLocationOnScreen();
ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() - 40, Color.red, ArrowBuilder.Type.TARGET); ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() - 40, Color.red, ArrowBuilder.Type.TARGET);
} else { } else {
for (PlayAreaPanel pa : MageFrame.getGame(gameId).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid); MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) { if (permanent != null) {
Point target = permanent.getLocationOnScreen(); Point target = permanent.getLocationOnScreen();

View file

@ -1,6 +1,7 @@
package mage.client.cards; package mage.client.cards;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientEventType; import mage.client.util.ClientEventType;
import mage.client.util.Event; import mage.client.util.Event;
@ -30,6 +31,9 @@ public class CardArea extends JPanel implements MouseListener {
private Dimension cardDimension; private Dimension cardDimension;
private int verticalCardOffset; private int verticalCardOffset;
private int customRenderMode = -1; // custom render mode tests
private Dimension customCardSize = null; // custom size for tests
/** /**
* Create the panel. * Create the panel.
*/ */
@ -62,8 +66,12 @@ public class CardArea extends JPanel implements MouseListener {
} }
private void setGUISize() { private void setGUISize() {
if (customCardSize != null) {
setCardDimension(customCardSize, GUISizeHelper.otherZonesCardVerticalOffset);
} else {
setCardDimension(GUISizeHelper.otherZonesCardDimension, GUISizeHelper.otherZonesCardVerticalOffset); setCardDimension(GUISizeHelper.otherZonesCardDimension, GUISizeHelper.otherZonesCardVerticalOffset);
} }
}
public void setCardDimension(Dimension dimension, int verticalCardOffset) { public void setCardDimension(Dimension dimension, int verticalCardOffset) {
this.cardDimension = dimension; this.cardDimension = dimension;
@ -129,7 +137,8 @@ public class CardArea extends JPanel implements MouseListener {
tmp.setAbility(card); // cross-reference, required for ability picker tmp.setAbility(card); // cross-reference, required for ability picker
card = tmp; card = tmp;
} }
MageCard cardPanel = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true); MageCard cardPanel = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true,
customRenderMode != -1 ? customRenderMode : PreferencesDialog.getRenderMode());
cardPanel.setBounds(rectangle); cardPanel.setBounds(rectangle);
cardPanel.addMouseListener(this); cardPanel.addMouseListener(this);
@ -265,6 +274,14 @@ public class CardArea extends JPanel implements MouseListener {
} }
} }
public void setCustomRenderMode(int customRenderMode) {
this.customRenderMode = customRenderMode;
}
public void setCustomCardSize(Dimension customCardSize) {
this.customCardSize = customCardSize;
}
@Override @Override
public void mouseEntered(MouseEvent e) { public void mouseEntered(MouseEvent e) {
} }

View file

@ -2,6 +2,7 @@ package mage.client.cards;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.MagePane; import mage.client.MagePane;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.view.CardView; import mage.view.CardView;
@ -45,7 +46,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
currentRoot = SwingUtilities.getRootPane(c); currentRoot = SwingUtilities.getRootPane(c);
// Pane // Pane
glassPane = (JComponent)currentRoot.getGlassPane(); glassPane = (JComponent) currentRoot.getGlassPane();
glassPane.setLayout(null); glassPane.setLayout(null);
glassPane.setOpaque(false); glassPane.setOpaque(false);
glassPane.setVisible(true); glassPane.setVisible(true);
@ -58,7 +59,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
if (rootMagePane == null) { if (rootMagePane == null) {
throw new RuntimeException("CardDraggerGlassPane::beginDrag not in a MagePane?"); throw new RuntimeException("CardDraggerGlassPane::beginDrag not in a MagePane?");
} else { } else {
currentEventRootMagePane = (MagePane)rootMagePane; currentEventRootMagePane = (MagePane) rootMagePane;
} }
// Hook up events // Hook up events
@ -72,8 +73,8 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
currentCards = new ArrayList<>(source.dragCardList()); currentCards = new ArrayList<>(source.dragCardList());
// Make a view for the first one and add it to us // Make a view for the first one and add it to us
dragView = Plugins.instance.getMageCard(currentCards.get(0), null, new Dimension(100, 140), null, true, false); dragView = Plugins.instance.getMageCard(currentCards.get(0), null, new Dimension(100, 140), null, true, false, PreferencesDialog.getRenderMode());
for (MouseListener l: dragView.getMouseListeners()) { for (MouseListener l : dragView.getMouseListeners()) {
dragView.removeMouseListener(l); dragView.removeMouseListener(l);
} }
for (MouseMotionListener l : dragView.getMouseMotionListeners()) { for (MouseMotionListener l : dragView.getMouseMotionListeners()) {
@ -95,7 +96,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
Component mouseOver = SwingUtilities.getDeepestComponentAt(currentEventRootMagePane, e.getX(), e.getY()); Component mouseOver = SwingUtilities.getDeepestComponentAt(currentEventRootMagePane, e.getX(), e.getY());
while (mouseOver != null) { while (mouseOver != null) {
if (mouseOver instanceof DragCardTarget) { if (mouseOver instanceof DragCardTarget) {
DragCardTarget target = (DragCardTarget)mouseOver; DragCardTarget target = (DragCardTarget) mouseOver;
MouseEvent targetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, mouseOver); MouseEvent targetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, mouseOver);
if (target != currentDragTarget) { if (target != currentDragTarget) {
if (currentDragTarget != null) { if (currentDragTarget != null) {
@ -116,7 +117,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
mouseOver = mouseOver.getParent(); mouseOver = mouseOver.getParent();
} }
if (currentDragTarget != null) { if (currentDragTarget != null) {
MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, (Component)currentDragTarget); MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, (Component) currentDragTarget);
currentDragTarget.dragCardExit(oldTargetEvent); currentDragTarget.dragCardExit(oldTargetEvent);
} }
currentDragTarget = null; currentDragTarget = null;
@ -164,13 +165,22 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
} }
@Override @Override
public void mouseClicked(MouseEvent e) {} public void mouseClicked(MouseEvent e) {
}
@Override @Override
public void mousePressed(MouseEvent e) {} public void mousePressed(MouseEvent e) {
}
@Override @Override
public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) {
}
@Override @Override
public void mouseExited(MouseEvent e) {} public void mouseExited(MouseEvent e) {
}
@Override @Override
public void mouseMoved(MouseEvent e) {} public void mouseMoved(MouseEvent e) {
}
} }

View file

@ -5,32 +5,32 @@
* *
* Created on 30-Mar-2010, 9:25:40 PM * Created on 30-Mar-2010, 9:25:40 PM
*/ */
package mage.client.cards; package mage.client.cards;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.deckeditor.SortSetting; import mage.client.deckeditor.SortSetting;
import mage.client.plugins.impl.Plugins; import mage.client.dialog.PreferencesDialog;
import mage.client.util.ClientEventType; import mage.client.plugins.impl.Plugins;
import mage.client.util.Event; import mage.client.util.ClientEventType;
import mage.client.util.GUISizeHelper; import mage.client.util.Event;
import mage.client.util.Listener; import mage.client.util.GUISizeHelper;
import mage.utils.CardColorUtil; import mage.client.util.Listener;
import mage.view.CardView; import mage.utils.CardColorUtil;
import mage.view.CardsView; import mage.view.CardView;
import org.mage.card.arcane.CardPanel; import mage.view.CardsView;
import org.mage.card.arcane.CardPanel;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.util.*; import java.util.List;
import java.util.List; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, ICardGrid { public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, ICardGrid {
protected final CardEventSource cardEventSource = new CardEventSource(); protected final CardEventSource cardEventSource = new CardEventSource();
protected BigCard bigCard; protected BigCard bigCard;
@ -83,7 +83,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener,
addCard(card, bigCard, gameId, drawImage); addCard(card, bigCard, gameId, drawImage);
} }
} }
for (Iterator<Entry<UUID, MageCard>> i = cards.entrySet().iterator(); i.hasNext();) { for (Iterator<Entry<UUID, MageCard>> i = cards.entrySet().iterator(); i.hasNext(); ) {
Entry<UUID, MageCard> entry = i.next(); Entry<UUID, MageCard> entry = i.next();
if (!showCards.containsKey(entry.getKey())) { if (!showCards.containsKey(entry.getKey())) {
removeCardImg(entry.getKey()); removeCardImg(entry.getKey());
@ -101,7 +101,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener,
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) { private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, drawImage, true); MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, drawImage, true, PreferencesDialog.getRenderMode());
cards.put(card.getId(), cardImg); cards.put(card.getId(), cardImg);
cardImg.addMouseListener(this); cardImg.addMouseListener(this);
add(cardImg); add(cardImg);
@ -347,18 +347,18 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener,
public int cardsSize() { public int cardsSize() {
return cards.size(); return cards.size();
} }
} }
class CardNameComparator implements Comparator<MageCard> { class CardNameComparator implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
return o1.getOriginal().getName().compareTo(o2.getOriginal().getName()); return o1.getOriginal().getName().compareTo(o2.getOriginal().getName());
} }
} }
class CardRarityComparator implements Comparator<MageCard> { class CardRarityComparator implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
@ -370,9 +370,9 @@ class CardRarityComparator implements Comparator<MageCard> {
} }
} }
} }
class CardCostComparator implements Comparator<MageCard> { class CardCostComparator implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
@ -384,9 +384,9 @@ class CardCostComparator implements Comparator<MageCard> {
} }
} }
} }
class CardColorComparator implements Comparator<MageCard> { class CardColorComparator implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
@ -398,9 +398,9 @@ class CardColorComparator implements Comparator<MageCard> {
} }
} }
} }
class CardColorDetailedIdentity implements Comparator<MageCard> { class CardColorDetailedIdentity implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
@ -413,9 +413,9 @@ class CardColorDetailedIdentity implements Comparator<MageCard> {
} }
} }
} }
class CardTypeComparator implements Comparator<MageCard> { class CardTypeComparator implements Comparator<MageCard> {
@Override @Override
public int compare(MageCard o1, MageCard o2) { public int compare(MageCard o1, MageCard o2) {
@ -427,4 +427,4 @@ class CardTypeComparator implements Comparator<MageCard> {
} }
} }
} }

View file

@ -8,6 +8,7 @@
package mage.client.cards; package mage.client.cards;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.CardsViewUtil; import mage.client.util.CardsViewUtil;
import mage.client.util.Config; import mage.client.util.Config;
@ -227,7 +228,7 @@
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId) { private void addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard mageCard = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true); MageCard mageCard = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode());
if (zone != null) { if (zone != null) {
mageCard.setZone(zone); mageCard.setZone(zone);
} }

View file

@ -5,41 +5,41 @@
* *
* Created on Dec 18, 2009, 10:40:12 AM * Created on Dec 18, 2009, 10:40:12 AM
*/ */
package mage.client.cards; package mage.client.cards;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.constants.Constants.DeckEditorMode; import mage.client.constants.Constants.DeckEditorMode;
import mage.client.constants.Constants.SortBy; import mage.client.constants.Constants.SortBy;
import mage.client.deckeditor.SortSetting; import mage.client.deckeditor.SortSetting;
import mage.client.deckeditor.table.TableModel; import mage.client.deckeditor.table.TableModel;
import mage.client.deckeditor.table.UpdateCountsCallback; import mage.client.deckeditor.table.UpdateCountsCallback;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.*; import mage.client.util.Event;
import mage.client.util.Event; import mage.client.util.*;
import mage.client.util.gui.TableSpinnerEditor; import mage.client.util.gui.TableSpinnerEditor;
import mage.view.CardView; import mage.view.CardView;
import mage.view.CardsView; import mage.view.CardsView;
import mage.view.SimpleCardView; import mage.view.SimpleCardView;
import org.mage.card.arcane.CardPanel; import org.mage.card.arcane.CardPanel;
import org.mage.card.arcane.ManaSymbolsCellRenderer; import org.mage.card.arcane.ManaSymbolsCellRenderer;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.beans.Beans; import java.beans.Beans;
import java.util.*; import java.util.List;
import java.util.List; import java.util.*;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class CardsList extends javax.swing.JPanel implements MouseListener, ICardGrid { public class CardsList extends javax.swing.JPanel implements MouseListener, ICardGrid {
protected final CardEventSource cardEventSource = new CardEventSource(); protected final CardEventSource cardEventSource = new CardEventSource();
private Dimension cardDimension; private Dimension cardDimension;
@ -389,7 +389,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar
} }
private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) { private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true); MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true, PreferencesDialog.getRenderMode());
cardArea.add(cardImg); cardArea.add(cardImg);
cardImg.update(card); cardImg.update(card);
cardImg.addMouseListener(this); cardImg.addMouseListener(this);
@ -706,4 +706,4 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar
this.sortSetting = sortSetting; this.sortSetting = sortSetting;
} }
} }

View file

@ -10,6 +10,7 @@ package mage.client.cards;
import mage.cards.CardDimensions; import mage.cards.CardDimensions;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.CardViewRarityComparator; import mage.client.util.CardViewRarityComparator;
import mage.client.util.ClientEventType; import mage.client.util.ClientEventType;
@ -28,7 +29,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class DraftGrid extends javax.swing.JPanel implements MouseListener { public class DraftGrid extends javax.swing.JPanel implements MouseListener {
@ -40,17 +40,19 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
protected MageCard markedCard; protected MageCard markedCard;
protected boolean emptyGrid; protected boolean emptyGrid;
/** Creates new form DraftGrid */ /**
* Creates new form DraftGrid
*/
public DraftGrid() { public DraftGrid() {
initComponents(); initComponents();
markedCard = null; markedCard = null;
emptyGrid= true; emptyGrid = true;
} }
public void clear() { public void clear() {
markedCard = null; markedCard = null;
this.clearCardEventListeners(); this.clearCardEventListeners();
for (Component comp: getComponents()) { for (Component comp : getComponents()) {
if (comp instanceof Card || comp instanceof MageCard) { if (comp instanceof Card || comp instanceof MageCard) {
this.remove(comp); this.remove(comp);
} }
@ -79,10 +81,10 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
CardDimensions cardDimension = null; CardDimensions cardDimension = null;
int maxCards; int maxCards;
double scale ; double scale;
for (int i = 1; i < maxRows; i++) { for (int i = 1; i < maxRows; i++) {
scale = (double) (this.getHeight()/i) / Constants.FRAME_MAX_HEIGHT; scale = (double) (this.getHeight() / i) / Constants.FRAME_MAX_HEIGHT;
cardDimension = new CardDimensions(scale); cardDimension = new CardDimensions(scale);
maxCards = this.getWidth() / (cardDimension.getFrameWidth() + offsetX); maxCards = this.getWidth() / (cardDimension.getFrameWidth() + offsetX);
if ((maxCards * i) >= booster.size()) { if ((maxCards * i) >= booster.size()) {
@ -100,8 +102,8 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
List<CardView> sortedCards = new ArrayList<>(booster.values()); List<CardView> sortedCards = new ArrayList<>(booster.values());
sortedCards.sort(new CardViewRarityComparator()); sortedCards.sort(new CardViewRarityComparator());
for (CardView card: sortedCards) { for (CardView card : sortedCards) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, dimension, null, true, true); MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, dimension, null, true, true, PreferencesDialog.getRenderMode());
cardImg.addMouseListener(this); cardImg.addMouseListener(this);
add(cardImg); add(cardImg);
cardImg.update(card); cardImg.update(card);
@ -133,7 +135,8 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
Plugins.instance.getActionCallback().mouseExited(null, null); Plugins.instance.getActionCallback().mouseExited(null, null);
} }
/** This method is called from within the constructor to /**
* This method is called from within the constructor to
* initialize the form. * initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor. * always regenerated by the Form Editor.
@ -160,7 +163,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
if (e.getButton() == MouseEvent.BUTTON1) { if (e.getButton() == MouseEvent.BUTTON1) {
Object obj = e.getSource(); Object obj = e.getSource();
if (obj instanceof MageCard) { if (obj instanceof MageCard) {
this.cardEventSource.fireEvent(((MageCard)obj).getOriginal(), ClientEventType.PICK_A_CARD); this.cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.PICK_A_CARD);
this.hidePopup(); this.hidePopup();
AudioManager.playOnDraftSelect(); AudioManager.playOnDraftSelect();
} }
@ -177,8 +180,8 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
if (this.markedCard != null) { if (this.markedCard != null) {
markedCard.setSelected(false); markedCard.setSelected(false);
} }
this.cardEventSource.fireEvent(((MageCard)obj).getOriginal(), ClientEventType.MARK_A_CARD); this.cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.MARK_A_CARD);
markedCard = ((MageCard)obj); markedCard = ((MageCard) obj);
markedCard.setSelected(true); markedCard.setSelected(true);
repaint(); repaint();
} }

View file

@ -1,16 +1,5 @@
package mage.client.cards; package mage.client.cards;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.swing.*;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.cards.decks.DeckCardInfo; import mage.cards.decks.DeckCardInfo;
@ -31,6 +20,18 @@ import mage.view.CardsView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.CardRenderer; import org.mage.card.arcane.CardRenderer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* Created by StravantUser on 2016-09-20. * Created by StravantUser on 2016-09-20.
*/ */
@ -456,6 +457,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
--count; --count;
} }
} }
private int count = 0; private int count = 0;
} }
@ -659,7 +661,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
@Override @Override
public String toString() { public String toString() {
return '(' + sort.toString() + ',' + Boolean.toString(separateCreatures) + ',' + Integer.toString(cardSize) + ')'; return '(' + sort.toString() + ',' + separateCreatures + ',' + cardSize + ')';
} }
} }
@ -1767,7 +1769,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
updateCounts(); updateCounts();
// Create the card view // Create the card view
final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new Dimension(getCardWidth(), getCardHeight()), null, true, true); final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new Dimension(getCardWidth(), getCardHeight()), null, true, true, PreferencesDialog.getRenderMode());
cardPanel.update(card); cardPanel.update(card);
cardPanel.setCardCaptionTopOffset(0); cardPanel.setCardCaptionTopOffset(0);

View file

@ -3,8 +3,8 @@ package mage.client.combat;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.game.PlayAreaPanel; import mage.client.game.PlayAreaPanel;
import mage.client.util.audio.AudioManager;
import mage.client.util.SettingsManager; import mage.client.util.SettingsManager;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder; import mage.client.util.gui.ArrowBuilder;
import mage.view.CardView; import mage.view.CardView;
import mage.view.CombatGroupView; import mage.view.CombatGroupView;
@ -67,7 +67,7 @@ public enum CombatManager {
} }
private void drawAttacker(CombatGroupView group, CardView attacker, UUID gameId) { private void drawAttacker(CombatGroupView group, CardView attacker, UUID gameId) {
for (PlayAreaPanel pa2 : MageFrame.getGame(gameId).getPlayers().values()) { for (PlayAreaPanel pa2 : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent attackerCard = pa2.getBattlefieldPanel().getPermanents().get(attacker.getId()); MagePermanent attackerCard = pa2.getBattlefieldPanel().getPermanents().get(attacker.getId());
if (attackerCard != null) { if (attackerCard != null) {
drawDefender(group, attackerCard, gameId); drawDefender(group, attackerCard, gameId);
@ -80,7 +80,7 @@ public enum CombatManager {
UUID defenderId = group.getDefenderId(); UUID defenderId = group.getDefenderId();
if (defenderId != null) { if (defenderId != null) {
parentPoint = getParentPoint(attackerCard); parentPoint = getParentPoint(attackerCard);
PlayAreaPanel p = MageFrame.getGame(gameId).getPlayers().get(defenderId); PlayAreaPanel p = MageFrame.getGamePlayers(gameId).get(defenderId);
if (p != null) { if (p != null) {
Point target = p.getLocationOnScreen(); Point target = p.getLocationOnScreen();
target.translate(-parentPoint.x, -parentPoint.y); target.translate(-parentPoint.x, -parentPoint.y);
@ -88,7 +88,7 @@ public enum CombatManager {
attackerPoint.translate(-parentPoint.x, -parentPoint.y); attackerPoint.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() - 20, Color.red, ArrowBuilder.Type.COMBAT); ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() - 20, Color.red, ArrowBuilder.Type.COMBAT);
} else { } else {
for (PlayAreaPanel pa : MageFrame.getGame(gameId).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(defenderId); MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(defenderId);
if (permanent != null) { if (permanent != null) {
Point target = permanent.getLocationOnScreen(); Point target = permanent.getLocationOnScreen();
@ -104,7 +104,7 @@ public enum CombatManager {
private void drawBlockers(CombatGroupView group, MagePermanent attackerCard, UUID gameId) { private void drawBlockers(CombatGroupView group, MagePermanent attackerCard, UUID gameId) {
for (CardView blocker : group.getBlockers().values()) { for (CardView blocker : group.getBlockers().values()) {
for (PlayAreaPanel pa : MageFrame.getGame(gameId).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent blockerCard = pa.getBattlefieldPanel().getPermanents().get(blocker.getId()); MagePermanent blockerCard = pa.getBattlefieldPanel().getPermanents().get(blocker.getId());
if (blockerCard != null) { if (blockerCard != null) {
parentPoint = getParentPoint(blockerCard); parentPoint = getParentPoint(blockerCard);

View file

@ -8,6 +8,7 @@ import mage.client.components.ext.dlg.DialogContainer;
import mage.client.components.ext.dlg.DialogManager; import mage.client.components.ext.dlg.DialogManager;
import mage.client.components.ext.dlg.DlgParams; import mage.client.components.ext.dlg.DlgParams;
import mage.client.components.ext.dlg.IDialogPanel; import mage.client.components.ext.dlg.IDialogPanel;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.Command; import mage.client.util.Command;
import mage.client.util.SettingsManager; import mage.client.util.SettingsManager;
@ -162,7 +163,7 @@ public class ChoiceDialog extends IDialogPanel {
} }
CardView card = cardList.get(i); CardView card = cardList.get(i);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true); MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode());
cardImg.setLocation(dx, dy + j * (height + 30)); cardImg.setLocation(dx, dy + j * (height + 30));
add(cardImg); add(cardImg);

View file

@ -7,6 +7,7 @@ import mage.client.components.ext.dlg.DialogContainer;
import mage.client.components.ext.dlg.DialogManager; import mage.client.components.ext.dlg.DialogManager;
import mage.client.components.ext.dlg.DlgParams; import mage.client.components.ext.dlg.DlgParams;
import mage.client.components.ext.dlg.IDialogPanel; import mage.client.components.ext.dlg.IDialogPanel;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.FeedbackPanel; import mage.client.game.FeedbackPanel;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.Command; import mage.client.util.Command;
@ -40,7 +41,7 @@ public class StackDialog extends IDialogPanel {
@Override @Override
public void paintComponent(Graphics g) { public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D)g; Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); RenderingHints.VALUE_ANTIALIAS_ON);
@ -111,7 +112,7 @@ public class StackDialog extends IDialogPanel {
for (CardView card : cards.values()) { for (CardView card : cards.values()) {
if (card instanceof StackAbilityView) { if (card instanceof StackAbilityView) {
CardView tmp = ((StackAbilityView)card).getSourceCard(); CardView tmp = ((StackAbilityView) card).getSourceCard();
tmp.overrideRules(card.getRules()); tmp.overrideRules(card.getRules());
tmp.setIsAbility(true); tmp.setIsAbility(true);
tmp.overrideTargets(card.getTargets()); tmp.overrideTargets(card.getTargets());
@ -119,7 +120,7 @@ public class StackDialog extends IDialogPanel {
card = tmp; card = tmp;
} }
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true); MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode());
//cardImg.setBorder(BorderFactory.createLineBorder(Color.red)); //cardImg.setBorder(BorderFactory.createLineBorder(Color.red));
cardImg.setLocation(dx, dy); cardImg.setLocation(dx, dy);
@ -143,10 +144,11 @@ public class StackDialog extends IDialogPanel {
jButtonAccept.setObserver(new Command() { jButtonAccept.setObserver(new Command() {
@Override @Override
public void execute() { public void execute() {
DialogManager.getManager(gameId).fadeOut((DialogContainer)getParent()); DialogManager.getManager(gameId).fadeOut((DialogContainer) getParent());
//GameManager.getInputControl().getInput().selectButtonOK(); //GameManager.getInputControl().getInput().selectButtonOK();
StackDialog.this.feedbackPanel.doClick(); StackDialog.this.feedbackPanel.doClick();
} }
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
}); });
} }
@ -166,11 +168,12 @@ public class StackDialog extends IDialogPanel {
jButtonResponse.setObserver(new Command() { jButtonResponse.setObserver(new Command() {
@Override @Override
public void execute() { public void execute() {
DialogManager.getManager(gameId).fadeOut((DialogContainer)getParent()); DialogManager.getManager(gameId).fadeOut((DialogContainer) getParent());
} }
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
}); });
} }
return jButtonResponse; return jButtonResponse;
} }
} }

View file

@ -136,7 +136,7 @@ public class DeckGeneratorPool
int cardCount = getCardCount((card.getName())); int cardCount = getCardCount((card.getName()));
// No need to check if the land is valid for the colors chosen // No need to check if the land is valid for the colors chosen
// They are all filtered before searching for lands to include in the deck. // They are all filtered before searching for lands to include in the deck.
return (cardCount < 4); return (cardCount < (isSingleton ? 1 : 4));
} }

View file

@ -447,7 +447,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
} }
} }
}); });
refreshDeck(); refreshDeck(true);
if (mode == DeckEditorMode.FREE_BUILDING) { if (mode == DeckEditorMode.FREE_BUILDING) {
setDropTarget(new DropTarget(this, new DnDDeckTargetListener() { setDropTarget(new DropTarget(this, new DnDDeckTargetListener() {
@ -1414,14 +1414,15 @@ class ImportFilter extends FileFilter {
|| ext.equalsIgnoreCase("txt") || ext.equalsIgnoreCase("txt")
|| ext.equalsIgnoreCase("dek") || ext.equalsIgnoreCase("dek")
|| ext.equalsIgnoreCase("cod") || ext.equalsIgnoreCase("cod")
|| ext.equalsIgnoreCase("o8d"); || ext.equalsIgnoreCase("o8d")
|| ext.equalsIgnoreCase("draft");
} }
return false; return false;
} }
@Override @Override
public String getDescription() { public String getDescription() {
return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d)"; return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d; *.draft)";
} }
} }

View file

@ -8,6 +8,7 @@ import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.components.HoverButton; import mage.client.components.HoverButton;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
@ -406,7 +407,7 @@ public class MageBook extends JComponent {
if (cardDimension == null) { if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight()); cardDimension = new Dimension(Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight());
} }
final MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true); final MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true, PreferencesDialog.getRenderMode());
cardImg.setBounds(rectangle); cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10); jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(card); cardImg.update(card);
@ -447,7 +448,7 @@ public class MageBook extends JComponent {
newToken.removeSummoningSickness(); newToken.removeSummoningSickness();
PermanentView theToken = new PermanentView(newToken, null, null, null); PermanentView theToken = new PermanentView(newToken, null, null, null);
theToken.setInViewerOnly(true); theToken.setInViewerOnly(true);
final MageCard cardImg = Plugins.instance.getMagePermanent(theToken, bigCard, cardDimension, gameId, true); final MageCard cardImg = Plugins.instance.getMagePermanent(theToken, bigCard, cardDimension, gameId, true, PreferencesDialog.getRenderMode());
cardImg.setBounds(rectangle); cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10); jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(theToken); cardImg.update(theToken);

View file

@ -23,26 +23,26 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel3" alignment="0" max="32767" attributes="0"/> <Component id="scrollDevs" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="btnWhatsNew" min="-2" pref="100" max="-2" attributes="0"/> <Component id="btnWhatsNew" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Component id="btnOk" min="-2" pref="100" max="-2" attributes="0"/> <Component id="btnOk" min="-2" pref="100" max="-2" attributes="0"/>
</Group> </Group>
<Component id="jLabel4" alignment="0" max="32767" attributes="0"/> <Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblVersion" min="-2" max="-2" attributes="0"/> <Component id="lblVersion" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="labelDevs" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="80" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -60,10 +60,10 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" pref="21" max="-2" attributes="0"/> <Component id="labelDevs" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="scrollDevs" pref="161" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="68" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btnOk" alignment="3" min="-2" pref="30" max="-2" attributes="0"/> <Component id="btnOk" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
<Component id="btnWhatsNew" alignment="3" min="-2" pref="30" max="-2" attributes="0"/> <Component id="btnWhatsNew" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
@ -94,17 +94,7 @@
</Component> </Component>
<Component class="javax.swing.JLabel" name="jLabel2"> <Component class="javax.swing.JLabel" name="jLabel2">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Courtesy: BetaSteward@googlemail.com. Site: http://XMage.de/"/> <Property name="text" type="java.lang.String" value="Courtesy: BetaSteward@googlemail.com. Site: http://xmage.de/"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" value="Devs: BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, Jeff, Plopman, dustinconrad, emerald000.,"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel4">
<Properties>
<Property name="text" type="java.lang.String" value="fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox."/>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JButton" name="btnWhatsNew"> <Component class="javax.swing.JButton" name="btnWhatsNew">
@ -115,5 +105,26 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnWhatsNewActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnWhatsNewActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Container class="javax.swing.JScrollPane" name="scrollDevs">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="panelDevs">
<Properties>
<Property name="editable" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="labelDevs">
<Properties>
<Property name="text" type="java.lang.String" value="Developers:"/>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View file

@ -6,15 +6,20 @@ import mage.utils.MageVersion;
import javax.swing.*; import javax.swing.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
/** /**
* @author JayDi85 * @author JayDi85
*/ */
public class AboutDialog extends MageDialog { public class AboutDialog extends MageDialog {
private static String devsList = "BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, "
+ "Jeff, Plopman, dustinconrad, emerald000, fireshoes, lunaskyrise, "
+ "mnapoleon, jgod, LoneFox, drmDev, spjspj, TheElk801, L_J, JayDi85, "
+ "jmharmon, Ketsuban, hitch17";
public AboutDialog() { public AboutDialog() {
initComponents(); initComponents();
this.modal = false; this.modal = false;
panelDevs.setText(devsList + " and hundreds of other developers from https://github.com/magefree/mage/graphs/contributors");
} }
public void showDialog(MageVersion version) { public void showDialog(MageVersion version) {
@ -54,9 +59,10 @@ public class AboutDialog extends MageDialog {
jLabel1 = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel();
lblVersion = new javax.swing.JLabel(); lblVersion = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
btnWhatsNew = new javax.swing.JButton(); btnWhatsNew = new javax.swing.JButton();
scrollDevs = new javax.swing.JScrollPane();
panelDevs = new javax.swing.JTextPane();
labelDevs = new javax.swing.JLabel();
setMaximizable(true); setMaximizable(true);
setTitle("About XMage"); setTitle("About XMage");
@ -72,11 +78,7 @@ public class AboutDialog extends MageDialog {
lblVersion.setText("0.0.0"); lblVersion.setText("0.0.0");
jLabel2.setText("Courtesy: BetaSteward@googlemail.com. Site: http://XMage.de/"); jLabel2.setText("Courtesy: BetaSteward@googlemail.com. Site: http://xmage.de/");
jLabel3.setText("Devs: BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, Jeff, Plopman, dustinconrad, emerald000.,");
jLabel4.setText("fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox.");
btnWhatsNew.setText("What's new"); btnWhatsNew.setText("What's new");
btnWhatsNew.addActionListener(new java.awt.event.ActionListener() { btnWhatsNew.addActionListener(new java.awt.event.ActionListener() {
@ -85,27 +87,34 @@ public class AboutDialog extends MageDialog {
} }
}); });
scrollDevs.setBorder(null);
panelDevs.setEditable(false);
scrollDevs.setViewportView(panelDevs);
labelDevs.setText("Developers:");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(scrollDevs)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(btnWhatsNew, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnWhatsNew, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup()
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createSequentialGroup()
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(jLabel1) .addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblVersion)) .addComponent(lblVersion))
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)) .addComponent(jLabel2)
.addGap(0, 0, Short.MAX_VALUE))) .addComponent(labelDevs))
.addGap(0, 80, Short.MAX_VALUE)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
@ -118,10 +127,10 @@ public class AboutDialog extends MageDialog {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel2) .addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(labelDevs)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scrollDevs, javax.swing.GroupLayout.DEFAULT_SIZE, 161, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 68, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnWhatsNew, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(btnWhatsNew, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
@ -144,9 +153,10 @@ public class AboutDialog extends MageDialog {
private javax.swing.JButton btnWhatsNew; private javax.swing.JButton btnWhatsNew;
private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3; private javax.swing.JLabel labelDevs;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel lblVersion; private javax.swing.JLabel lblVersion;
private javax.swing.JTextPane panelDevs;
private javax.swing.JScrollPane scrollDevs;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View file

@ -88,6 +88,9 @@ public class ConnectDialog extends MageDialog {
MagePreferences.setUserName(serverAddress, txtUserName.getText().trim()); MagePreferences.setUserName(serverAddress, txtUserName.getText().trim());
MagePreferences.setPassword(serverAddress, String.valueOf(txtPassword.getPassword()).trim()); MagePreferences.setPassword(serverAddress, String.valueOf(txtPassword.getPassword()).trim());
MageFrame.getPreferences().put(KEY_CONNECT_AUTO_CONNECT, Boolean.toString(chkAutoConnect.isSelected())); MageFrame.getPreferences().put(KEY_CONNECT_AUTO_CONNECT, Boolean.toString(chkAutoConnect.isSelected()));
// last settings for reconnect
MagePreferences.saveLastServer();
} }
/** /**
@ -517,7 +520,6 @@ public class ConnectDialog extends MageDialog {
char[] input = new char[0]; char[] input = new char[0];
try { try {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
connection = new Connection(); connection = new Connection();
connection.setHost(this.txtServer.getText().trim()); connection.setHost(this.txtServer.getText().trim());
connection.setPort(Integer.valueOf(this.txtPort.getText().trim())); connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
@ -545,6 +547,12 @@ public class ConnectDialog extends MageDialog {
}//GEN-LAST:event_btnConnectActionPerformed }//GEN-LAST:event_btnConnectActionPerformed
private void setConnectButtonsState(boolean enable) {
btnConnect.setEnabled(enable);
btnRegister.setEnabled(enable);
btnForgotPassword.setEnabled(enable);
}
private class ConnectTask extends SwingWorker<Boolean, Void> { private class ConnectTask extends SwingWorker<Boolean, Void> {
private boolean result = false; private boolean result = false;
@ -555,7 +563,7 @@ public class ConnectDialog extends MageDialog {
@Override @Override
protected Boolean doInBackground() throws Exception { protected Boolean doInBackground() throws Exception {
lblStatus.setText("Connecting..."); lblStatus.setText("Connecting...");
btnConnect.setEnabled(false); setConnectButtonsState(false);
result = MageFrame.connect(connection); result = MageFrame.connect(connection);
lastConnectError = SessionHandler.getLastConnectError(); lastConnectError = SessionHandler.getLastConnectError();
return result; return result;
@ -565,7 +573,6 @@ public class ConnectDialog extends MageDialog {
protected void done() { protected void done() {
try { try {
get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS); get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if (result) { if (result) {
lblStatus.setText(""); lblStatus.setText("");
connected(); connected();
@ -578,13 +585,13 @@ public class ConnectDialog extends MageDialog {
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
logger.fatal("Update Players Task error", ex); logger.fatal("Update Players Task error", ex);
} catch (CancellationException ex) { } catch (CancellationException ex) {
logger.info("Connect was canceled"); logger.info("Connect: canceled");
lblStatus.setText("Connect was canceled"); lblStatus.setText("Connect was canceled");
} catch (TimeoutException ex) { } catch (TimeoutException ex) {
logger.fatal("Connection timeout: ", ex); logger.fatal("Connection timeout: ", ex);
} finally { } finally {
MageFrame.stopConnecting(); MageFrame.stopConnecting();
btnConnect.setEnabled(true); setConnectButtonsState(true);
} }
} }
} }

View file

@ -109,6 +109,7 @@ public class MageDialog extends javax.swing.JInternalFrame {
SwingUtilities.invokeAndWait(() -> stopModal()); SwingUtilities.invokeAndWait(() -> stopModal());
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
LOGGER.fatal("MageDialog error", ex); LOGGER.fatal("MageDialog error", ex);
Thread.currentThread().interrupt();
} catch (InvocationTargetException ex) { } catch (InvocationTargetException ex) {
LOGGER.fatal("MageDialog error", ex); LOGGER.fatal("MageDialog error", ex);
} }
@ -184,9 +185,10 @@ public class MageDialog extends javax.swing.JInternalFrame {
wait(); wait();
} }
} }
} catch (InterruptedException ignored) { } catch (InterruptedException e) {
LOGGER.fatal("MageDialog error", e);
Thread.currentThread().interrupt();
} }
} }
private synchronized void stopModal() { private synchronized void stopModal() {

View file

@ -637,13 +637,18 @@ public class NewTableDialog extends MageDialog {
case "Variant Magic - Commander": case "Variant Magic - Commander":
case "Variant Magic - Duel Commander": case "Variant Magic - Duel Commander":
case "Variant Magic - MTGO 1v1 Commander": case "Variant Magic - MTGO 1v1 Commander":
case "Variant Magic - Freeform Commander":
case "Variant Magic - Penny Dreadful Commander": case "Variant Magic - Penny Dreadful Commander":
if (!options.getGameType().startsWith("Commander")) { if (!options.getGameType().startsWith("Commander")) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Commander needs also a Commander game type", "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Commander needs also a Commander game type", "Error", JOptionPane.ERROR_MESSAGE);
return false; return false;
} }
break; break;
case "Variant Magic - Freeform Commander":
if (!options.getGameType().startsWith("Freeform Commander")) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Freeform Commander needs also a Freeform Commander game type", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
break;
case "Variant Magic - Brawl": case "Variant Magic - Brawl":
case "Variant Magic - Duel Brawl": case "Variant Magic - Duel Brawl":
if (!options.getGameType().startsWith("Brawl")) { if (!options.getGameType().startsWith("Brawl")) {
@ -678,6 +683,13 @@ public class NewTableDialog extends MageDialog {
return false; return false;
} }
break; break;
case "Freeform Commander Two Player Duel":
case "Freeform Commander Free For All":
if (!options.getDeckType().equals("Variant Magic - Freeform Commander")) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Deck type Freeform Commander needs also a Freeform Commander game type", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
break;
case "Brawl Two Player Duel": case "Brawl Two Player Duel":
case "Brawl Free For All": case "Brawl Free For All":
if (!options.getDeckType().equals("Variant Magic - Brawl") if (!options.getDeckType().equals("Variant Magic - Brawl")

View file

@ -31,6 +31,7 @@ import java.awt.*;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* @author BetaSteward_at_googlemail.com, JayDi85 * @author BetaSteward_at_googlemail.com, JayDi85
@ -655,7 +656,7 @@ public class NewTournamentDialog extends MageDialog {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void cbTournamentTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTournamentTypeActionPerformed private void cbTournamentTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTournamentTypeActionPerformed
setTournamentOptions((Integer) this.spnNumPlayers.getValue()); prepareTourneyView((Integer) this.spnNumPlayers.getValue());
}//GEN-LAST:event_cbTournamentTypeActionPerformed }//GEN-LAST:event_cbTournamentTypeActionPerformed
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
@ -663,6 +664,15 @@ public class NewTournamentDialog extends MageDialog {
// get settings // get settings
TournamentOptions tOptions = getTournamentOptions(); TournamentOptions tOptions = getTournamentOptions();
// CHECKS
TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem();
if (tournamentType.isRandom() || tournamentType.isRichMan()) {
if (tOptions.getLimitedOptions().getSetCodes().isEmpty()) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Warning, you must select packs for the pool", "Warning", JOptionPane.WARNING_MESSAGE);
return;
}
}
// save last settings // save last settings
onSaveSettings(0, tOptions); onSaveSettings(0, tOptions);
@ -837,19 +847,25 @@ public class NewTournamentDialog extends MageDialog {
createPlayers((Integer) spnNumPlayers.getValue() - 1); createPlayers((Integer) spnNumPlayers.getValue() - 1);
} }
private void setTournamentOptions(int numPlayers) { private void prepareTourneyView(int numPlayers) {
TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem();
activatePanelElements(tournamentType); activatePanelElements(tournamentType);
// players
if (numPlayers < tournamentType.getMinPlayers() || numPlayers > tournamentType.getMaxPlayers()) { if (numPlayers < tournamentType.getMinPlayers() || numPlayers > tournamentType.getMaxPlayers()) {
numPlayers = tournamentType.getMinPlayers(); numPlayers = tournamentType.getMinPlayers();
createPlayers(numPlayers - 1); createPlayers(numPlayers - 1); // ?
} }
this.spnNumPlayers.setModel(new SpinnerNumberModel(numPlayers, tournamentType.getMinPlayers(), tournamentType.getMaxPlayers(), 1)); this.spnNumPlayers.setModel(new SpinnerNumberModel(numPlayers, tournamentType.getMinPlayers(), tournamentType.getMaxPlayers(), 1));
this.spnNumPlayers.setEnabled(tournamentType.getMinPlayers() != tournamentType.getMaxPlayers()); this.spnNumPlayers.setEnabled(tournamentType.getMinPlayers() != tournamentType.getMaxPlayers());
createPlayers((Integer) spnNumPlayers.getValue() - 1); createPlayers((Integer) spnNumPlayers.getValue() - 1);
this.spnNumSeats.setModel(new SpinnerNumberModel(2, 2, tournamentType.getMaxPlayers(), 1)); this.spnNumSeats.setModel(new SpinnerNumberModel(2, 2, tournamentType.getMaxPlayers(), 1));
// packs
preparePacksView(tournamentType);
}
private void preparePacksView(TournamentTypeView tournamentType) {
if (tournamentType.isLimited()) { if (tournamentType.isLimited()) {
this.isRandom = tournamentType.isRandom(); this.isRandom = tournamentType.isRandom();
this.isRichMan = tournamentType.isRichMan(); this.isRichMan = tournamentType.isRichMan();
@ -859,7 +875,6 @@ public class NewTournamentDialog extends MageDialog {
createPacks(tournamentType.getNumBoosters()); createPacks(tournamentType.getNumBoosters());
} }
} }
} }
private void setNumberOfSwissRoundsMin(int numPlayers) { private void setNumberOfSwissRoundsMin(int numPlayers) {
@ -921,6 +936,43 @@ public class NewTournamentDialog extends MageDialog {
} }
} }
private String prepareVersionStr(int version, boolean saveMode) {
// version: 0, 1, 2... to save/load
// version: -1 to reset (load from empty record)
switch (version) {
case -1:
return saveMode ? "" : "-1"; // can't save to -1 version
case 1:
return "1";
case 2:
return "2";
default:
return "";
}
}
private void loadRandomPacks(int version) {
String versionStr = prepareVersionStr(version, false);
ArrayList<String> packList;
String packNames;
String randomPrefs = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT + versionStr, "");
if (!randomPrefs.isEmpty()) {
packList = new ArrayList<>(Arrays.asList(randomPrefs.split(";")));
packNames = randomPrefs;
} else {
ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate();
packList = Arrays.stream(allExpansions).map(ExpansionInfo::getCode).collect(Collectors.toCollection(ArrayList::new));
packNames = Arrays.stream(allExpansions).map(ExpansionInfo::getCode).collect(Collectors.joining(";"));
}
randomPackSelector.setSelectedPacks(packList);
txtRandomPacks.setText(packNames);
// workaround to apply field's auto-size
this.pack();
this.revalidate();
this.repaint();
}
private void createRandomPacks() { private void createRandomPacks() {
if (pnlRandomPacks.getComponentCount() == 0) { if (pnlRandomPacks.getComponentCount() == 0) {
if (randomPackSelector == null) { if (randomPackSelector == null) {
@ -930,20 +982,9 @@ public class NewTournamentDialog extends MageDialog {
txtRandomPacks = new JTextArea(); txtRandomPacks = new JTextArea();
txtRandomPacks.setEnabled(false); txtRandomPacks.setEnabled(false);
txtRandomPacks.setLineWrap(true); txtRandomPacks.setLineWrap(true);
String randomPrefs = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT, "");
if (!randomPrefs.isEmpty()) { loadRandomPacks(-1); // load default packs
txtRandomPacks.setText(randomPrefs);
ArrayList<String> theList = new ArrayList<>(Arrays.asList(randomPrefs.split(";")));
randomPackSelector.setSelectedPacks(theList);
} else {
ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate();
StringBuilder packList = new StringBuilder();
for (ExpansionInfo exp : allExpansions) {
packList.append(exp.getCode());
packList.append(';');
}
txtRandomPacks.setText(packList.toString());
}
txtRandomPacks.setAlignmentX(Component.LEFT_ALIGNMENT); txtRandomPacks.setAlignmentX(Component.LEFT_ALIGNMENT);
pnlRandomPacks.add(txtRandomPacks); pnlRandomPacks.add(txtRandomPacks);
JButton btnSelectRandomPacks = new JButton(); JButton btnSelectRandomPacks = new JButton();
@ -953,6 +994,7 @@ public class NewTournamentDialog extends MageDialog {
btnSelectRandomPacks.addActionListener(evt -> showRandomPackSelectorDialog()); btnSelectRandomPacks.addActionListener(evt -> showRandomPackSelectorDialog());
pnlRandomPacks.add(btnSelectRandomPacks); pnlRandomPacks.add(btnSelectRandomPacks);
} }
txtRandomPacks.setText(txtRandomPacks.getText()); // workaround to apply field's auto-size
this.pack(); this.pack();
this.revalidate(); this.revalidate();
this.repaint(); this.repaint();
@ -961,12 +1003,7 @@ public class NewTournamentDialog extends MageDialog {
private void showRandomPackSelectorDialog() { private void showRandomPackSelectorDialog() {
randomPackSelector.setType(isRandom, isRichMan); randomPackSelector.setType(isRandom, isRichMan);
randomPackSelector.showDialog(); randomPackSelector.showDialog();
StringBuilder packList = new StringBuilder(); this.txtRandomPacks.setText(String.join(";", randomPackSelector.getSelectedPacks()));
for (String str : randomPackSelector.getSelectedPacks()) {
packList.append(str);
packList.append(';');
}
this.txtRandomPacks.setText(packList.toString());
this.pack(); this.pack();
this.revalidate(); this.revalidate();
this.repaint(); this.repaint();
@ -1169,6 +1206,7 @@ public class NewTournamentDialog extends MageDialog {
if (tournamentType.isLimited()) { if (tournamentType.isLimited()) {
tOptions.getLimitedOptions().setConstructionTime((Integer) this.spnConstructTime.getValue() * 60); tOptions.getLimitedOptions().setConstructionTime((Integer) this.spnConstructTime.getValue() * 60);
tOptions.getLimitedOptions().setIsRandom(tournamentType.isRandom()); tOptions.getLimitedOptions().setIsRandom(tournamentType.isRandom());
tOptions.getLimitedOptions().setIsRichMan(tournamentType.isRichMan());
if (tournamentType.isCubeBooster()) { if (tournamentType.isCubeBooster()) {
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString()); tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
if (!(cubeFromDeckFilename.isEmpty())) { if (!(cubeFromDeckFilename.isEmpty())) {
@ -1188,6 +1226,7 @@ public class NewTournamentDialog extends MageDialog {
this.isRichMan = tournamentType.isRichMan(); this.isRichMan = tournamentType.isRichMan();
tOptions.getLimitedOptions().getSetCodes().clear(); tOptions.getLimitedOptions().getSetCodes().clear();
ArrayList<String> selected = randomPackSelector.getSelectedPacks(); ArrayList<String> selected = randomPackSelector.getSelectedPacks();
Collections.shuffle(selected);
int maxPacks = 3 * (players.size() + 1); int maxPacks = 3 * (players.size() + 1);
if (tournamentType.isRichMan()) { if (tournamentType.isRichMan()) {
maxPacks = 36; maxPacks = 36;
@ -1197,7 +1236,6 @@ public class NewTournamentDialog extends MageDialog {
infoString.append(maxPacks); infoString.append(maxPacks);
infoString.append(" sets will be randomly chosen."); infoString.append(" sets will be randomly chosen.");
JOptionPane.showMessageDialog(MageFrame.getDesktop(), infoString, "Information", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(MageFrame.getDesktop(), infoString, "Information", JOptionPane.INFORMATION_MESSAGE);
Collections.shuffle(selected);
tOptions.getLimitedOptions().getSetCodes().addAll(selected.subList(0, maxPacks)); tOptions.getLimitedOptions().getSetCodes().addAll(selected.subList(0, maxPacks));
} else { } else {
tOptions.getLimitedOptions().getSetCodes().addAll(selected); tOptions.getLimitedOptions().getSetCodes().addAll(selected);
@ -1242,23 +1280,7 @@ public class NewTournamentDialog extends MageDialog {
} }
private void onLoadSettings(int version) { private void onLoadSettings(int version) {
String versionStr = prepareVersionStr(version, false);
String versionStr = "";
switch (version) {
case -1:
versionStr = "-1"; // default (empty)
break;
case 1:
versionStr = "1";
break;
case 2:
versionStr = "2";
break;
default:
versionStr = "";
break;
}
int numPlayers; int numPlayers;
txtName.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NAME + versionStr, "Tournament")); txtName.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NAME + versionStr, "Tournament"));
txtPassword.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PASSWORD + versionStr, "")); txtPassword.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PASSWORD + versionStr, ""));
@ -1298,16 +1320,13 @@ public class NewTournamentDialog extends MageDialog {
activatePanelElements(tournamentType); activatePanelElements(tournamentType);
if (tournamentType.isLimited()) { if (tournamentType.isLimited()) {
if (!tournamentType.isDraft()) {
numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_SEALED + versionStr, "2"));
setTournamentOptions(numPlayers);
loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, ""));
}
if (tournamentType.isDraft()) { if (tournamentType.isDraft()) {
numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_DRAFT + versionStr, "4")); numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_DRAFT + versionStr, "4"));
setTournamentOptions(numPlayers); prepareTourneyView(numPlayers);
if (!(tournamentType.isRandom() || tournamentType.isRichMan())) {
if (tournamentType.isRandom() || tournamentType.isRichMan()) {
loadRandomPacks(version);
} else {
loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_DRAFT + versionStr, "")); loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_DRAFT + versionStr, ""));
} }
@ -1318,6 +1337,10 @@ public class NewTournamentDialog extends MageDialog {
break; break;
} }
} }
} else {
numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_SEALED + versionStr, "2"));
prepareTourneyView(numPlayers);
loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, ""));
} }
} }
this.cbAllowSpectators.setSelected(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_ALLOW_SPECTATORS + versionStr, "Yes").equals("Yes")); this.cbAllowSpectators.setSelected(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_ALLOW_SPECTATORS + versionStr, "Yes").equals("Yes"));
@ -1332,20 +1355,7 @@ public class NewTournamentDialog extends MageDialog {
} }
private void onSaveSettings(int version, TournamentOptions tOptions) { private void onSaveSettings(int version, TournamentOptions tOptions) {
String versionStr = prepareVersionStr(version, true);
String versionStr = "";
switch (version) {
case 1:
versionStr = "1";
break;
case 2:
versionStr = "2";
break;
default:
versionStr = "";
break;
}
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NAME + versionStr, tOptions.getName()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NAME + versionStr, tOptions.getName());
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PASSWORD + versionStr, tOptions.getPassword()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PASSWORD + versionStr, tOptions.getPassword());
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TIME_LIMIT + versionStr, Integer.toString(tOptions.getMatchOptions().getPriorityTime())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TIME_LIMIT + versionStr, Integer.toString(tOptions.getMatchOptions().getPriorityTime()));
@ -1375,15 +1385,8 @@ public class NewTournamentDialog extends MageDialog {
if (deckFile != null && !deckFile.isEmpty()) { if (deckFile != null && !deckFile.isEmpty()) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_DECK_FILE + versionStr, deckFile); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_DECK_FILE + versionStr, deckFile);
} }
if (tOptions.getLimitedOptions().getIsRandom() || tOptions.getLimitedOptions().getIsRichMan()) {
if (tOptions.getLimitedOptions().getIsRandom()) { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT + versionStr, String.join(";", this.randomPackSelector.getSelectedPacks()));
// save random boosters to prefs
StringBuilder packlist = new StringBuilder();
for (String pack : this.randomPackSelector.getSelectedPacks()) {
packlist.append(pack);
packlist.append(';');
}
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT + versionStr, packlist.toString());
} }
} }
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_ALLOW_SPECTATORS + versionStr, (tOptions.isWatchingAllowed() ? "Yes" : "No")); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_ALLOW_SPECTATORS + versionStr, (tOptions.isWatchingAllowed() ? "Yes" : "No"));

View file

@ -24,7 +24,7 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Component id="tabsPanel" alignment="0" max="32767" attributes="0"/> <Component id="tabsPanel" alignment="0" max="32767" attributes="0"/>
@ -42,7 +42,7 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="tabsPanel" max="32767" attributes="0"/> <Component id="tabsPanel" min="-2" pref="554" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="saveButton" alignment="3" min="-2" pref="30" max="-2" attributes="0"/> <Component id="saveButton" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
@ -98,7 +98,7 @@
<Component id="main_gamelog" min="-2" max="-2" attributes="0"/> <Component id="main_gamelog" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="main_battlefield" min="-2" max="-2" attributes="0"/> <Component id="main_battlefield" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace pref="39" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -4071,7 +4071,7 @@
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="phases_stopSettings" min="-2" max="-2" attributes="0"/> <Component id="phases_stopSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="160" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -4296,12 +4296,12 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="panelCardImages" max="32767" attributes="0"/> <Component id="panelCardImages" max="32767" attributes="0"/>
<Component id="jPanel1" max="32767" attributes="0"/> <Component id="jPanel1" max="32767" attributes="0"/>
<Component id="panelBackgroundImages" max="32767" attributes="0"/> <Component id="panelBackgroundImages" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -4316,7 +4316,7 @@
<Component id="panelCardImages" min="-2" max="-2" attributes="0"/> <Component id="panelCardImages" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="panelBackgroundImages" min="-2" max="-2" attributes="0"/> <Component id="panelBackgroundImages" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="133" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -4341,6 +4341,7 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="cbUseDefaultImageFolder" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="txtImageFolderPath" max="32767" attributes="0"/> <Component id="txtImageFolderPath" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -4348,34 +4349,24 @@
</Group> </Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> <Component id="cbSaveToZipFiles" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="cbCheckForNewImages" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="147" max="-2" attributes="0"/>
</Group>
<Group type="103" alignment="0" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="labelNumberOfDownloadThreads" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="labelPreferedImageLanguage" alignment="0" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="labelPreferedImageLanguage" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
</Group>
<Component id="cbSaveToZipFiles" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
<Component id="cbPreferedImageLanguage" min="-2" pref="153" max="-2" attributes="0"/> <Component id="cbPreferedImageLanguage" min="-2" pref="153" max="-2" attributes="0"/>
</Group> <Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="labelNumberOfDownloadThreads" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbNumberOfDownloadThreads" min="-2" pref="153" max="-2" attributes="0"/> <Component id="cbNumberOfDownloadThreads" min="-2" pref="153" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="labelHint1" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
<Component id="cbUseDefaultImageFolder" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="391" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -4385,25 +4376,23 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="cbUseDefaultImageFolder" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="cbUseDefaultImageFolder" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtImageFolderPath" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="txtImageFolderPath" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseImageLocation" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnBrowseImageLocation" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cbCheckForNewImages" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbSaveToZipFiles" min="-2" max="-2" attributes="0"/> <Component id="cbSaveToZipFiles" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="labelNumberOfDownloadThreads" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="labelNumberOfDownloadThreads" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cbNumberOfDownloadThreads" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="cbNumberOfDownloadThreads" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelHint1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="cbPreferedImageLanguage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelPreferedImageLanguage" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="labelPreferedImageLanguage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cbPreferedImageLanguage" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -4431,14 +4420,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseImageLocationActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseImageLocationActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="cbCheckForNewImages">
<Properties>
<Property name="text" type="java.lang.String" value="Check for new images on startup"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbCheckForNewImagesActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbSaveToZipFiles"> <Component class="javax.swing.JCheckBox" name="cbSaveToZipFiles">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Store images in zip files"/> <Property name="text" type="java.lang.String" value="Store images in zip files"/>
@ -4465,7 +4446,7 @@
</Component> </Component>
<Component class="javax.swing.JLabel" name="labelPreferedImageLanguage"> <Component class="javax.swing.JLabel" name="labelPreferedImageLanguage">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Prefered image language:"/> <Property name="text" type="java.lang.String" value="Default images language:"/>
<Property name="focusable" type="boolean" value="false"/> <Property name="focusable" type="boolean" value="false"/>
</Properties> </Properties>
</Component> </Component>
@ -4487,145 +4468,9 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
</SubComponents> <Component class="javax.swing.JLabel" name="labelHint1">
</Container>
<Container class="javax.swing.JPanel" name="panelBackgroundImages">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="text" type="java.lang.String" value="(change it to 1-3 if image source bans your IP for too many connections)"/>
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Background images">
<Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Component id="jLabel14" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
<Component id="jLabel15" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtBackgroundImagePath" max="32767" attributes="0"/>
<Component id="txtBattlefieldImagePath" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="btnBrowseBackgroundImage" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseBattlefieldImage" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="cbUseRandomBattleImage" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="cbUseDefaultBattleImage" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="cbUseDefaultBackground" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="cbUseDefaultBackground" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtBackgroundImagePath" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseBackgroundImage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cbUseDefaultBattleImage" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cbUseRandomBattleImage" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtBattlefieldImagePath" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseBattlefieldImage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="cbUseDefaultBackground">
<Properties>
<Property name="text" type="java.lang.String" value="Use default image"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseDefaultBackgroundActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtBackgroundImagePath">
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtBackgroundImagePathActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseBackgroundImage">
<Properties>
<Property name="text" type="java.lang.String" value="Browse..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseBackgroundImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtBattlefieldImagePath">
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtBattlefieldImagePathActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseBattlefieldImage">
<Properties>
<Property name="text" type="java.lang.String" value="Browse..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseBattlefieldImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbUseDefaultBattleImage">
<Properties>
<Property name="text" type="java.lang.String" value="Use default battlefield image"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseDefaultBattleImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbUseRandomBattleImage">
<Properties>
<Property name="text" type="java.lang.String" value="Select random battlefield image"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseRandomBattleImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel14">
<Properties>
<Property name="text" type="java.lang.String" value="Background:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel15">
<Properties>
<Property name="text" type="java.lang.String" value="Battlefield:"/>
</Properties> </Properties>
</Component> </Component>
</SubComponents> </SubComponents>
@ -4696,6 +4541,121 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="panelBackgroundImages">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Background images">
<Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="cbUseDefaultBackground" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="txtBackgroundImagePath" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnBrowseBackgroundImage" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="cbUseRandomBattleImage" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="txtBattlefieldImagePath" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnBrowseBattlefieldImage" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="cbUseDefaultBattleImage" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="cbUseDefaultBattleImage" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="cbUseDefaultBackground" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtBackgroundImagePath" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseBackgroundImage" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="cbUseRandomBattleImage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtBattlefieldImagePath" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnBrowseBattlefieldImage" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="cbUseDefaultBackground">
<Properties>
<Property name="text" type="java.lang.String" value="Use default location for backgrounds"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseDefaultBackgroundActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtBackgroundImagePath">
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtBackgroundImagePathActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseBackgroundImage">
<Properties>
<Property name="text" type="java.lang.String" value="Browse..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseBackgroundImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtBattlefieldImagePath">
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtBattlefieldImagePathActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseBattlefieldImage">
<Properties>
<Property name="text" type="java.lang.String" value="Browse..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBrowseBattlefieldImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbUseDefaultBattleImage">
<Properties>
<Property name="text" type="java.lang.String" value="Use default battlefield image"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseDefaultBattleImageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbUseRandomBattleImage">
<Properties>
<Property name="text" type="java.lang.String" value="Use random background"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseRandomBattleImageActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="tabSounds"> <Container class="javax.swing.JPanel" name="tabSounds">
@ -4891,7 +4851,7 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="avatarPane" pref="620" max="32767" attributes="0"/> <Component id="avatarPane" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -5802,7 +5762,7 @@
<Component id="jLabel17" min="-2" max="-2" attributes="0"/> <Component id="jLabel17" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace pref="251" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -5811,7 +5771,7 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lblURLServerList" max="32767" attributes="0"/> <Component id="lblURLServerList" max="32767" attributes="0"/>
<Component id="txtURLServerList" pref="28" max="32767" attributes="0"/> <Component id="txtURLServerList" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel17" min="-2" max="-2" attributes="0"/> <Component id="jLabel17" min="-2" max="-2" attributes="0"/>
@ -6068,7 +6028,7 @@
</Group> </Group>
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="controlsDescriptionLabel" pref="481" max="32767" attributes="0"/> <Component id="controlsDescriptionLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>

View file

@ -78,7 +78,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_CARD_IMAGES_USE_DEFAULT = "cardImagesUseDefault"; public static final String KEY_CARD_IMAGES_USE_DEFAULT = "cardImagesUseDefault";
public static final String KEY_CARD_IMAGES_PATH = "cardImagesPath"; public static final String KEY_CARD_IMAGES_PATH = "cardImagesPath";
public static final String KEY_CARD_IMAGES_THREADS = "cardImagesThreads"; public static final String KEY_CARD_IMAGES_THREADS = "cardImagesThreads";
public static final String KEY_CARD_IMAGES_CHECK = "cardImagesCheck";
public static final String KEY_CARD_IMAGES_SAVE_TO_ZIP = "cardImagesSaveToZip"; public static final String KEY_CARD_IMAGES_SAVE_TO_ZIP = "cardImagesSaveToZip";
public static final String KEY_CARD_IMAGES_PREF_LANGUAGE = "cardImagesPreferedImageLaguage"; public static final String KEY_CARD_IMAGES_PREF_LANGUAGE = "cardImagesPreferedImageLaguage";
@ -468,12 +467,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbUseDefaultImageFolder = new javax.swing.JCheckBox(); cbUseDefaultImageFolder = new javax.swing.JCheckBox();
txtImageFolderPath = new javax.swing.JTextField(); txtImageFolderPath = new javax.swing.JTextField();
btnBrowseImageLocation = new javax.swing.JButton(); btnBrowseImageLocation = new javax.swing.JButton();
cbCheckForNewImages = new javax.swing.JCheckBox();
cbSaveToZipFiles = new javax.swing.JCheckBox(); cbSaveToZipFiles = new javax.swing.JCheckBox();
cbPreferedImageLanguage = new javax.swing.JComboBox<>(); cbPreferedImageLanguage = new javax.swing.JComboBox<>();
labelPreferedImageLanguage = new javax.swing.JLabel(); labelPreferedImageLanguage = new javax.swing.JLabel();
labelNumberOfDownloadThreads = new javax.swing.JLabel(); labelNumberOfDownloadThreads = new javax.swing.JLabel();
cbNumberOfDownloadThreads = new javax.swing.JComboBox(); cbNumberOfDownloadThreads = new javax.swing.JComboBox();
labelHint1 = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
cbCardRenderImageFallback = new javax.swing.JCheckBox();
cbCardRenderShowReminderText = new javax.swing.JCheckBox();
cbCardRenderHideSetSymbol = new javax.swing.JCheckBox();
panelBackgroundImages = new javax.swing.JPanel(); panelBackgroundImages = new javax.swing.JPanel();
cbUseDefaultBackground = new javax.swing.JCheckBox(); cbUseDefaultBackground = new javax.swing.JCheckBox();
txtBackgroundImagePath = new javax.swing.JTextField(); txtBackgroundImagePath = new javax.swing.JTextField();
@ -482,12 +485,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
btnBrowseBattlefieldImage = new javax.swing.JButton(); btnBrowseBattlefieldImage = new javax.swing.JButton();
cbUseDefaultBattleImage = new javax.swing.JCheckBox(); cbUseDefaultBattleImage = new javax.swing.JCheckBox();
cbUseRandomBattleImage = new javax.swing.JCheckBox(); cbUseRandomBattleImage = new javax.swing.JCheckBox();
jLabel14 = new javax.swing.JLabel();
jLabel15 = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
cbCardRenderImageFallback = new javax.swing.JCheckBox();
cbCardRenderShowReminderText = new javax.swing.JCheckBox();
cbCardRenderHideSetSymbol = new javax.swing.JCheckBox();
tabSounds = new javax.swing.JPanel(); tabSounds = new javax.swing.JPanel();
sounds_clips = new javax.swing.JPanel(); sounds_clips = new javax.swing.JPanel();
cbEnableGameSounds = new javax.swing.JCheckBox(); cbEnableGameSounds = new javax.swing.JCheckBox();
@ -872,7 +869,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(main_battlefield, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(main_battlefield, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(39, Short.MAX_VALUE))
); );
main_card.getAccessibleContext().setAccessibleName("Game panel"); main_card.getAccessibleContext().setAccessibleName("Game panel");
@ -1535,7 +1532,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(checkBoxEndTurnOthers)) .add(checkBoxEndTurnOthers))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(phases_stopSettings, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(phases_stopSettings, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(160, Short.MAX_VALUE)) .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
tabsPanel.addTab("Phases & Priority", tabPhases); tabsPanel.addTab("Phases & Priority", tabPhases);
@ -1558,13 +1555,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
}); });
cbCheckForNewImages.setText("Check for new images on startup");
cbCheckForNewImages.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbCheckForNewImagesActionPerformed(evt);
}
});
cbSaveToZipFiles.setText("Store images in zip files"); cbSaveToZipFiles.setText("Store images in zip files");
cbSaveToZipFiles.addActionListener(new java.awt.event.ActionListener() { cbSaveToZipFiles.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -1575,7 +1565,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbPreferedImageLanguage.setMaximumRowCount(20); cbPreferedImageLanguage.setMaximumRowCount(20);
cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"}));
labelPreferedImageLanguage.setText("Prefered image language:"); labelPreferedImageLanguage.setText("Default images language:");
labelPreferedImageLanguage.setFocusable(false); labelPreferedImageLanguage.setFocusable(false);
labelNumberOfDownloadThreads.setText("Number of download threads:"); labelNumberOfDownloadThreads.setText("Number of download threads:");
@ -1583,6 +1573,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbNumberOfDownloadThreads.setMaximumRowCount(20); cbNumberOfDownloadThreads.setMaximumRowCount(20);
cbNumberOfDownloadThreads.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); cbNumberOfDownloadThreads.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"}));
labelHint1.setText("(change it to 1-3 if image source bans your IP for too many connections)");
org.jdesktop.layout.GroupLayout panelCardImagesLayout = new org.jdesktop.layout.GroupLayout(panelCardImages); org.jdesktop.layout.GroupLayout panelCardImagesLayout = new org.jdesktop.layout.GroupLayout(panelCardImages);
panelCardImages.setLayout(panelCardImagesLayout); panelCardImages.setLayout(panelCardImagesLayout);
panelCardImagesLayout.setHorizontalGroup( panelCardImagesLayout.setHorizontalGroup(
@ -1590,158 +1582,46 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createSequentialGroup()
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createSequentialGroup()
.addContainerGap() .add(cbUseDefaultImageFolder)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(txtImageFolderPath) .add(txtImageFolderPath)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(btnBrowseImageLocation)) .add(btnBrowseImageLocation))
.add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createSequentialGroup()
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) .add(cbSaveToZipFiles)
.add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createSequentialGroup()
.add(cbCheckForNewImages) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(147, 147, 147))
.add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(panelCardImagesLayout.createSequentialGroup()
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
.add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createSequentialGroup()
.addContainerGap()
.add(labelPreferedImageLanguage))
.add(org.jdesktop.layout.GroupLayout.LEADING, cbSaveToZipFiles))
.add(20, 20, 20)
.add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(panelCardImagesLayout.createSequentialGroup()
.addContainerGap()
.add(labelNumberOfDownloadThreads) .add(labelNumberOfDownloadThreads)
.add(labelPreferedImageLanguage))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(cbUseDefaultImageFolder)) .add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(0, 391, Short.MAX_VALUE))) .add(panelCardImagesLayout.createSequentialGroup()
.add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(labelHint1)))))
.add(0, 0, Short.MAX_VALUE)))
.addContainerGap()) .addContainerGap())
); );
panelCardImagesLayout.setVerticalGroup( panelCardImagesLayout.setVerticalGroup(
panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createSequentialGroup()
.add(cbUseDefaultImageFolder)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(cbUseDefaultImageFolder)
.add(txtImageFolderPath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(txtImageFolderPath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(btnBrowseImageLocation)) .add(btnBrowseImageLocation))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(cbCheckForNewImages)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cbSaveToZipFiles) .add(cbSaveToZipFiles)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(labelNumberOfDownloadThreads) .add(labelNumberOfDownloadThreads)
.add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(labelHint1))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(labelPreferedImageLanguage)
.add(labelPreferedImageLanguage))) .add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
);
panelBackgroundImages.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Background images"));
cbUseDefaultBackground.setText("Use default image");
cbUseDefaultBackground.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseDefaultBackgroundActionPerformed(evt);
}
});
txtBackgroundImagePath.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtBackgroundImagePathActionPerformed(evt);
}
});
btnBrowseBackgroundImage.setText("Browse...");
btnBrowseBackgroundImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnBrowseBackgroundImageActionPerformed(evt);
}
});
txtBattlefieldImagePath.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtBattlefieldImagePathActionPerformed(evt);
}
});
btnBrowseBattlefieldImage.setText("Browse...");
btnBrowseBattlefieldImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnBrowseBattlefieldImageActionPerformed(evt);
}
});
cbUseDefaultBattleImage.setText("Use default battlefield image");
cbUseDefaultBattleImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseDefaultBattleImageActionPerformed(evt);
}
});
cbUseRandomBattleImage.setText("Select random battlefield image");
cbUseRandomBattleImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseRandomBattleImageActionPerformed(evt);
}
});
jLabel14.setText("Background:");
jLabel15.setText("Battlefield:");
org.jdesktop.layout.GroupLayout panelBackgroundImagesLayout = new org.jdesktop.layout.GroupLayout(panelBackgroundImages);
panelBackgroundImages.setLayout(panelBackgroundImagesLayout);
panelBackgroundImagesLayout.setHorizontalGroup(
panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(19, 19, 19)
.add(jLabel14))
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(25, 25, 25)
.add(jLabel15)))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(txtBackgroundImagePath)
.add(txtBattlefieldImagePath))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, btnBrowseBackgroundImage)
.add(org.jdesktop.layout.GroupLayout.TRAILING, btnBrowseBattlefieldImage)))
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(cbUseRandomBattleImage)
.add(cbUseDefaultBattleImage)
.add(cbUseDefaultBackground))
.add(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
panelBackgroundImagesLayout.setVerticalGroup(
panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.addContainerGap()
.add(cbUseDefaultBackground)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(txtBackgroundImagePath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(btnBrowseBackgroundImage)
.add(jLabel14))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(cbUseDefaultBattleImage)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(cbUseRandomBattleImage)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(txtBattlefieldImagePath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(btnBrowseBattlefieldImage)
.add(jLabel15)))
); );
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card styles (restart xmage to apply new settings)")); jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card styles (restart xmage to apply new settings)"));
@ -1789,6 +1669,95 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(0, 0, Short.MAX_VALUE)) .add(0, 0, Short.MAX_VALUE))
); );
panelBackgroundImages.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Background images"));
cbUseDefaultBackground.setText("Use default location for backgrounds");
cbUseDefaultBackground.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseDefaultBackgroundActionPerformed(evt);
}
});
txtBackgroundImagePath.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtBackgroundImagePathActionPerformed(evt);
}
});
btnBrowseBackgroundImage.setText("Browse...");
btnBrowseBackgroundImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnBrowseBackgroundImageActionPerformed(evt);
}
});
txtBattlefieldImagePath.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtBattlefieldImagePathActionPerformed(evt);
}
});
btnBrowseBattlefieldImage.setText("Browse...");
btnBrowseBattlefieldImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnBrowseBattlefieldImageActionPerformed(evt);
}
});
cbUseDefaultBattleImage.setText("Use default battlefield image");
cbUseDefaultBattleImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseDefaultBattleImageActionPerformed(evt);
}
});
cbUseRandomBattleImage.setText("Use random background");
cbUseRandomBattleImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseRandomBattleImageActionPerformed(evt);
}
});
org.jdesktop.layout.GroupLayout panelBackgroundImagesLayout = new org.jdesktop.layout.GroupLayout(panelBackgroundImages);
panelBackgroundImages.setLayout(panelBackgroundImagesLayout);
panelBackgroundImagesLayout.setHorizontalGroup(
panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(cbUseDefaultBackground)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(txtBackgroundImagePath)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(btnBrowseBackgroundImage))
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(cbUseRandomBattleImage)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(txtBattlefieldImagePath)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(btnBrowseBattlefieldImage))
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(cbUseDefaultBattleImage)
.add(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
panelBackgroundImagesLayout.setVerticalGroup(
panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelBackgroundImagesLayout.createSequentialGroup()
.add(cbUseDefaultBattleImage)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(cbUseDefaultBackground)
.add(txtBackgroundImagePath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(btnBrowseBackgroundImage))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(cbUseRandomBattleImage)
.add(txtBattlefieldImagePath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(btnBrowseBattlefieldImage))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
org.jdesktop.layout.GroupLayout tabImagesLayout = new org.jdesktop.layout.GroupLayout(tabImages); org.jdesktop.layout.GroupLayout tabImagesLayout = new org.jdesktop.layout.GroupLayout(tabImages);
tabImages.setLayout(tabImagesLayout); tabImages.setLayout(tabImagesLayout);
tabImagesLayout.setHorizontalGroup( tabImagesLayout.setHorizontalGroup(
@ -1810,7 +1779,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(panelCardImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(panelCardImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(133, Short.MAX_VALUE)) .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
tabsPanel.addTab("Images", tabImages); tabsPanel.addTab("Images", tabImages);
@ -2385,7 +2354,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabAvatarsLayout.setVerticalGroup( tabAvatarsLayout.setVerticalGroup(
tabAvatarsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) tabAvatarsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(tabAvatarsLayout.createSequentialGroup() .add(tabAvatarsLayout.createSequentialGroup()
.add(avatarPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 620, Short.MAX_VALUE) .add(avatarPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap()) .addContainerGap())
); );
@ -2420,14 +2389,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(connection_serversLayout.createSequentialGroup() .add(connection_serversLayout.createSequentialGroup()
.add(141, 141, 141) .add(141, 141, 141)
.add(jLabel17))) .add(jLabel17)))
.addContainerGap(251, Short.MAX_VALUE)) .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
connection_serversLayout.setVerticalGroup( connection_serversLayout.setVerticalGroup(
connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(connection_serversLayout.createSequentialGroup() .add(connection_serversLayout.createSequentialGroup()
.add(connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false) .add(connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(lblURLServerList, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(lblURLServerList, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(txtURLServerList, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)) .add(txtURLServerList, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jLabel17)) .add(jLabel17))
); );
@ -2663,7 +2632,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(keyToggleRecordMacro, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(keyToggleRecordMacro, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(keySwitchChat, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) .add(keySwitchChat, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(controlsDescriptionLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE) .add(controlsDescriptionLabel)
.addContainerGap()) .addContainerGap())
); );
tabControlsLayout.setVerticalGroup( tabControlsLayout.setVerticalGroup(
@ -2749,7 +2718,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .add(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(org.jdesktop.layout.GroupLayout.LEADING, tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.LEADING, tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@ -2763,7 +2732,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup() .add(layout.createSequentialGroup()
.add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(tabsPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 554, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(saveButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 30, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(saveButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 30, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
@ -2892,7 +2861,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
// images // images
save(prefs, dialog.cbUseDefaultImageFolder, KEY_CARD_IMAGES_USE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbUseDefaultImageFolder, KEY_CARD_IMAGES_USE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY);
saveImagesPath(prefs); saveImagesPath(prefs);
save(prefs, dialog.cbCheckForNewImages, KEY_CARD_IMAGES_CHECK, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbNumberOfDownloadThreads, KEY_CARD_IMAGES_THREADS); save(prefs, dialog.cbNumberOfDownloadThreads, KEY_CARD_IMAGES_THREADS);
save(prefs, dialog.cbPreferedImageLanguage, KEY_CARD_IMAGES_PREF_LANGUAGE); save(prefs, dialog.cbPreferedImageLanguage, KEY_CARD_IMAGES_PREF_LANGUAGE);
@ -3198,31 +3166,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_cbCardRenderShowReminderTextActionPerformed }//GEN-LAST:event_cbCardRenderShowReminderTextActionPerformed
private void cbSaveToZipFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSaveToZipFilesActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbSaveToZipFilesActionPerformed
private void cbCheckForNewImagesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCheckForNewImagesActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbCheckForNewImagesActionPerformed
private void btnBrowseImageLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowseImageLocationActionPerformed
int returnVal = fc.showOpenDialog(PreferencesDialog.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
txtImageFolderPath.setText(file.getAbsolutePath());
}
}//GEN-LAST:event_btnBrowseImageLocationActionPerformed
private void cbUseDefaultImageFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseDefaultImageFolderActionPerformed
if (cbUseDefaultImageFolder.isSelected()) {
useDefaultPath();
} else {
useConfigurablePath();
}
}//GEN-LAST:event_cbUseDefaultImageFolderActionPerformed
private void cbCardRenderHideSetSymbolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderHideSetSymbolActionPerformed private void cbCardRenderHideSetSymbolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderHideSetSymbolActionPerformed
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_cbCardRenderHideSetSymbolActionPerformed }//GEN-LAST:event_cbCardRenderHideSetSymbolActionPerformed
@ -3263,6 +3206,27 @@ public class PreferencesDialog extends javax.swing.JDialog {
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_cbStopBlockWithZeroActionPerformed }//GEN-LAST:event_cbStopBlockWithZeroActionPerformed
private void cbSaveToZipFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSaveToZipFilesActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbSaveToZipFilesActionPerformed
private void btnBrowseImageLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowseImageLocationActionPerformed
int returnVal = fc.showOpenDialog(PreferencesDialog.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
txtImageFolderPath.setText(file.getAbsolutePath());
}
}//GEN-LAST:event_btnBrowseImageLocationActionPerformed
private void cbUseDefaultImageFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseDefaultImageFolderActionPerformed
if (cbUseDefaultImageFolder.isSelected()) {
useDefaultPath();
} else {
useConfigurablePath();
}
}//GEN-LAST:event_cbUseDefaultImageFolderActionPerformed
private void showProxySettings() { private void showProxySettings() {
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem(); Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
switch (proxyType) { switch (proxyType) {
@ -3446,7 +3410,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
dialog.txtImageFolderPath.setText(path); dialog.txtImageFolderPath.setText(path);
updateCache(KEY_CARD_IMAGES_PATH, path); updateCache(KEY_CARD_IMAGES_PATH, path);
} }
load(prefs, dialog.cbCheckForNewImages, KEY_CARD_IMAGES_CHECK, "true");
load(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true"); load(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true");
dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10")); dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10"));
dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode())); dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode()));
@ -3751,6 +3714,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
} }
public static int getRenderMode() {
if (getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_FALLBACK, "false").equals("false")) {
return 0; // mtgo
} else {
return 1; // image
}
}
private static int getDefaultControlMofier(String key) { private static int getDefaultControlMofier(String key) {
switch (key) { switch (key) {
default: default:
@ -3964,7 +3935,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox cbCardRenderHideSetSymbol; private javax.swing.JCheckBox cbCardRenderHideSetSymbol;
private javax.swing.JCheckBox cbCardRenderImageFallback; private javax.swing.JCheckBox cbCardRenderImageFallback;
private javax.swing.JCheckBox cbCardRenderShowReminderText; private javax.swing.JCheckBox cbCardRenderShowReminderText;
private javax.swing.JCheckBox cbCheckForNewImages;
private javax.swing.JCheckBox cbConfirmEmptyManaPool; private javax.swing.JCheckBox cbConfirmEmptyManaPool;
private javax.swing.JCheckBox cbDraftLogAutoSave; private javax.swing.JCheckBox cbDraftLogAutoSave;
private javax.swing.JCheckBox cbEnableBattlefieldBGM; private javax.swing.JCheckBox cbEnableBattlefieldBGM;
@ -4014,8 +3984,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JPanel guiSizeBasic; private javax.swing.JPanel guiSizeBasic;
private javax.swing.JPanel guiSizeGame; private javax.swing.JPanel guiSizeGame;
private javax.swing.JLabel jLabel11; private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel15;
private javax.swing.JLabel jLabel16; private javax.swing.JLabel jLabel16;
private javax.swing.JLabel jLabel17; private javax.swing.JLabel jLabel17;
private javax.swing.JLabel jLabelBeforeCombat; private javax.swing.JLabel jLabelBeforeCombat;
@ -4076,6 +4044,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JLabel labelEndStep; private javax.swing.JLabel labelEndStep;
private javax.swing.JLabel labelEnlargedImageSize; private javax.swing.JLabel labelEnlargedImageSize;
private javax.swing.JLabel labelGameFeedback; private javax.swing.JLabel labelGameFeedback;
private javax.swing.JLabel labelHint1;
private javax.swing.JLabel labelMainStep; private javax.swing.JLabel labelMainStep;
private javax.swing.JLabel labelNextTurn; private javax.swing.JLabel labelNextTurn;
private javax.swing.JLabel labelNumberOfDownloadThreads; private javax.swing.JLabel labelNumberOfDownloadThreads;

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="578" max="32767" attributes="0"/>
<Component id="buttonCancel" min="-2" pref="100" max="-2" attributes="0"/>
</Group>
<Component id="cardsPanel" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="buttonReloadCards" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelRenderMode" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboRenderMode" min="-2" pref="131" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelSize" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="sliderSize" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="buttonReloadCards" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelRenderMode" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboRenderMode" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelSize" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="sliderSize" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="cardsPanel" pref="421" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="buttonCancel" min="-2" pref="30" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="buttonCancel">
<Properties>
<Property name="text" type="java.lang.String" value="Close"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonCancelActionPerformed"/>
</Events>
</Component>
<Component class="mage.client.cards.CardArea" name="cardsPanel">
</Component>
<Component class="javax.swing.JButton" name="buttonReloadCards">
<Properties>
<Property name="text" type="java.lang.String" value="Reload cards"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonReloadCardsActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="labelRenderMode">
<Properties>
<Property name="text" type="java.lang.String" value="Render mode:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboRenderMode">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="2">
<StringItem index="0" value="MTGO"/>
<StringItem index="1" value="Image"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="comboRenderModeItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JSlider" name="sliderSize">
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="sliderSizeStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="labelSize">
<Properties>
<Property name="text" type="java.lang.String" value="Card size:"/>
</Properties>
</Component>
</SubComponents>
</Form>

View file

@ -0,0 +1,336 @@
package mage.client.dialog;
import mage.cards.Card;
import mage.cards.CardGraphicInfo;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.decks.Deck;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.util.GUISizeHelper;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.game.GameImpl;
import mage.game.command.Emblem;
import mage.game.command.Plane;
import mage.game.command.emblems.AjaniAdversaryOfTyrantsEmblem;
import mage.game.command.planes.AkoumPlane;
import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan;
import mage.game.mulligan.VancouverMulligan;
import mage.game.permanent.PermanentCard;
import mage.players.Player;
import mage.players.StubPlayer;
import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author JayDi85
*/
public class TestCardRenderDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(TestCardRenderDialog.class);
float cardSizeMod = 1.0f;
public TestCardRenderDialog() {
initComponents();
}
public void showDialog() {
this.setModal(false);
getRootPane().setDefaultButton(buttonCancel);
reloadCards();
// windows settings
MageFrame.getDesktop().remove(this);
if (this.isModal()) {
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
} else {
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
}
this.makeWindowCentered();
// Close on "ESC"
registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
this.setVisible(true);
}
private void onCancel() {
this.removeDialog();
}
private PermanentView createCard(Game game, UUID controllerId, String code, String cardNumber, int power, int toughness, int damage) {
CardInfo cardInfo = CardRepository.instance.findCard(code, cardNumber);
ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code);
CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(),
new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt()));
Card card = CardImpl.createCard(cardInfo.getClassName(), testSet);
Set<Card> cardsList = new HashSet<>();
cardsList.add(card);
game.loadCards(cardsList, controllerId);
PermanentCard perm = new PermanentCard(card, controllerId, game);
if (damage > 0) perm.damage(damage, controllerId, game);
if (power > 0) perm.getPower().setValue(power);
if (toughness > 0) perm.getToughness().setValue(toughness);
perm.removeSummoningSickness();
if (perm.isTransformable()) {
perm.setTransformed(true);
}
PermanentView cardView = new PermanentView(perm, card, controllerId, game);
cardView.setInViewerOnly(true);
return cardView;
}
private AbilityView createEmblem(Emblem emblem) {
AbilityView emblemView = new AbilityView(emblem.getAbilities().get(0), emblem.getName(), new CardView(new EmblemView(emblem)));
emblemView.setName(emblem.getName());
return emblemView;
}
private AbilityView createPlane(Plane plane) {
AbilityView planeView = new AbilityView(plane.getAbilities().get(0), plane.getName(), new CardView(new PlaneView(plane)));
planeView.setName(plane.getName());
return planeView;
}
private void reloadCards() {
cardsPanel.cleanUp();
cardsPanel.setCustomRenderMode(comboRenderMode.getSelectedIndex());
Game game = new TestGame(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, new VancouverMulligan(0), 20);
Player player = new StubPlayer("player1", RangeOfInfluence.ALL);
Deck deck = new Deck();
game.addPlayer(player, deck);
BigCard big = new BigCard();
CardsView view = new CardsView();
CardView card;
card = createCard(game, player.getId(), "RNA", "263", 0, 0, 0); // mountain
view.put(card.getId(), card);
card = createCard(game, player.getId(), "RNA", "185", 0, 0, 0); // Judith, the Scourge Diva
view.put(card.getId(), card);
card = createCard(game, player.getId(), "RNA", "78", 125, 89, 0); // Noxious Groodion
view.put(card.getId(), card);
card = createCard(game, player.getId(), "RNA", "14", 3, 5, 2); // Knight of Sorrows
view.put(card.getId(), card);
card = createCard(game, player.getId(), "DKA", "140", 5, 2, 2); // Huntmaster of the Fells, transforms
view.put(card.getId(), card);
card = createCard(game, player.getId(), "RNA", "221", 0, 0, 0); // Bedeck // Bedazzle
view.put(card.getId(), card);
card = createCard(game, player.getId(), "XLN", "234", 0, 0, 0); // Conqueror's Galleon
view.put(card.getId(), card);
card = createEmblem(new AjaniAdversaryOfTyrantsEmblem()); // Emblem Ajani
view.put(card.getId(), card);
card = createPlane(new AkoumPlane()); // Plane - Akoum
view.put(card.getId(), card);
cardsPanel.setCustomCardSize(new Dimension(getCardWidth(), getCardHeight()));
cardsPanel.changeGUISize();
cardsPanel.loadCards(view, big, game.getId());
}
private int getCardWidth() {
if (GUISizeHelper.editorCardDimension == null) {
return 200;
}
return (int) (GUISizeHelper.editorCardDimension.width * cardSizeMod);
}
private int getCardHeight() {
return (int) (1.4 * getCardWidth());
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
buttonCancel = new javax.swing.JButton();
cardsPanel = new mage.client.cards.CardArea();
buttonReloadCards = new javax.swing.JButton();
labelRenderMode = new javax.swing.JLabel();
comboRenderMode = new javax.swing.JComboBox<>();
sliderSize = new javax.swing.JSlider();
labelSize = new javax.swing.JLabel();
buttonCancel.setText("Close");
buttonCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonCancelActionPerformed(evt);
}
});
buttonReloadCards.setText("Reload cards");
buttonReloadCards.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonReloadCardsActionPerformed(evt);
}
});
labelRenderMode.setText("Render mode:");
comboRenderMode.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"MTGO", "Image"}));
comboRenderMode.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
comboRenderModeItemStateChanged(evt);
}
});
sliderSize.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderSizeStateChanged(evt);
}
});
labelSize.setText("Card size:");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 578, Short.MAX_VALUE)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(cardsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(buttonReloadCards)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelRenderMode)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelSize)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(buttonReloadCards)
.addComponent(labelRenderMode)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelSize))
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cardsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 421, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void buttonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCancelActionPerformed
onCancel();
}//GEN-LAST:event_buttonCancelActionPerformed
private void buttonReloadCardsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReloadCardsActionPerformed
reloadCards();
}//GEN-LAST:event_buttonReloadCardsActionPerformed
private void comboRenderModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboRenderModeItemStateChanged
reloadCards();
}//GEN-LAST:event_comboRenderModeItemStateChanged
private void sliderSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderSizeStateChanged
// from DragCardGrid
// Fraction in [-1, 1]
float sliderFrac = ((float) (sliderSize.getValue() - 50)) / 50;
// Convert to frac in [0.5, 2.0] exponentially
cardSizeMod = (float) Math.pow(2, sliderFrac);
reloadCards();
}//GEN-LAST:event_sliderSizeStateChanged
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonCancel;
private javax.swing.JButton buttonReloadCards;
private mage.client.cards.CardArea cardsPanel;
private javax.swing.JComboBox<String> comboRenderMode;
private javax.swing.JLabel labelRenderMode;
private javax.swing.JLabel labelSize;
private javax.swing.JSlider sliderSize;
// End of variables declaration//GEN-END:variables
}
class TestGame extends GameImpl {
private int numPlayers;
public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife);
}
public TestGame(final TestGame game) {
super(game);
this.numPlayers = game.numPlayers;
}
@Override
public MatchType getGameType() {
return new TestGameType();
}
@Override
public int getNumPlayers() {
return numPlayers;
}
@Override
public TestGame copy() {
return new TestGame(this);
}
}
class TestGameType extends MatchType {
public TestGameType() {
this.name = "Test Game Type";
this.maxPlayers = 10;
this.minPlayers = 3;
this.numTeams = 0;
this.useAttackOption = true;
this.useRange = true;
this.sideboardingAllowed = true;
}
protected TestGameType(final TestGameType matchType) {
super(matchType);
}
@Override
public TestGameType copy() {
return new TestGameType(this);
}
}

View file

@ -200,9 +200,11 @@ public class WhatsNewDialog extends MageDialog {
}.getType(); }.getType();
try { try {
httpCookies = gson.fromJson(sourceValue, type); httpCookies = gson.fromJson(sourceValue, type);
if (httpCookies != null) {
for (HttpCookie cookie : httpCookies) { for (HttpCookie cookie : httpCookies) {
store.add(URI.create(cookie.getDomain()), cookie); store.add(URI.create(cookie.getDomain()), cookie);
} }
}
} catch (Exception e) { } catch (Exception e) {
logger.error("Wrong news page cookies", e); logger.error("Wrong news page cookies", e);
} }

View file

@ -136,7 +136,7 @@ public class DraftPanel extends javax.swing.JPanel {
if (isLogging()) { if (isLogging()) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".txt"; String logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".draft";
draftLogger = new DraftPickLogger(new File("gamelogs"), logFilename); draftLogger = new DraftPickLogger(new File("gamelogs"), logFilename);
} else { } else {
draftLogger = new DraftPickLogger(); draftLogger = new DraftPickLogger();

View file

@ -5,44 +5,35 @@
* *
* Created on 10-Jan-2010, 10:43:14 PM * Created on 10-Jan-2010, 10:43:14 PM
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Component; import mage.cards.MagePermanent;
import java.awt.Dimension; import mage.client.cards.BigCard;
import java.awt.event.ComponentAdapter; import mage.client.cards.Permanent;
import java.awt.event.ComponentEvent; import mage.client.dialog.PreferencesDialog;
import java.util.ArrayList; import mage.client.plugins.impl.Plugins;
import java.util.HashMap; import mage.client.util.Config;
import java.util.HashSet; import mage.client.util.GUISizeHelper;
import java.util.Iterator; import mage.client.util.audio.AudioManager;
import java.util.LinkedHashMap; import mage.client.util.layout.CardLayoutStrategy;
import java.util.List; import mage.client.util.layout.impl.OldCardLayoutStrategy;
import java.util.Map; import mage.view.CounterView;
import java.util.Map.Entry; import mage.view.PermanentView;
import java.util.Set;
import java.util.UUID;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import mage.cards.MagePermanent;
import mage.client.cards.BigCard;
import mage.client.cards.Permanent;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Config;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.layout.CardLayoutStrategy;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
import mage.view.CounterView;
import mage.view.PermanentView;
/** import javax.swing.*;
* import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
/**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class BattlefieldPanel extends javax.swing.JLayeredPane { public class BattlefieldPanel extends javax.swing.JLayeredPane {
private final Map<UUID, MagePermanent> permanents = new LinkedHashMap<>(); private final Map<UUID, MagePermanent> permanents = new LinkedHashMap<>();
private UUID gameId; private UUID gameId;
@ -200,7 +191,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
removedCreature = false; removedCreature = false;
for (Iterator<Entry<UUID, MagePermanent>> iterator = permanents.entrySet().iterator(); iterator.hasNext();) { for (Iterator<Entry<UUID, MagePermanent>> iterator = permanents.entrySet().iterator(); iterator.hasNext(); ) {
Entry<UUID, MagePermanent> entry = iterator.next(); Entry<UUID, MagePermanent> entry = iterator.next();
if (!battlefield.containsKey(entry.getKey()) || !battlefield.get(entry.getKey()).isPhasedIn()) { if (!battlefield.containsKey(entry.getKey()) || !battlefield.get(entry.getKey()).isPhasedIn()) {
removePermanent(entry.getKey(), 1); removePermanent(entry.getKey(), 1);
@ -237,7 +228,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
if (cardDimension == null) { if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight()); cardDimension = new Dimension(Config.dimensions.getFrameWidth(), Config.dimensions.getFrameHeight());
} }
final MagePermanent perm = Plugins.instance.getMagePermanent(permanent, bigCard, cardDimension, gameId, true); final MagePermanent perm = Plugins.instance.getMagePermanent(permanent, bigCard, cardDimension, gameId, true, PreferencesDialog.getRenderMode());
permanents.put(permanent.getId(), perm); permanents.put(permanent.getId(), perm);
@ -330,4 +321,4 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
public Map<String, JComponent> getUiComponentsList() { public Map<String, JComponent> getUiComponentsList() {
return uiComponentsList; return uiComponentsList;
} }
} }

View file

@ -1,10 +1,5 @@
package mage.client.plugins; package mage.client.plugins;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.UUID;
import javax.swing.*;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
@ -12,6 +7,12 @@ import mage.client.cards.BigCard;
import mage.view.CardView; import mage.view.CardView;
import mage.view.PermanentView; import mage.view.PermanentView;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.UUID;
public interface MagePlugins { public interface MagePlugins {
void loadPlugins(); void loadPlugins();
@ -22,9 +23,9 @@ public interface MagePlugins {
JComponent updateTablePanel(Map<String, JComponent> ui); JComponent updateTablePanel(Map<String, JComponent> ui);
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, int renderMode);
MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable); MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode);
boolean isThemePluginLoaded(); boolean isThemePluginLoaded();

View file

@ -30,8 +30,8 @@ import java.awt.*;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.*;
import java.util.List; import java.util.List;
import java.util.*;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
@ -154,24 +154,22 @@ public class MageActionCallback implements ActionCallback {
try { try {
final Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); final Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
Component popup2 = MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE); Component popupInfo = MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE);
((CardInfoPane) popupInfo).setCard(data.getCard(), popupContainer);
((CardInfoPane) popup2).setCard(data.getCard(), popupContainer); showPopup(popupContainer, popupInfo);
showPopup(popupContainer, popup2);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.warn(e.getMessage()); LOGGER.error("Can't show card tooltip", e);
Thread.currentThread().interrupt();
} }
} }
public void showPopup(final Component popupContainer, final Component infoPane) throws InterruptedException { public void showPopup(final Component popupContainer, final Component infoPane) throws InterruptedException {
final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
if (!popupTextWindowOpen if (!popupTextWindowOpen || enlargedWindowState != EnlargedWindowState.CLOSED) {
|| enlargedWindowState != EnlargedWindowState.CLOSED) {
return; return;
} }
if (data.getLocationOnScreen() == null) { if (data.getLocationOnScreen() == null) {
data.setLocationOnScreen(data.getComponent().getLocationOnScreen()); data.setLocationOnScreen(data.getComponent().getLocationOnScreen());
} }
@ -365,8 +363,6 @@ public class MageActionCallback implements ActionCallback {
if (!((GamePane) topPane).getGameId().equals(data.getGameId())) { if (!((GamePane) topPane).getGameId().equals(data.getGameId())) {
return; return;
} }
} else if (data.getGameId() != null) {
return;
} }
hideTooltipPopup(); hideTooltipPopup();
@ -383,6 +379,7 @@ public class MageActionCallback implements ActionCallback {
ArrowUtil.drawArrowsForPairedCards(data, parentPoint); ArrowUtil.drawArrowsForPairedCards(data, parentPoint);
ArrowUtil.drawArrowsForBandedCards(data, parentPoint); ArrowUtil.drawArrowsForBandedCards(data, parentPoint);
ArrowUtil.drawArrowsForEnchantPlayers(data, parentPoint); ArrowUtil.drawArrowsForEnchantPlayers(data, parentPoint);
tooltipCard = data.getCard(); tooltipCard = data.getCard();
showTooltipPopup(data, parentComponent, parentPoint); showTooltipPopup(data, parentComponent, parentPoint);
} }
@ -414,13 +411,9 @@ public class MageActionCallback implements ActionCallback {
@Override @Override
public void hideOpenComponents() { public void hideOpenComponents() {
this.hideTooltipPopup(); hideAll(null);
this.hideEnlargedCard();
} }
/**
* Hides the text popup window
*/
public void hideTooltipPopup() { public void hideTooltipPopup() {
this.tooltipCard = null; this.tooltipCard = null;
if (tooltipPopup != null) { if (tooltipPopup != null) {
@ -433,11 +426,11 @@ public class MageActionCallback implements ActionCallback {
if (SessionHandler.getSession() == null) { if (SessionHandler.getSession() == null) {
return; return;
} }
// set enlarged card display to visible = false
Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
popupContainer.setVisible(false); popupContainer.setVisible(false);
} catch (Exception e2) { } catch (InterruptedException e) {
LOGGER.warn("Can't set tooltip to visible = false", e2); LOGGER.error("Can't hide card tooltip", e);
Thread.currentThread().interrupt();
} }
} }

View file

@ -1,12 +1,5 @@
package mage.client.plugins.impl; package mage.client.plugins.impl;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.swing.JComponent;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
@ -27,12 +20,20 @@ import mage.view.PermanentView;
import net.xeoh.plugins.base.PluginManager; import net.xeoh.plugins.base.PluginManager;
import net.xeoh.plugins.base.impl.PluginManagerFactory; import net.xeoh.plugins.base.impl.PluginManagerFactory;
import net.xeoh.plugins.base.util.uri.ClassURI; import net.xeoh.plugins.base.util.uri.ClassURI;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.CardPluginImpl; import org.mage.plugins.card.CardPluginImpl;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
import org.mage.plugins.theme.ThemePluginImpl; import org.mage.plugins.theme.ThemePluginImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
public enum Plugins implements MagePlugins { public enum Plugins implements MagePlugins {
instance; instance;
public static final String PLUGINS_DIRECTORY = "plugins"; public static final String PLUGINS_DIRECTORY = "plugins";
@ -92,24 +93,24 @@ public enum Plugins implements MagePlugins {
} }
@Override @Override
public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage) { public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, int renderMode) {
if (cardPlugin != null) { if (cardPlugin != null) {
mageActionCallback.refreshSession(); mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard); mageActionCallback.setCardPreviewComponent(bigCard);
return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode);
} else { } else {
return new Permanent(card, bigCard, Config.dimensions, gameId); return new Permanent(card, bigCard, Config.dimensions, gameId);
} }
} }
@Override @Override
public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable) { public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode) {
if (cardPlugin != null) { if (cardPlugin != null) {
if (previewable) { if (previewable) {
mageActionCallback.refreshSession(); mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard); mageActionCallback.setCardPreviewComponent(bigCard);
} }
return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode);
} else { } else {
return new Card(card, bigCard, Config.dimensions, gameId); return new Card(card, bigCard, Config.dimensions, gameId);
} }

View file

@ -2,6 +2,7 @@ package mage.client.preference;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.util.Config;
import java.util.Set; import java.util.Set;
import java.util.prefs.BackingStoreException; import java.util.prefs.BackingStoreException;
@ -16,9 +17,13 @@ public final class MagePreferences {
private static final String KEY_PASSWORD = "password"; private static final String KEY_PASSWORD = "password";
private static final String KEY_EMAIL = "email"; private static final String KEY_EMAIL = "email";
private static final String KEY_AUTO_CONNECT = "autoConnect"; private static final String KEY_AUTO_CONNECT = "autoConnect";
private static final String NODE_KEY_IGNORE_LIST = "ignoreListString"; private static final String NODE_KEY_IGNORE_LIST = "ignoreListString";
private static String lastServerAddress = "";
private static int lastServerPort = 0;
private static String lastServerUser = "";
private static String lastServerPassword = "";
private static Preferences prefs() { private static Preferences prefs() {
// TODO: Move MageFrame.prefs to this class. // TODO: Move MageFrame.prefs to this class.
return MageFrame.getPreferences(); return MageFrame.getPreferences();
@ -138,4 +143,26 @@ public final class MagePreferences {
return prefs().node(NODE_KEY_IGNORE_LIST).node(serverAddress); return prefs().node(NODE_KEY_IGNORE_LIST).node(serverAddress);
} }
public static void saveLastServer() {
lastServerAddress = getServerAddressWithDefault(Config.serverName);
lastServerPort = getServerPortWithDefault(Config.port);
lastServerUser = getUserName(lastServerAddress);
lastServerPassword = getPassword(lastServerAddress);
}
public static String getLastServerAddress() {
return lastServerAddress.isEmpty() ? getServerAddress() : lastServerAddress;
}
public static int getLastServerPort() {
return lastServerPort == 0 ? getServerPort() : lastServerPort;
}
public static String getLastServerUser() {
return lastServerUser.isEmpty() ? getUserName(getLastServerAddress()) : lastServerUser;
}
public static String getLastServerPassword() {
return lastServerPassword.isEmpty() ? getPassword(getLastServerAddress()) : lastServerPassword;
}
} }

View file

@ -105,7 +105,7 @@ public class TablesPane extends MagePane {
@Override @Override
public void activated() { public void activated() {
tablesPanel.startTasks(); tablesPanel.startUpdateTasks(false);
} }
@Override @Override

View file

@ -43,8 +43,11 @@
<Component id="filterBar2" max="32767" attributes="0"/> <Component id="filterBar2" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="btnQuickStart" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<EmptySpace pref="792" max="32767" attributes="0"/> <Component id="btnQuickStartDuel" min="-2" max="-2" attributes="0"/>
<Component id="btnQuickStartCommander" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="734" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -60,10 +63,16 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="filterBar1" max="32767" attributes="0"/> <Component id="filterBar1" max="32767" attributes="0"/>
<Component id="btnQuickStart" min="-2" max="-2" attributes="0"/> <Component id="btnQuickStartDuel" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filterBar2" max="32767" attributes="0"/> <Component id="filterBar2" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="btnQuickStartCommander" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -506,15 +515,26 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JButton" name="btnQuickStart"> <Component class="javax.swing.JButton" name="btnQuickStartDuel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Quick Start"/> <Property name="text" type="java.lang.String" value="Quick start duel"/>
<Property name="focusable" type="boolean" value="false"/> <Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/> <Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/> <Property name="verticalTextPosition" type="int" value="3"/>
</Properties> </Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuickStartActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuickStartDuelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnQuickStartCommander">
<Properties>
<Property name="text" type="java.lang.String" value="Quick start commander"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuickStartCommanderActionPerformed"/>
</Events> </Events>
</Component> </Component>
</SubComponents> </SubComponents>

View file

@ -1,5 +1,6 @@
package mage.client.table; package mage.client.table;
import mage.cards.decks.DeckCardLists;
import mage.cards.decks.importer.DeckImporter; import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.SessionHandler; import mage.client.SessionHandler;
@ -16,6 +17,8 @@ import mage.constants.*;
import mage.game.match.MatchOptions; import mage.game.match.MatchOptions;
import mage.players.PlayerType; import mage.players.PlayerType;
import mage.remote.MageRemoteException; import mage.remote.MageRemoteException;
import mage.util.DeckUtil;
import mage.util.RandomUtil;
import mage.view.MatchView; import mage.view.MatchView;
import mage.view.RoomUsersView; import mage.view.RoomUsersView;
import mage.view.TableView; import mage.view.TableView;
@ -65,6 +68,7 @@ public class TablesPanel extends javax.swing.JPanel {
public static final int REFRESH_ACTIVE_TABLES_SECS = 5; public static final int REFRESH_ACTIVE_TABLES_SECS = 5;
public static final int REFRESH_FINISHED_TABLES_SECS = 30; public static final int REFRESH_FINISHED_TABLES_SECS = 30;
public static final int REFRESH_PLAYERS_SECS = 10; public static final int REFRESH_PLAYERS_SECS = 10;
public static final double REFRESH_TIMEOUTS_INCREASE_FACTOR = 0.8; // can increase timeouts by 80% (0.8)
private final TablesTableModel tableModel; private final TablesTableModel tableModel;
private final MatchesTableModel matchesModel; private final MatchesTableModel matchesModel;
@ -211,6 +215,12 @@ public class TablesPanel extends javax.swing.JPanel {
return res; return res;
} }
public static int randomizeTimout(int minTimout) {
// randomize timeouts to fix calls waves -- slow server can creates queue and moves all clients to same call window
int increase = (int) (minTimout * REFRESH_TIMEOUTS_INCREASE_FACTOR);
return minTimout + RandomUtil.nextInt(increase);
}
/** /**
* Creates new form TablesPanel * Creates new form TablesPanel
@ -513,6 +523,7 @@ public class TablesPanel extends javax.swing.JPanel {
public void cleanUp() { public void cleanUp() {
saveGuiSettings(); saveGuiSettings();
chatPanelMain.cleanUp(); chatPanelMain.cleanUp();
stopTasks();
} }
public void changeGUISize() { public void changeGUISize() {
@ -632,23 +643,31 @@ public class TablesPanel extends javax.swing.JPanel {
} }
} }
public void startTasks() { public void startUpdateTasks(boolean refreshImmediately) {
if (SessionHandler.getSession() != null) { if (SessionHandler.getSession() != null) {
if (updateTablesTask == null || updateTablesTask.isDone()) { // active tables and server messages
if (updateTablesTask == null || updateTablesTask.isDone() || refreshImmediately) {
if (updateTablesTask != null) updateTablesTask.cancel(true);
updateTablesTask = new UpdateTablesTask(roomId, this); updateTablesTask = new UpdateTablesTask(roomId, this);
updateTablesTask.execute(); updateTablesTask.execute();
} }
if (updatePlayersTask == null || updatePlayersTask.isDone()) {
updatePlayersTask = new UpdatePlayersTask(roomId, this.chatPanelMain); // finished tables
updatePlayersTask.execute();
}
if (this.btnStateFinished.isSelected()) { if (this.btnStateFinished.isSelected()) {
if (updateMatchesTask == null || updateMatchesTask.isDone()) { if (updateMatchesTask == null || updateMatchesTask.isDone() || refreshImmediately) {
if (updateMatchesTask != null) updateMatchesTask.cancel(true);
updateMatchesTask = new UpdateMatchesTask(roomId, this); updateMatchesTask = new UpdateMatchesTask(roomId, this);
updateMatchesTask.execute(); updateMatchesTask.execute();
} }
} else if (updateMatchesTask != null) { } else {
updateMatchesTask.cancel(true); if (updateMatchesTask != null) updateMatchesTask.cancel(true);
}
// players list
if (updatePlayersTask == null || updatePlayersTask.isDone() || refreshImmediately) {
if (updatePlayersTask != null) updatePlayersTask.cancel(true);
updatePlayersTask = new UpdatePlayersTask(roomId, this.chatPanelMain);
updatePlayersTask.execute();
} }
} }
} }
@ -669,7 +688,8 @@ public class TablesPanel extends javax.swing.JPanel {
this.roomId = roomId; this.roomId = roomId;
UUID chatRoomId = null; UUID chatRoomId = null;
if (SessionHandler.getSession() != null) { if (SessionHandler.getSession() != null) {
btnQuickStart.setVisible(SessionHandler.isTestMode()); btnQuickStartDuel.setVisible(SessionHandler.isTestMode());
btnQuickStartCommander.setVisible(SessionHandler.isTestMode());
gameChooser.init(); gameChooser.init();
chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null); chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null);
} }
@ -687,7 +707,7 @@ public class TablesPanel extends javax.swing.JPanel {
} }
if (chatRoomId != null) { if (chatRoomId != null) {
this.chatPanelMain.getUserChatPanel().connect(chatRoomId); this.chatPanelMain.getUserChatPanel().connect(chatRoomId);
startTasks(); startUpdateTasks(true);
this.setVisible(true); this.setVisible(true);
this.repaint(); this.repaint();
} else { } else {
@ -695,7 +715,7 @@ public class TablesPanel extends javax.swing.JPanel {
} }
//tableModel.setSession(session); //tableModel.setSession(session);
reloadMessages(); reloadServerMessages();
MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable); MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable);
@ -704,7 +724,7 @@ public class TablesPanel extends javax.swing.JPanel {
} }
protected void reloadMessages() { protected void reloadServerMessages() {
// reload server messages // reload server messages
java.util.List<String> serverMessages = SessionHandler.getServerMessages(); java.util.List<String> serverMessages = SessionHandler.getServerMessages();
synchronized (this) { synchronized (this) {
@ -954,7 +974,8 @@ public class TablesPanel extends javax.swing.JPanel {
jSeparator5 = new javax.swing.JToolBar.Separator(); jSeparator5 = new javax.swing.JToolBar.Separator();
btnOpen = new javax.swing.JToggleButton(); btnOpen = new javax.swing.JToggleButton();
btnPassword = new javax.swing.JToggleButton(); btnPassword = new javax.swing.JToggleButton();
btnQuickStart = new javax.swing.JButton(); btnQuickStartDuel = new javax.swing.JButton();
btnQuickStartCommander = new javax.swing.JButton();
jSplitPane1 = new javax.swing.JSplitPane(); jSplitPane1 = new javax.swing.JSplitPane();
jPanelTables = new javax.swing.JPanel(); jPanelTables = new javax.swing.JPanel();
jSplitPaneTables = new javax.swing.JSplitPane(); jSplitPaneTables = new javax.swing.JSplitPane();
@ -1374,13 +1395,23 @@ public class TablesPanel extends javax.swing.JPanel {
}); });
filterBar2.add(btnPassword); filterBar2.add(btnPassword);
btnQuickStart.setText("Quick Start"); btnQuickStartDuel.setText("Quick start duel");
btnQuickStart.setFocusable(false); btnQuickStartDuel.setFocusable(false);
btnQuickStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); btnQuickStartDuel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnQuickStart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnQuickStartDuel.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnQuickStart.addActionListener(new java.awt.event.ActionListener() { btnQuickStartDuel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
btnQuickStartActionPerformed(evt); btnQuickStartDuelActionPerformed(evt);
}
});
btnQuickStartCommander.setText("Quick start commander");
btnQuickStartCommander.setFocusable(false);
btnQuickStartCommander.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnQuickStartCommander.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnQuickStartCommander.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnQuickStartCommanderActionPerformed(evt);
} }
}); });
@ -1398,8 +1429,10 @@ public class TablesPanel extends javax.swing.JPanel {
.addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnQuickStart) .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addContainerGap(792, Short.MAX_VALUE)) .addComponent(btnQuickStartDuel)
.addComponent(btnQuickStartCommander))
.addContainerGap(734, Short.MAX_VALUE))
); );
jPanelTopLayout.setVerticalGroup( jPanelTopLayout.setVerticalGroup(
jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1412,9 +1445,13 @@ public class TablesPanel extends javax.swing.JPanel {
.addGroup(jPanelTopLayout.createSequentialGroup() .addGroup(jPanelTopLayout.createSequentialGroup()
.addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnQuickStart)) .addComponent(btnQuickStartDuel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanelTopLayout.createSequentialGroup()
.addComponent(btnQuickStartCommander)
.addGap(0, 0, Short.MAX_VALUE)))))
.addContainerGap()) .addContainerGap())
); );
@ -1518,16 +1555,23 @@ public class TablesPanel extends javax.swing.JPanel {
newTournamentDialog.showDialog(roomId); newTournamentDialog.showDialog(roomId);
}//GEN-LAST:event_btnNewTournamentActionPerformed }//GEN-LAST:event_btnNewTournamentActionPerformed
private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed private void createTestGame(String gameName, String gameType) {
TableView table; TableView table;
try { try {
File f = new File("test.dck"); String testDeckFile = "test.dck";
File f = new File(testDeckFile);
if (!f.exists()) { if (!f.exists()) {
JOptionPane.showMessageDialog(null, "Couldn't find test.dck file for quick game start", "Error", JOptionPane.ERROR_MESSAGE); // default test deck
return; testDeckFile = DeckUtil.writeTextToTempFile(""
+ "5 Swamp" + System.lineSeparator()
+ "5 Forest" + System.lineSeparator()
+ "5 Island" + System.lineSeparator()
+ "5 Mountain" + System.lineSeparator()
+ "5 Plains");
} }
DeckCardLists testDeck = DeckImporter.importDeckFromFile(testDeckFile);
MatchOptions options = new MatchOptions("1", "Two Player Duel", false, 2); MatchOptions options = new MatchOptions(gameName, gameType, false, 2);
options.getPlayerTypes().add(PlayerType.HUMAN); options.getPlayerTypes().add(PlayerType.HUMAN);
options.getPlayerTypes().add(PlayerType.COMPUTER_MAD); options.getPlayerTypes().add(PlayerType.COMPUTER_MAD);
options.setDeckType("Limited"); options.setDeckType("Limited");
@ -1544,13 +1588,17 @@ public class TablesPanel extends javax.swing.JPanel {
options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
table = SessionHandler.createTable(roomId, options); table = SessionHandler.createTable(roomId, options);
SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporter.importDeckFromFile("test.dck"), ""); SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, testDeck, "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporter.importDeckFromFile("test.dck"), ""); SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, testDeck, "");
SessionHandler.startMatch(roomId, table.getTableId()); SessionHandler.startMatch(roomId, table.getTableId());
} catch (HeadlessException ex) { } catch (HeadlessException ex) {
handleError(ex); handleError(ex);
} }
}//GEN-LAST:event_btnQuickStartActionPerformed }
private void btnQuickStartDuelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartDuelActionPerformed
createTestGame("Test duel", "Two Player Duel");
}//GEN-LAST:event_btnQuickStartDuelActionPerformed
private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed
newTableDialog.showDialog(roomId); newTableDialog.showDialog(roomId);
@ -1580,7 +1628,7 @@ public class TablesPanel extends javax.swing.JPanel {
} else { } else {
this.jSplitPaneTables.setDividerLocation(this.jPanelTables.getHeight()); this.jSplitPaneTables.setDividerLocation(this.jPanelTables.getHeight());
} }
this.startTasks(); this.startUpdateTasks(true);
}//GEN-LAST:event_btnStateFinishedActionPerformed }//GEN-LAST:event_btnStateFinishedActionPerformed
private void btnRatedbtnFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRatedbtnFilterActionPerformed private void btnRatedbtnFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRatedbtnFilterActionPerformed
@ -1603,6 +1651,10 @@ public class TablesPanel extends javax.swing.JPanel {
MageFrame.getInstance().showWhatsNewDialog(true); MageFrame.getInstance().showWhatsNewDialog(true);
}//GEN-LAST:event_buttonWhatsNewActionPerformed }//GEN-LAST:event_buttonWhatsNewActionPerformed
private void btnQuickStartCommanderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartCommanderActionPerformed
createTestGame("Test commander", "Commander Two Player Duel");
}//GEN-LAST:event_btnQuickStartCommanderActionPerformed
private void handleError(Exception ex) { private void handleError(Exception ex) {
LOGGER.fatal("Error loading deck: ", ex); LOGGER.fatal("Error loading deck: ", ex);
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE);
@ -1623,7 +1675,8 @@ public class TablesPanel extends javax.swing.JPanel {
private javax.swing.JButton btnNewTournament; private javax.swing.JButton btnNewTournament;
private javax.swing.JToggleButton btnOpen; private javax.swing.JToggleButton btnOpen;
private javax.swing.JToggleButton btnPassword; private javax.swing.JToggleButton btnPassword;
private javax.swing.JButton btnQuickStart; private javax.swing.JButton btnQuickStartCommander;
private javax.swing.JButton btnQuickStartDuel;
private javax.swing.JToggleButton btnRated; private javax.swing.JToggleButton btnRated;
private javax.swing.JToggleButton btnSkillBeginner; private javax.swing.JToggleButton btnSkillBeginner;
private javax.swing.JToggleButton btnSkillCasual; private javax.swing.JToggleButton btnSkillCasual;
@ -1665,6 +1718,7 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
private final UUID roomId; private final UUID roomId;
private final TablesPanel panel; private final TablesPanel panel;
private boolean isFirstRun = true;
private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); private static final Logger logger = Logger.getLogger(UpdateTablesTask.class);
@ -1683,8 +1737,7 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
if (tables != null) { if (tables != null) {
this.publish(tables); this.publish(tables);
} }
TimeUnit.SECONDS.sleep(TablesPanel.randomizeTimout(TablesPanel.REFRESH_ACTIVE_TABLES_SECS));
TimeUnit.SECONDS.sleep(TablesPanel.REFRESH_ACTIVE_TABLES_SECS);
} }
return null; return null;
} }
@ -1692,10 +1745,13 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
@Override @Override
protected void process(java.util.List<Collection<TableView>> view) { protected void process(java.util.List<Collection<TableView>> view) {
panel.updateTables(view.get(0)); panel.updateTables(view.get(0));
// update server messages
count++; count++;
if (count > 60) { if (isFirstRun || count > 60) {
count = 0; count = 0;
panel.reloadMessages(); isFirstRun = false;
panel.reloadServerMessages();
} }
} }
@ -1728,7 +1784,7 @@ class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
while (!isCancelled()) { while (!isCancelled()) {
this.publish(SessionHandler.getRoomUsers(roomId)); this.publish(SessionHandler.getRoomUsers(roomId));
TimeUnit.SECONDS.sleep(TablesPanel.REFRESH_PLAYERS_SECS); TimeUnit.SECONDS.sleep(TablesPanel.randomizeTimout(TablesPanel.REFRESH_PLAYERS_SECS));
} }
return null; return null;
} }
@ -1765,11 +1821,8 @@ class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
@Override @Override
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
while (!isCancelled()) { while (!isCancelled()) {
Collection<MatchView> matches = SessionHandler.getFinishedMatches(roomId); this.publish(SessionHandler.getFinishedMatches(roomId));
if (!matches.isEmpty()) { TimeUnit.SECONDS.sleep(TablesPanel.randomizeTimout(TablesPanel.REFRESH_FINISHED_TABLES_SECS));
this.publish(matches);
}
TimeUnit.SECONDS.sleep(TablesPanel.REFRESH_FINISHED_TABLES_SECS);
} }
return null; return null;
} }

View file

@ -16,14 +16,15 @@ import java.util.UUID;
*/ */
public final class ArrowUtil { public final class ArrowUtil {
private ArrowUtil() {} private ArrowUtil() {
}
public static void drawArrowsForPairedCards(TransferData data, Point parentPoint) { public static void drawArrowsForPairedCards(TransferData data, Point parentPoint) {
if (data.getCard().getPairedCard() != null) { if (data.getCard().getPairedCard() != null) {
Point me = new Point(data.getLocationOnScreen()); Point me = new Point(data.getLocationOnScreen());
me.translate(-parentPoint.x, -parentPoint.y); me.translate(-parentPoint.x, -parentPoint.y);
UUID uuid = data.getCard().getPairedCard(); UUID uuid = data.getCard().getPairedCard();
for (PlayAreaPanel pa : MageFrame.getGame(data.getGameId()).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(data.getGameId()).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid); MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) { if (permanent != null) {
Point target = permanent.getLocationOnScreen(); Point target = permanent.getLocationOnScreen();
@ -38,7 +39,7 @@ public final class ArrowUtil {
if (data.getCard().getBandedCards() != null && !data.getCard().getBandedCards().isEmpty()) { if (data.getCard().getBandedCards() != null && !data.getCard().getBandedCards().isEmpty()) {
Point me = new Point(data.getLocationOnScreen()); Point me = new Point(data.getLocationOnScreen());
me.translate(-parentPoint.x, -parentPoint.y); me.translate(-parentPoint.x, -parentPoint.y);
for (PlayAreaPanel pa : MageFrame.getGame(data.getGameId()).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(data.getGameId()).values()) {
for (UUID uuid : data.getCard().getBandedCards()) { for (UUID uuid : data.getCard().getBandedCards()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid); MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) { if (permanent != null) {
@ -53,7 +54,7 @@ public final class ArrowUtil {
public static void drawArrowsForEnchantPlayers(TransferData data, Point parentPoint) { public static void drawArrowsForEnchantPlayers(TransferData data, Point parentPoint) {
if (data.getGameId() != null && MageFrame.getGame(data.getGameId()) != null) { if (data.getGameId() != null && MageFrame.getGame(data.getGameId()) != null) {
for (PlayAreaPanel pa : MageFrame.getGame(data.getGameId()).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(data.getGameId()).values()) {
PlayerPanelExt playAreaPanel = pa.getPlayerPanel(); PlayerPanelExt playAreaPanel = pa.getPlayerPanel();
if (playAreaPanel != null && playAreaPanel.getPlayer() != null && playAreaPanel.getPlayer().hasAttachments()) { if (playAreaPanel != null && playAreaPanel.getPlayer() != null && playAreaPanel.getPlayer().hasAttachments()) {
Point me = new Point(data.getLocationOnScreen()); Point me = new Point(data.getLocationOnScreen());
@ -62,7 +63,7 @@ public final class ArrowUtil {
if (attachmentId.equals(data.getCard().getId())) { if (attachmentId.equals(data.getCard().getId())) {
Point player = pa.getLocationOnScreen(); Point player = pa.getLocationOnScreen();
player.translate(-parentPoint.x, -parentPoint.y); player.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(data.getGameId(),(int) me.getX() + 35, (int) me.getY(), (int) player.getX() + 40, (int) player.getY() - 40, Color.magenta, ArrowBuilder.Type.ENCHANT_PLAYERS); ArrowBuilder.getBuilder().addArrow(data.getGameId(), (int) me.getX() + 35, (int) me.getY(), (int) player.getX() + 40, (int) player.getY() - 40, Color.magenta, ArrowBuilder.Type.ENCHANT_PLAYERS);
} }
} }
} }
@ -75,7 +76,7 @@ public final class ArrowUtil {
Point me = new Point(data.getLocationOnScreen()); Point me = new Point(data.getLocationOnScreen());
me.translate(-parentPoint.x, -parentPoint.y); me.translate(-parentPoint.x, -parentPoint.y);
UUID uuid = data.getCard().getParentId(); UUID uuid = data.getCard().getParentId();
for (PlayAreaPanel pa : MageFrame.getGame(data.getGameId()).getPlayers().values()) { for (PlayAreaPanel pa : MageFrame.getGamePlayers(data.getGameId()).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid); MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) { if (permanent != null) {
Point source = permanent.getLocationOnScreen(); Point source = permanent.getLocationOnScreen();
@ -96,7 +97,7 @@ public final class ArrowUtil {
me.translate(-parentPoint.x, -parentPoint.y); me.translate(-parentPoint.x, -parentPoint.y);
for (UUID uuid : targets) { for (UUID uuid : targets) {
PlayAreaPanel p = MageFrame.getGame(data.getGameId()).getPlayers().get(uuid); PlayAreaPanel p = MageFrame.getGamePlayers(data.getGameId()).get(uuid);
if (p != null) { if (p != null) {
Point target = p.getLocationOnScreen(); Point target = p.getLocationOnScreen();
target.translate(-parentPoint.x, -parentPoint.y); target.translate(-parentPoint.x, -parentPoint.y);
@ -104,7 +105,7 @@ public final class ArrowUtil {
continue; continue;
} }
for (PlayAreaPanel panel : MageFrame.getGame(data.getGameId()).getPlayers().values()) { for (PlayAreaPanel panel : MageFrame.getGamePlayers(data.getGameId()).values()) {
MagePermanent permanent = panel.getBattlefieldPanel().getPermanents().get(uuid); MagePermanent permanent = panel.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) { if (permanent != null) {
Point target = permanent.getLocationOnScreen(); Point target = permanent.getLocationOnScreen();
@ -117,7 +118,7 @@ public final class ArrowUtil {
if (view != null) { if (view != null) {
CardsView graveyard = view.getGraveyard(); CardsView graveyard = view.getGraveyard();
if (graveyard.containsKey(uuid)) { if (graveyard.containsKey(uuid)) {
p = MageFrame.getGame(data.getGameId()).getPlayers().get(view.getPlayerId()); p = MageFrame.getGamePlayers(data.getGameId()).get(view.getPlayerId());
if (p != null) { if (p != null) {
Point target = p.getLocationOnScreen(); Point target = p.getLocationOnScreen();
target.translate(-parentPoint.x, -parentPoint.y); target.translate(-parentPoint.x, -parentPoint.y);

View file

@ -181,10 +181,14 @@ public final class GuiDisplayUtil {
public static TextLines getTextLinesfromCardView(CardView card) { public static TextLines getTextLinesfromCardView(CardView card) {
TextLines textLines = new TextLines(); TextLines textLines = new TextLines();
// rules
textLines.setLines(new ArrayList<>(card.getRules())); textLines.setLines(new ArrayList<>(card.getRules()));
for (String rule : card.getRules()) { for (String rule : card.getRules()) {
textLines.setBasicTextLength(textLines.getBasicTextLength() + rule.length()); textLines.setBasicTextLength(textLines.getBasicTextLength() + rule.length());
} }
// counters
if (card.getMageObjectType().canHaveCounters()) { if (card.getMageObjectType().canHaveCounters()) {
ArrayList<CounterView> counters = new ArrayList<>(); ArrayList<CounterView> counters = new ArrayList<>();
if (card instanceof PermanentView) { if (card instanceof PermanentView) {
@ -212,6 +216,8 @@ public final class GuiDisplayUtil {
textLines.setBasicTextLength(textLines.getBasicTextLength() + 50); textLines.setBasicTextLength(textLines.getBasicTextLength() + 50);
} }
} }
// damage
if (card.getMageObjectType().isPermanent() && card instanceof PermanentView) { if (card.getMageObjectType().isPermanent() && card instanceof PermanentView) {
int damage = ((PermanentView) card).getDamage(); int damage = ((PermanentView) card).getDamage();
if (damage > 0) { if (damage > 0) {

View file

@ -1,5 +1,6 @@
package org.mage.card.arcane; package org.mage.card.arcane;
import mage.MageInt;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.client.constants.Constants; import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
@ -9,6 +10,7 @@ import mage.client.util.SoftValuesLoadingCache;
import mage.components.ImagePanel; import mage.components.ImagePanel;
import mage.components.ImagePanelStyle; import mage.components.ImagePanelStyle;
import mage.constants.AbilityType; import mage.constants.AbilityType;
import mage.constants.SubType;
import mage.view.CardView; import mage.view.CardView;
import mage.view.CounterView; import mage.view.CounterView;
import mage.view.PermanentView; import mage.view.PermanentView;
@ -49,11 +51,16 @@ public class CardPanelComponentImpl extends CardPanel {
private static final int CARD_MIN_SIZE_FOR_ICONS = 60; private static final int CARD_MIN_SIZE_FOR_ICONS = 60;
private static final int CARD_MAX_SIZE_FOR_ICONS = 200; private static final int CARD_MAX_SIZE_FOR_ICONS = 200;
// text min size for image render mode
private static final int CARD_TITLE_FONT_MIN_SIZE = 13;
private static final int CARD_PT_FONT_MIN_SIZE = 17;
public final ScaledImagePanel imagePanel; public final ScaledImagePanel imagePanel;
private ImagePanel overlayPanel; private ImagePanel overlayPanel;
private JPanel iconPanel; private JPanel iconPanel;
private JButton typeButton; private JButton typeButton;
private JPanel ptPanel;
private JPanel counterPanel; private JPanel counterPanel;
private JLabel loyaltyCounterLabel; private JLabel loyaltyCounterLabel;
@ -67,7 +74,9 @@ public class CardPanelComponentImpl extends CardPanel {
private int lastCardWidth; private int lastCardWidth;
private final GlowText titleText; private final GlowText titleText;
private final GlowText ptText; private final GlowText ptText1;
private final GlowText ptText2;
private final GlowText ptText3;
private final JLabel fullImageText; private final JLabel fullImageText;
private String fullImagePath = null; private String fullImagePath = null;
@ -280,7 +289,7 @@ public class CardPanelComponentImpl extends CardPanel {
// Title Text // Title Text
titleText = new GlowText(); titleText = new GlowText();
setText(getGameCard()); setTitle(getGameCard());
// int fontSize = (int) cardHeight / 11; // int fontSize = (int) cardHeight / 11;
// titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); // titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize));
titleText.setForeground(Color.white); titleText.setForeground(Color.white);
@ -295,16 +304,19 @@ public class CardPanelComponentImpl extends CardPanel {
add(fullImageText); add(fullImageText);
// PT Text // PT Text
ptText = new GlowText(); ptPanel = new JPanel();
if (getGameCard().isCreature()) { ptPanel.setOpaque(false);
ptText.setText(getGameCard().getPower() + '/' + getGameCard().getToughness()); ptPanel.setLayout(new BoxLayout(ptPanel, BoxLayout.X_AXIS));
} else if (getGameCard().isPlanesWalker()) { ptPanel.add(new Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(Integer.MAX_VALUE, 0)));
ptText.setText(getGameCard().getLoyalty()); ptText1 = new GlowText();
} ptText2 = new GlowText();
// ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); ptText3 = new GlowText();
ptText.setForeground(Color.white); updatePTTexts(getGameCard());
ptText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY); ptPanel.add(ptText1);
add(ptText); ptPanel.add(ptText2);
ptPanel.add(ptText3);
//
add(ptPanel);
// Sickness overlay // Sickness overlay
BufferedImage sickness = ImageManagerImpl.instance.getSicknessImage(); BufferedImage sickness = ImageManagerImpl.instance.getSicknessImage();
@ -349,7 +361,7 @@ public class CardPanelComponentImpl extends CardPanel {
this.setCounterPanel(null); this.setCounterPanel(null);
} }
private void setText(CardView card) { private void setTitle(CardView card) {
titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName()); titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName());
} }
@ -585,12 +597,14 @@ public class CardPanelComponentImpl extends CardPanel {
boolean showText = !isAnimationPanel() && canShowCardIcons(cardWidth, hasImage); boolean showText = !isAnimationPanel() && canShowCardIcons(cardWidth, hasImage);
titleText.setVisible(showText); titleText.setVisible(showText);
ptText.setVisible(showText); ptText1.setVisible(showText && !ptText1.getText().isEmpty());
ptText2.setVisible(showText && !ptText2.getText().isEmpty());
ptText3.setVisible(showText && !ptText3.getText().isEmpty());
fullImageText.setVisible(fullImagePath != null); fullImageText.setVisible(fullImagePath != null);
if (showText) { if (showText) {
int fontSize = cardHeight / 13; // startup font size (it same size on all zoom levels) int fontSize = cardHeight / 13; // startup font size (it same size on all zoom levels)
titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); titleText.setFont(getFont().deriveFont(Font.BOLD, Math.max(CARD_TITLE_FONT_MIN_SIZE, fontSize)));
// margins from card black border to text, not need? text show up good without margins // margins from card black border to text, not need? text show up good without margins
int titleMarginLeft = 0; //Math.round(28f / 672f * cardWidth); int titleMarginLeft = 0; //Math.round(28f / 672f * cardWidth);
@ -607,24 +621,60 @@ public class CardPanelComponentImpl extends CardPanel {
fullImageText.setFont(getFont().deriveFont(Font.PLAIN, 10)); fullImageText.setFont(getFont().deriveFont(Font.PLAIN, 10));
fullImageText.setBounds(titleText.getX(), titleText.getY(), titleText.getBounds().width, titleText.getBounds().height); fullImageText.setBounds(titleText.getX(), titleText.getY(), titleText.getBounds().width, titleText.getBounds().height);
// life points location (font as title) // PT (font as title)
ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); if (getGameCard().getOriginalCard() != null) {
Dimension ptSize = ptText.getPreferredSize(); prepareGlowFont(ptText1, Math.max(CARD_PT_FONT_MIN_SIZE, fontSize), getGameCard().getOriginalCard().getPower(), false);
ptText.setSize(ptSize.width, ptSize.height); prepareGlowFont(ptText2, Math.max(CARD_PT_FONT_MIN_SIZE, fontSize), null, false);
prepareGlowFont(ptText3, Math.max(CARD_PT_FONT_MIN_SIZE, fontSize), getGameCard().getOriginalCard().getToughness(), CardRendererUtils.isCardWithDamage(getGameCard()));
// right bottom corner with margin (sizes from any sample card) // right bottom corner with margin (sizes from any sample card)
int ptMarginRight = Math.round(64f / 672f * cardWidth); int ptMarginRight = Math.round(64f / 672f * cardWidth);
int ptMarginBottom = Math.round(62f / 936f * cardHeight); int ptMarginBottom = Math.round(62f / 936f * cardHeight);
int ptX = cardXOffset + cardWidth - ptMarginRight - ptSize.width; int ptWidth = cardWidth - ptMarginRight * 2;
int ptY = cardYOffset + cardHeight - ptMarginBottom - ptSize.height; int ptHeight = ptText2.getHeight();
ptText.setLocation(ptX, ptY); int ptX = cardXOffset + ptMarginRight;
int ptY = cardYOffset + cardHeight - ptMarginBottom - ptHeight;
ptPanel.setBounds(ptX, ptY, ptWidth, ptHeight);
}
// old version was with TEXT_GLOW_SIZE // old version was with TEXT_GLOW_SIZE
//ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2); //ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2);
} }
} }
private void prepareGlowFont(GlowText label, int fontSize, MageInt value, boolean drawAsDamaged) {
label.setFont(getFont().deriveFont(Font.BOLD, fontSize));
label.setForeground(CardRendererUtils.getCardTextColor(value, drawAsDamaged, titleText.getForeground(), true));
Dimension ptSize = label.getPreferredSize();
label.setSize(ptSize.width, ptSize.height);
}
private void updatePTTexts(CardView card) {
if (card.isCreature() || card.getSubTypes().contains(SubType.VEHICLE)) {
ptText1.setText(getGameCard().getPower());
ptText2.setText("/");
ptText3.setText(CardRendererUtils.getCardLifeWithDamage(getGameCard()));
} else if (card.isPlanesWalker()) {
ptText1.setText("");
ptText2.setText("");
ptText3.setText(getGameCard().getLoyalty());
} else {
ptText1.setText("");
ptText2.setText("");
ptText3.setText("");
}
ptText1.setForeground(Color.white);
ptText1.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
ptText2.setForeground(Color.white);
ptText2.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
ptText3.setForeground(Color.white);
ptText3.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
}
@Override @Override
public String toString() { public String toString() {
return getGameCard().toString(); return getGameCard().toString();
@ -647,10 +697,14 @@ public class CardPanelComponentImpl extends CardPanel {
// Update components // Update components
if (alpha == 0) { if (alpha == 0) {
this.ptText.setVisible(false); this.ptText1.setVisible(false);
this.ptText2.setVisible(false);
this.ptText3.setVisible(false);
this.titleText.setVisible(false); this.titleText.setVisible(false);
} else if (alpha == 1.0f) { } else if (alpha == 1.0f) {
this.ptText.setVisible(true); this.ptText1.setVisible(true);
this.ptText2.setVisible(true);
this.ptText3.setVisible(true);
this.titleText.setVisible(true); this.titleText.setVisible(true);
} }
} }
@ -683,7 +737,7 @@ public class CardPanelComponentImpl extends CardPanel {
UI.invokeLater(() -> { UI.invokeLater(() -> {
if (stamp == updateArtImageStamp) { if (stamp == updateArtImageStamp) {
hasImage = srcImage != null; hasImage = srcImage != null;
setText(getGameCard()); setTitle(getGameCard());
setImage(srcImage); setImage(srcImage);
} }
}); });
@ -712,7 +766,7 @@ public class CardPanelComponentImpl extends CardPanel {
@Override @Override
public void showCardTitle() { public void showCardTitle() {
displayTitleAnyway = true; displayTitleAnyway = true;
setText(getGameCard()); setTitle(getGameCard());
} }
@Override @Override
@ -720,17 +774,8 @@ public class CardPanelComponentImpl extends CardPanel {
// Super // Super
super.update(card); super.update(card);
// Update card text updatePTTexts(card);
if (card.isCreature() && card.isPlanesWalker()) { setTitle(card);
ptText.setText(card.getPower() + '/' + card.getToughness() + " (" + card.getLoyalty() + ')');
} else if (card.isCreature()) {
ptText.setText(card.getPower() + '/' + card.getToughness());
} else if (card.isPlanesWalker()) {
ptText.setText(card.getLoyalty());
} else {
ptText.setText("");
}
setText(card);
// Summoning Sickness overlay // Summoning Sickness overlay
if (hasSickness() && card.isCreature() && isPermanent()) { if (hasSickness() && card.isCreature() && isPermanent()) {

View file

@ -297,6 +297,8 @@ public class CardPanelRenderImpl extends CardPanel {
// Render with Antialialsing // Render with Antialialsing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// Attributes // Attributes
CardPanelAttributes attribs CardPanelAttributes attribs

View file

@ -1,5 +1,9 @@
package org.mage.card.arcane; package org.mage.card.arcane;
import mage.MageInt;
import mage.view.CardView;
import mage.view.PermanentView;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.HashMap; import java.util.HashMap;
@ -10,12 +14,18 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* @author stravant@gmail.com * @author stravant@gmail.com, JayDi85
* <p> * <p>
* Various static utilities for use in the card renderer * Various static utilities for use in the card renderer
*/ */
public final class CardRendererUtils { public final class CardRendererUtils {
// text colors for PT (mtgo and image render modes)
private static final Color CARD_TEXT_COLOR_GOOD_LIGHT = new Color(182, 235, 168);
private static final Color CARD_TEXT_COLOR_GOOD_DARK = new Color(52, 135, 88);
private static final Color CARD_TEXT_COLOR_BAD_LIGHT = new Color(234, 153, 153);
private static final Color CARD_TEXT_COLOR_BAD_DARK = new Color(200, 33, 33);
/** /**
* Convert an abstract image, whose underlying implementation may or may not * Convert an abstract image, whose underlying implementation may or may not
* be a BufferedImage into a BufferedImage by creating one and coping the * be a BufferedImage into a BufferedImage by creating one and coping the
@ -53,9 +63,9 @@ public final class CardRendererUtils {
int b = c.getBlue(); int b = c.getBlue();
int alpha = c.getAlpha(); int alpha = c.getAlpha();
int plus_r = (int) ((255 - r) / 2); int plus_r = (255 - r) / 2;
int plus_g = (int) ((255 - g) / 2); int plus_g = (255 - g) / 2;
int plus_b = (int) ((255 - b) / 2); int plus_b = (255 - b) / 2;
return new Color(r + plus_r, return new Color(r + plus_r,
g + plus_g, g + plus_g,
@ -69,9 +79,9 @@ public final class CardRendererUtils {
int b = c.getBlue(); int b = c.getBlue();
int alpha = c.getAlpha(); int alpha = c.getAlpha();
int plus_r = (int) (Math.min(255 - r, r) / 2); int plus_r = Math.min(255 - r, r) / 2;
int plus_g = (int) (Math.min(255 - g, g) / 2); int plus_g = Math.min(255 - g, g) / 2;
int plus_b = (int) (Math.min(255 - b, b) / 2); int plus_b = Math.min(255 - b, b) / 2;
return new Color(r - plus_r, return new Color(r - plus_r,
g - plus_g, g - plus_g,
@ -195,4 +205,52 @@ public final class CardRendererUtils {
return null; return null;
} }
} }
public static String getCardLifeWithDamage(CardView cardView) {
// life with damage
String originLife = cardView.getToughness();
if (cardView instanceof PermanentView) {
int damage = ((PermanentView) cardView).getDamage();
int life;
try {
life = Integer.parseInt(originLife);
originLife = String.valueOf(Math.max(0, life - damage));
} catch (NumberFormatException e) {
//
}
}
return originLife;
}
public static boolean isCardWithDamage(CardView cardView) {
boolean haveDamage = false;
if (cardView instanceof PermanentView) {
haveDamage = ((PermanentView) cardView).getDamage() > 0;
}
return haveDamage;
}
public static Color getCardTextColor(MageInt value, boolean drawAsDamaged, Color defaultColor, boolean textLight) {
if (drawAsDamaged) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
}
// boost colorizing
if (value != null) {
int current = value.getValue();
int origin = value.getBaseValue();
if (origin != 0) {
if (current < origin) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
} else if (current > origin) {
return textLight ? CARD_TEXT_COLOR_GOOD_LIGHT : CARD_TEXT_COLOR_GOOD_DARK;
} else {
return defaultColor;
}
}
}
return defaultColor;
}
} }

View file

@ -1,5 +1,10 @@
package org.mage.card.arcane; package org.mage.card.arcane;
import mage.client.util.ImageCaches;
import mage.client.util.SoftValuesLoadingCache;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer; import java.awt.font.LineBreakMeasurer;
@ -14,17 +19,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import javax.swing.*;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import mage.client.util.ImageCaches;
import mage.client.util.SoftValuesLoadingCache;
public class GlowText extends JLabel { public class GlowText extends JLabel {
private static final long serialVersionUID = 1827677946939348001L; private static final long serialVersionUID = 1827677946939348001L;
@ -123,10 +117,7 @@ public class GlowText extends JLabel {
if (!Objects.equals(this.color, other.color)) { if (!Objects.equals(this.color, other.color)) {
return false; return false;
} }
if (!Objects.equals(this.glowColor, other.glowColor)) { return Objects.equals(this.glowColor, other.glowColor);
return false;
}
return true;
} }
} }
@ -158,7 +149,11 @@ public class GlowText extends JLabel {
return; return;
} }
g.drawImage(IMAGE_CACHE.getOrThrow(new Key(getWidth(), getHeight(), getText(), getFont(), getForeground(), glowSize, glowIntensity, glowColor, wrap)), 0, 0, null); g.drawImage(getGlowImage(), 0, 0, null);
}
public BufferedImage getGlowImage() {
return IMAGE_CACHE.getOrThrow(new Key(getWidth(), getHeight(), getText(), getFont(), getForeground(), glowSize, glowIntensity, glowColor, wrap));
} }
private static BufferedImage createGlowImage(Key key) { private static BufferedImage createGlowImage(Key key) {

View file

@ -1,8 +1,3 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.card.arcane; package org.mage.card.arcane;
import mage.ObjectColor; import mage.ObjectColor;
@ -56,13 +51,14 @@ import static org.mage.card.arcane.ManaSymbols.getSizedManaSymbol;
*/ */
/** /**
* @author stravant@gmail.com * @author stravant@gmail.com, JayDi85
* <p> * <p>
* Base rendering class for new border cards * Base rendering class for new border cards
*/ */
public class ModernCardRenderer extends CardRenderer { public class ModernCardRenderer extends CardRenderer {
private static final Logger LOGGER = Logger.getLogger(ModernCardRenderer.class); private static final Logger LOGGER = Logger.getLogger(ModernCardRenderer.class);
private static final GlowText glowTextRenderer = new GlowText();
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Textures for modern frame cards // Textures for modern frame cards
@ -98,7 +94,7 @@ public class ModernCardRenderer extends CardRenderer {
return new Font("Arial", Font.PLAIN, 1); return new Font("Arial", Font.PLAIN, 1);
} }
public static final Font BASE_BELEREN_FONT = loadFont("beleren-bold"); // public static final Font BASE_BELEREN_FONT = loadFont("beleren-bold");
public static final Paint BG_TEXTURE_WHITE = loadBackgroundTexture("white"); public static final Paint BG_TEXTURE_WHITE = loadBackgroundTexture("white");
public static final Paint BG_TEXTURE_BLUE = loadBackgroundTexture("blue"); public static final Paint BG_TEXTURE_BLUE = loadBackgroundTexture("blue");
@ -252,16 +248,13 @@ public class ModernCardRenderer extends CardRenderer {
// Box text height // Box text height
boxTextHeight = getTextHeightForBoxHeight(boxHeight); boxTextHeight = getTextHeightForBoxHeight(boxHeight);
boxTextOffset = (boxHeight - boxTextHeight) / 2; boxTextOffset = (boxHeight - boxTextHeight) / 2;
// Not using Beleren for now because it looks bad at small font sizes. Maybe we want to in the future?
//boxTextFont = BASE_BELEREN_FONT.deriveFont(Font.PLAIN, boxTextHeight);
boxTextFont = new Font("Arial", Font.PLAIN, boxTextHeight); boxTextFont = new Font("Arial", Font.PLAIN, boxTextHeight);
boxTextFontNarrow = new Font("Arial Narrow", Font.PLAIN, boxTextHeight); boxTextFontNarrow = new Font("Arial Narrow", Font.PLAIN, boxTextHeight);
// Box text height // Box text height
ptTextHeight = getPTTextHeightForLineHeight(boxHeight); ptTextHeight = getPTTextHeightForLineHeight(boxHeight);
ptTextOffset = (boxHeight - ptTextHeight) / 2; ptTextOffset = (boxHeight - ptTextHeight) / 2;
// Beleren font does work well for numbers though ptTextFont = new Font("Arial", Font.BOLD, ptTextHeight);
ptTextFont = BASE_BELEREN_FONT.deriveFont(Font.PLAIN, ptTextHeight);
} }
@Override @Override
@ -482,7 +475,7 @@ public class ModernCardRenderer extends CardRenderer {
g.setPaint(borderPaint); g.setPaint(borderPaint);
if (cardView.getFrameStyle() == FrameStyle.KLD_INVENTION) { if (cardView.getFrameStyle() == FrameStyle.KLD_INVENTION) {
g.drawImage(FRAME_INVENTION, 0, 0, cardWidth, cardHeight, null); g.drawImage(FRAME_INVENTION, 3, 3, cardWidth - 6, cardHeight - 6, null);
g.drawRect( g.drawRect(
totalContentInset, typeLineY, totalContentInset, typeLineY,
contentWidth - 1, cardHeight - borderWidth * 3 - typeLineY - 1); contentWidth - 1, cardHeight - borderWidth * 3 - typeLineY - 1);
@ -933,6 +926,51 @@ public class ModernCardRenderer extends CardRenderer {
} }
} }
public void paintOutlineTextByGlow(Graphics2D g, String text, Color color, int x, int y) {
GlowText label = new GlowText();
label.setGlow(Color.black, 6, 3);
label.setText(text);
label.setFont(g.getFont().deriveFont(Font.BOLD));
label.setForeground(color);
Dimension ptSize = label.getPreferredSize();
label.setSize(ptSize.width, ptSize.height);
g.drawImage(label.getGlowImage(), x, y, null);
}
public void paintOutlineTextByStroke(Graphics2D g, String text, Color color, int x, int y) {
// https://stackoverflow.com/a/35222059/1276632
Color outlineColor = Color.black;
Color fillColor = color;
BasicStroke outlineStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
// remember original settings
Color originalColor = g.getColor();
Stroke originalStroke = g.getStroke();
RenderingHints originalHints = g.getRenderingHints();
// create a glyph vector from your text
GlyphVector glyphVector = g.getFont().createGlyphVector(g.getFontRenderContext(), text);
// get the shape object
Shape textShape = glyphVector.getOutline(x, y);
// activate anti aliasing for text rendering (if you want it to look nice)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setColor(outlineColor);
g.setStroke(outlineStroke);
g.draw(textShape); // draw outline
g.setColor(fillColor);
g.fill(textShape); // fill the shape
// reset to original settings after painting
g.setColor(originalColor);
g.setStroke(originalStroke);
g.setRenderingHints(originalHints);
}
// Draw the P/T and/or Loyalty boxes // Draw the P/T and/or Loyalty boxes
protected void drawBottomRight(Graphics2D g, Paint borderPaint, Color fill) { protected void drawBottomRight(Graphics2D g, Paint borderPaint, Color fill) {
// No bottom right for abilities // No bottom right for abilities
@ -944,17 +982,31 @@ public class ModernCardRenderer extends CardRenderer {
int curY = cardHeight - (int) (0.03f * cardHeight); int curY = cardHeight - (int) (0.03f * cardHeight);
// Width of the boxes // Width of the boxes
int partWidth = (int) Math.max(30, 0.20f * cardWidth); int partBoxWidth = (int) Math.max(30, 0.20f * cardWidth);
// Is it a creature? // Is it a creature?
boolean isVehicle = cardView.getSubTypes().contains(SubType.VEHICLE); boolean isVehicle = cardView.getSubTypes().contains(SubType.VEHICLE);
if (cardView.isCreature() || isVehicle) { if (cardView.isCreature() || isVehicle) {
int x = cardWidth - borderWidth - partWidth;
// draws p/t by parts
int ptDeviderSpace = 1; // Arial font is too narrow for devider (2/2) and needs extra space
String ptText1 = cardView.getPower();
String ptText2 = "/";
String ptText3 = CardRendererUtils.getCardLifeWithDamage(cardView);
int ptTextWidth1 = g.getFontMetrics(ptTextFont).stringWidth(ptText1);
int ptTextWidth2 = g.getFontMetrics(ptTextFont).stringWidth(ptText2) + 2 * ptDeviderSpace;
int ptTextWidth3 = g.getFontMetrics(ptTextFont).stringWidth(ptText3);
// PT max size
int ptContentWidth = contentInset + ptTextWidth1 + ptDeviderSpace + ptTextWidth2 + ptDeviderSpace + ptTextWidth3 + contentInset;
partBoxWidth = Math.max(ptContentWidth, partBoxWidth);
int x = cardWidth - borderWidth - partBoxWidth;
// Draw PT box // Draw PT box
CardRendererUtils.drawRoundedBox(g, CardRendererUtils.drawRoundedBox(g,
x, curY - boxHeight, x, curY - boxHeight,
partWidth, boxHeight, partBoxWidth, boxHeight,
contentInset, contentInset,
borderPaint, borderPaint,
isVehicle ? BOX_VEHICLE : fill); isVehicle ? BOX_VEHICLE : fill);
@ -963,27 +1015,42 @@ public class ModernCardRenderer extends CardRenderer {
g.setColor(new Color(0, 0, 0, 150)); g.setColor(new Color(0, 0, 0, 150));
g.fillRect( g.fillRect(
x + contentInset, curY - boxHeight - 1, x + contentInset, curY - boxHeight - 1,
partWidth - 2 * contentInset, 1); partBoxWidth - 2 * contentInset, 1);
// Draw text // Draw text
Color textColor; Color defaultTextColor;
boolean defaultTextLight;
if (isVehicle) { if (isVehicle) {
boolean isAnimated = !(cardView instanceof PermanentView) || cardView.isCreature(); boolean isAnimated = !(cardView instanceof PermanentView) || cardView.isCreature();
if (isAnimated) { if (isAnimated) {
textColor = Color.white; defaultTextColor = Color.white;
} else { } else {
textColor = new Color(180, 180, 180); defaultTextColor = new Color(180, 180, 180);
} }
defaultTextLight = true;
} else { } else {
textColor = getBoxTextColor(); defaultTextColor = getBoxTextColor();
defaultTextLight = !defaultTextColor.equals(Color.black);
} }
g.setColor(textColor); g.setColor(defaultTextColor);
g.setFont(ptTextFont); g.setFont(ptTextFont);
String ptText = cardView.getPower() + '/' + cardView.getToughness();
int ptTextWidth = g.getFontMetrics().stringWidth(ptText); // draws
g.drawString(ptText, int ptEmptySpace = (partBoxWidth - ptContentWidth) / 2;
x + (partWidth - ptTextWidth) / 2, curY - ptTextOffset - 1); int ptPosStart1 = x + contentInset + ptEmptySpace;
int ptPosStart2 = ptPosStart1 + ptTextWidth1 + ptDeviderSpace;
int ptPosStart3 = ptPosStart2 + ptTextWidth2 + ptDeviderSpace;
// p
g.setColor(CardRendererUtils.getCardTextColor(cardView.getOriginalCard().getPower(), false, defaultTextColor, defaultTextLight));
g.drawString(ptText1, ptPosStart1, curY - ptTextOffset - 1); // left
// /
g.setColor(defaultTextColor);
g.drawString(ptText2, ptPosStart2, curY - ptTextOffset - 1); // center
// t
g.setColor(CardRendererUtils.getCardTextColor(cardView.getOriginalCard().getPower(), CardRendererUtils.isCardWithDamage(cardView), defaultTextColor, defaultTextLight));
g.drawString(ptText3, ptPosStart3, curY - ptTextOffset - 1); // right
//
g.setColor(defaultTextColor);
// Advance // Advance
curY -= boxHeight; curY -= boxHeight;
@ -994,9 +1061,9 @@ public class ModernCardRenderer extends CardRenderer {
if (cardView.isPlanesWalker() if (cardView.isPlanesWalker()
&& (cardView instanceof PermanentView || !cardView.getStartingLoyalty().equals("0"))) { && (cardView instanceof PermanentView || !cardView.getStartingLoyalty().equals("0"))) {
// Draw the PW loyalty box // Draw the PW loyalty box
int w = partWidth; int w = partBoxWidth;
int h = partWidth / 2; int h = partBoxWidth / 2;
int x = cardWidth - partWidth - borderWidth; int x = cardWidth - partBoxWidth - borderWidth;
int y = curY - h; int y = curY - h;
Polygon symbol = new Polygon( Polygon symbol = new Polygon(
@ -1047,16 +1114,16 @@ public class ModernCardRenderer extends CardRenderer {
// does it have damage on it? // does it have damage on it?
if ((cardView instanceof PermanentView) && ((PermanentView) cardView).getDamage() > 0) { if ((cardView instanceof PermanentView) && ((PermanentView) cardView).getDamage() > 0) {
int x = cardWidth - partWidth - borderWidth; int x = cardWidth - partBoxWidth - borderWidth;
int y = curY - boxHeight; int y = curY - boxHeight;
String damage = String.valueOf(((PermanentView) cardView).getDamage()); String damage = String.valueOf(((PermanentView) cardView).getDamage());
g.setFont(ptTextFont); g.setFont(ptTextFont);
int txWidth = g.getFontMetrics().stringWidth(damage); int txWidth = g.getFontMetrics().stringWidth(damage);
g.setColor(Color.red); g.setColor(Color.red);
g.fillRect(x, y, partWidth, boxHeight); g.fillRect(x, y, partBoxWidth, boxHeight);
g.setColor(Color.white); g.setColor(Color.white);
g.drawRect(x, y, partWidth, boxHeight); g.drawRect(x, y, partBoxWidth, boxHeight);
g.drawString(damage, x + (partWidth - txWidth) / 2, curY - 1); g.drawString(damage, x + (partBoxWidth - txWidth) / 2, curY - 1);
} }
} }

View file

@ -2,7 +2,6 @@ package org.mage.plugins.card;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.interfaces.plugin.CardPlugin; import mage.interfaces.plugin.CardPlugin;
import mage.view.CardView; import mage.view.CardView;
@ -99,25 +98,28 @@ public class CardPluginImpl implements CardPlugin {
* Temporary card rendering shim. Split card rendering isn't implemented * Temporary card rendering shim. Split card rendering isn't implemented
* yet, so use old component based rendering for the split cards. * yet, so use old component based rendering for the split cards.
*/ */
private CardPanel makePanel(CardView view, UUID gameId, boolean loadImage, ActionCallback callback, boolean isFoil, Dimension dimension) { private CardPanel makePanel(CardView view, UUID gameId, boolean loadImage, ActionCallback callback, boolean isFoil, Dimension dimension, int renderMode) {
String fallback = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_FALLBACK, "false"); switch (renderMode) {
if (fallback.equals("true")) { case 0:
return new CardPanelComponentImpl(view, gameId, loadImage, callback, isFoil, dimension);
} else {
return new CardPanelRenderImpl(view, gameId, loadImage, callback, isFoil, dimension); return new CardPanelRenderImpl(view, gameId, loadImage, callback, isFoil, dimension);
case 1:
return new CardPanelComponentImpl(view, gameId, loadImage, callback, isFoil, dimension);
default:
throw new IllegalStateException("Unknown render mode " + renderMode);
} }
} }
@Override @Override
public MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { public MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage, int renderMode) {
CardPanel cardPanel = makePanel(permanent, gameId, loadImage, callback, false, dimension); CardPanel cardPanel = makePanel(permanent, gameId, loadImage, callback, false, dimension, renderMode);
cardPanel.setShowCastingCost(true); cardPanel.setShowCastingCost(true);
return cardPanel; return cardPanel;
} }
@Override @Override
public MagePermanent getMageCard(CardView cardView, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { public MagePermanent getMageCard(CardView cardView, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage, int renderMode) {
CardPanel cardPanel = makePanel(cardView, gameId, loadImage, callback, false, dimension); CardPanel cardPanel = makePanel(cardView, gameId, loadImage, callback, false, dimension, renderMode);
cardPanel.setShowCastingCost(true); cardPanel.setShowCastingCost(true);
return cardPanel; return cardPanel;
} }

View file

@ -50,8 +50,25 @@ public class ScryfallImageSupportTokens {
put("RNA/Zombie", "https://api.scryfall.com/cards/trna/3/en?format=image"); put("RNA/Zombie", "https://api.scryfall.com/cards/trna/3/en?format=image");
// WAR // WAR
put("WAR/Zombie Army", "https://api.scryfall.com/cards/twar/8/en?format=image"); put("WAR/Angel", "https://api.scryfall.com/cards/twar/2/en?format=image");
put("WAR/Assassin", "https://api.scryfall.com/cards/twar/6/en?format=image");
put("WAR/Citizen", "https://api.scryfall.com/cards/twar/16/en?format=image");
put("WAR/Devil", "https://api.scryfall.com/cards/twar/12/en?format=image");
put("WAR/Dragon", "https://api.scryfall.com/cards/twar/13/en?format=image");
put("WAR/Goblin", "https://api.scryfall.com/cards/twar/14/en?format=image");
put("WAR/Emblem Nissa, Who Shakes the World", "https://api.scryfall.com/cards/twar/19/en?format=image");
put("WAR/Servo", "https://api.scryfall.com/cards/twar/18/en?format=image");
put("WAR/Soldier", "https://api.scryfall.com/cards/twar/3/en?format=image");
put("WAR/Spirit", "https://api.scryfall.com/cards/twar/1/en?format=image");
put("WAR/Voja, Friend to Elves", "https://api.scryfall.com/cards/twar/17/en?format=image");
put("WAR/Wall", "https://api.scryfall.com/cards/twar/4/en?format=image");
put("WAR/Wizard", "https://api.scryfall.com/cards/twar/5/en?format=image");
put("WAR/Wolf", "https://api.scryfall.com/cards/twar/15/en?format=image");
put("WAR/Zombie Army/1", "https://api.scryfall.com/cards/twar/10/en?format=image");
put("WAR/Zombie Army/2", "https://api.scryfall.com/cards/twar/8/en?format=image");
put("WAR/Zombie Army/3", "https://api.scryfall.com/cards/twar/9/en?format=image");
put("WAR/Zombie Warrior", "https://api.scryfall.com/cards/twar/11/en?format=image");
put("WAR/Zombie", "https://api.scryfall.com/cards/twar/7/en?format=image");
// generate supported sets // generate supported sets
supportedSets.clear(); supportedSets.clear();

View file

@ -52,7 +52,7 @@ public final class CardImageUtils {
return filePath; return filePath;
} }
log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + getTokenImagePath(card)); //log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + getTokenImagePath(card));
} else { } else {
log.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName()); log.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName());
} }

View file

@ -87,6 +87,7 @@
|Generate|EMBLEM:SWS|Obi-Wan Kenobi||Emblem Obi-Wan Kenobi|ObiWanKenobiEmblem| |Generate|EMBLEM:SWS|Obi-Wan Kenobi||Emblem Obi-Wan Kenobi|ObiWanKenobiEmblem|
|Generate|EMBLEM:RIX|Huatli, Radiant Champion||Emblem Huatli|HuatliRadiantChampionEmblem| |Generate|EMBLEM:RIX|Huatli, Radiant Champion||Emblem Huatli|HuatliRadiantChampionEmblem|
|Generate|EMBLEM:RNA|Domri, Chaos Bringer||Emblem Domri|DomriChaosBringerEmblem| |Generate|EMBLEM:RNA|Domri, Chaos Bringer||Emblem Domri|DomriChaosBringerEmblem|
|Generate|EMBLEM:WAR|Nissa, Who Shakes the World||Emblem Nissa|NissaWhoShakesTheWorldEmblem|
|Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane| |Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane|
|Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane| |Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane|
|Generate|PLANE:PCA|Plane - Akoum|||AkoumPlane| |Generate|PLANE:PCA|Plane - Akoum|||AkoumPlane|
@ -1198,4 +1199,27 @@
|Generate|TOK:RNA|Thopter|||ThopterToken| |Generate|TOK:RNA|Thopter|||ThopterToken|
|Generate|TOK:RNA|Treasure|||TreasureToken| |Generate|TOK:RNA|Treasure|||TreasureToken|
|Generate|TOK:RNA|Zombie|||ZombieToken| |Generate|TOK:RNA|Zombie|||ZombieToken|
|Generate|TOK:WAR|Zombie Army|||ZombieArmyToken| |Generate|TOK:WAR|Angel|||AngelVigilanceToken|
|Generate|TOK:WAR|Assassin|||AssassinToken2|
|Generate|TOK:WAR|Devil|||DevilToken|
|Generate|TOK:WAR|Dragon|||DragonToken|
|Generate|TOK:WAR|Goblin|||GoblinToken|
|Generate|TOK:WAR|Servo|||ServoToken|
|Generate|TOK:WAR|Soldier|||SoldierVigilanceToken|
|Generate|TOK:WAR|Spirit|||UginTheIneffableToken|
|Generate|TOK:WAR|Voja, Friend to Elves|||VojaFriendToElvesToken|
|Generate|TOK:WAR|Wall|||TeyoToken|
|Generate|TOK:WAR|Wizard|||WizardToken|
|Generate|TOK:WAR|Wolf|||WolfToken|
|Generate|TOK:WAR|Zombie|||ZombieToken|
|Generate|TOK:WAR|Zombie Warrior|||GodEternalOketraToken|
|Generate|TOK:WAR|Zombie Army|1||ZombieArmyToken|
|Generate|TOK:WAR|Zombie Army|2||ZombieArmyToken|
|Generate|TOK:WAR|Zombie Army|3||ZombieArmyToken|

View file

@ -71,7 +71,7 @@ public class MultiConnectTest {
} }
@Override @Override
public void disconnected(boolean errorCall) { public void disconnected(boolean askToReconnect) {
logger.info("disconnected"); logger.info("disconnected");
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-common</artifactId> <artifactId>mage-common</artifactId>

View file

@ -1,11 +1,9 @@
package mage.interfaces; package mage.interfaces;
import mage.interfaces.callback.CallbackClient; import mage.interfaces.callback.CallbackClient;
import mage.utils.MageVersion; import mage.utils.MageVersion;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public interface MageClient extends CallbackClient { public interface MageClient extends CallbackClient {
@ -14,7 +12,7 @@ public interface MageClient extends CallbackClient {
void connected(String message); void connected(String message);
void disconnected(boolean errorCall); void disconnected(boolean askToReconnect);
void showMessage(String message); void showMessage(String message);

View file

@ -1,30 +1,28 @@
package mage.interfaces.plugin; package mage.interfaces.plugin;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.UUID;
import javax.swing.*;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.view.CardView; import mage.view.CardView;
import mage.view.PermanentView; import mage.view.PermanentView;
import net.xeoh.plugins.base.Plugin; import net.xeoh.plugins.base.Plugin;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.UUID;
/** /**
* Interface for card plugins * Interface for card plugins
* *
* @version 0.6 17.07.2011 added options to #sortPermanents
* @version 0.3 21.11.2010 #getMageCard
* @version 0.2 07.11.2010 #downloadImages
* @version 0.1 31.10.2010 #getMagePermanent, #sortPermanents
* @author nantuko * @author nantuko
* @version 0.1 31.10.2010 #getMagePermanent, #sortPermanents
*/ */
public interface CardPlugin extends Plugin { public interface CardPlugin extends Plugin {
MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage); MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage, int renderMode);
MagePermanent getMageCard(CardView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage); MagePermanent getMageCard(CardView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage, int renderMode);
int sortPermanents(Map<String, JComponent> ui, Map<UUID, MagePermanent> cards, boolean nonPermanentsOwnRow, boolean topPanel); int sortPermanents(Map<String, JComponent> ui, Map<UUID, MagePermanent> cards, boolean nonPermanentsOwnRow, boolean topPanel);

View file

@ -28,14 +28,16 @@ import org.jboss.remoting.transport.bisocket.Bisocket;
import org.jboss.remoting.transport.socket.SocketWrapper; import org.jboss.remoting.transport.socket.SocketWrapper;
import org.jboss.remoting.transporter.TransporterClient; import org.jboss.remoting.transporter.TransporterClient;
import javax.swing.*;
import java.io.*; import java.io.*;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com, JayDi85
*/ */
public class SessionImpl implements Session { public class SessionImpl implements Session {
@ -54,6 +56,7 @@ public class SessionImpl implements Session {
private ServerState serverState; private ServerState serverState;
private SessionState sessionState = SessionState.DISCONNECTED; private SessionState sessionState = SessionState.DISCONNECTED;
private Connection connection; private Connection connection;
private RemotingTask lastRemotingTask = null;
private static final int PING_CYCLES = 10; private static final int PING_CYCLES = 10;
private final LinkedList<Long> pingTime = new LinkedList<>(); private final LinkedList<Long> pingTime = new LinkedList<>();
private String pingInfo = ""; private String pingInfo = "";
@ -76,22 +79,56 @@ public class SessionImpl implements Session {
return sessionId; return sessionId;
} }
// RemotingTask encapsulates a task which is involved with some JBoss Remoting. This is // RemotingTask - do server side works in background and return result, can be canceled at any time
// intended to be used with handleRemotingTaskExceptions for sharing the common exception public abstract class RemotingTask {
// handling.
public interface RemotingTask {
boolean run() throws Throwable; SwingWorker<Boolean, Object> worker = null;
Throwable lastError = null;
abstract public boolean work() throws Throwable;
boolean doWork() throws Throwable {
worker = new SwingWorker<Boolean, Object>() {
@Override
protected Boolean doInBackground() {
try {
return work();
} catch (Throwable t) {
lastError = t;
return false;
}
}
};
worker.execute();
boolean res = worker.get();
if (lastError != null) {
throw lastError;
}
return res;
} }
// handleRemotingTaskExceptions runs the given task and handles exceptions appropriately. This public void cancel() {
// way we can share the common exception handling. if (worker != null) {
private boolean handleRemotingTaskExceptions(RemotingTask remoting) { worker.cancel(true);
}
}
}
private void showMessageToUser(String message) {
client.showMessage("Remote task error. " + message);
}
private boolean doRemoteWorkAndHandleErrors(RemotingTask remoting) {
// execute remote task and wait result, can be canceled
lastRemotingTask = remoting;
try { try {
return remoting.run(); return remoting.doWork();
} catch (InterruptedException | CancellationException t) {
// was canceled by user, nothing to show
} catch (MalformedURLException ex) { } catch (MalformedURLException ex) {
logger.fatal("", ex); logger.fatal("Connect: wrong server address", ex);
client.showMessage("Unable connect to server. " + ex.getMessage()); showMessageToUser(ex.getMessage());
} catch (UndeclaredThrowableException ex) { } catch (UndeclaredThrowableException ex) {
String addMessage = ""; String addMessage = "";
Throwable cause = ex.getCause(); Throwable cause = ex.getCause();
@ -103,7 +140,7 @@ public class SessionImpl implements Session {
addMessage = "Probably the server version is not compatible with the client. "; addMessage = "Probably the server version is not compatible with the client. ";
} }
} else { } else {
logger.error("Unknown server error", exep.getCause()); logger.error("Connect: unknown server error", exep.getCause());
} }
} else if (cause instanceof NoSuchMethodException) { } else if (cause instanceof NoSuchMethodException) {
// NoSuchMethodException is thrown on an invocation of an unknow JBoss remoting // NoSuchMethodException is thrown on an invocation of an unknow JBoss remoting
@ -112,66 +149,59 @@ public class SessionImpl implements Session {
+ "server version is not compatible with the client: " + cause.getMessage(); + "server version is not compatible with the client: " + cause.getMessage();
} }
if (addMessage.isEmpty()) { if (addMessage.isEmpty()) {
logger.fatal("", ex); logger.fatal("Connect: unknown error", ex);
} }
client.showMessage("Unable connect to server. " + addMessage + (ex.getMessage() != null ? ex.getMessage() : "")); showMessageToUser(addMessage + (ex.getMessage() != null ? ex.getMessage() : ""));
} catch (IOException ex) { } catch (IOException ex) {
logger.fatal("", ex); logger.fatal("Connect: unknown IO error", ex);
String addMessage = ""; String addMessage = "";
if (ex.getMessage() != null && ex.getMessage().startsWith("Unable to perform invocation")) { if (ex.getMessage() != null && ex.getMessage().startsWith("Unable to perform invocation")) {
addMessage = "Maybe the server version is not compatible. "; addMessage = "Maybe the server version is not compatible. ";
} }
client.showMessage("Unable connect to server. " + addMessage + (ex.getMessage() != null ? ex.getMessage() : "")); showMessageToUser(addMessage + (ex.getMessage() != null ? ex.getMessage() : ""));
} catch (MageVersionException ex) { } catch (MageVersionException ex) {
if (!canceled) { logger.warn("Connect: wrong versions");
client.showMessage("Unable connect to server. " + ex.getMessage());
}
disconnect(false); disconnect(false);
if (!canceled) {
showMessageToUser(ex.getMessage());
}
} catch (CannotConnectException ex) { } catch (CannotConnectException ex) {
if (!canceled) { if (!canceled) {
handleCannotConnectException(ex); handleCannotConnectException(ex);
} }
} catch (Throwable t) { } catch (Throwable t) {
logger.fatal("Unable connect to server - ", t); logger.fatal("Connect: FAIL", t);
if (!canceled) {
disconnect(false); disconnect(false);
StringBuilder sb = new StringBuilder(); if (!canceled) {
sb.append("Unable connect to server.\n"); showMessageToUser(t.getMessage());
for (StackTraceElement element : t.getStackTrace()) {
sb.append(element.toString()).append('\n');
}
client.showMessage(sb.toString());
} }
} finally {
lastRemotingTask = null;
} }
return false; return false;
} }
@Override @Override
public synchronized boolean register(final Connection connection) { public synchronized boolean register(final Connection connection) {
return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() { return doRemoteConnection(connection) && doRemoteWorkAndHandleErrors(new RemotingTask() {
@Override @Override
public boolean run() throws Throwable { public boolean work() throws Throwable {
logger.info("Trying to register as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Registration: username " + getUserName() + " for email " + getEmail());
boolean registerResult = server.registerUser(sessionId, connection.getUsername(), boolean result = server.registerUser(sessionId, connection.getUsername(), connection.getPassword(), connection.getEmail());
connection.getPassword(), connection.getEmail()); logger.info("Registration: " + (result ? "DONE, check your email for new password" : "FAIL"));
if (registerResult) { return result;
logger.info("Registered as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());
}
return registerResult;
} }
}); });
} }
@Override @Override
public synchronized boolean emailAuthToken(final Connection connection) { public synchronized boolean emailAuthToken(final Connection connection) {
return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() { return doRemoteConnection(connection) && doRemoteWorkAndHandleErrors(new RemotingTask() {
@Override @Override
public boolean run() throws Throwable { public boolean work() throws Throwable {
logger.info("Trying to ask for an auth token to " + getEmail() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Auth request: requesting auth token for username " + getUserName() + " to email " + getEmail());
boolean result = server.emailAuthToken(sessionId, connection.getEmail()); boolean result = server.emailAuthToken(sessionId, connection.getEmail());
if (result) { logger.info("Auth request: " + (result ? "DONE, check your email for auth token" : "FAIL"));
logger.info("An auth token is emailed to " + getEmail() + " from MAGE server at " + connection.getHost() + ':' + connection.getPort());
}
return result; return result;
} }
}); });
@ -179,14 +209,12 @@ public class SessionImpl implements Session {
@Override @Override
public synchronized boolean resetPassword(final Connection connection) { public synchronized boolean resetPassword(final Connection connection) {
return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() { return doRemoteConnection(connection) && doRemoteWorkAndHandleErrors(new RemotingTask() {
@Override @Override
public boolean run() throws Throwable { public boolean work() throws Throwable {
logger.info("Trying reset the password in XMAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Password reset: reseting password for username " + getUserName());
boolean result = server.resetPassword(sessionId, connection.getEmail(), connection.getAuthToken(), connection.getPassword()); boolean result = server.resetPassword(sessionId, connection.getEmail(), connection.getAuthToken(), connection.getPassword());
if (result) { logger.info("Password reset: " + (result ? "DONE, check your email for new password" : "FAIL"));
logger.info("Password is successfully reset in MAGE server at " + connection.getHost() + ':' + connection.getPort());
}
return result; return result;
} }
}); });
@ -194,39 +222,39 @@ public class SessionImpl implements Session {
@Override @Override
public synchronized boolean connect(final Connection connection) { public synchronized boolean connect(final Connection connection) {
return establishJBossRemotingConnection(connection) return doRemoteConnection(connection) && doRemoteWorkAndHandleErrors(new RemotingTask() {
&& handleRemotingTaskExceptions(new RemotingTask() {
@Override @Override
public boolean run() throws Throwable { public boolean work() throws Throwable {
setLastError(""); setLastError("");
logger.info("Trying to log-in as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Logging: as username " + getUserName() + " to server " + connection.getHost() + ':' + connection.getPort());
boolean registerResult; boolean result;
if (connection.getAdminPassword() == null) { if (connection.getAdminPassword() == null) {
// for backward compatibility. don't remove twice call - first one does nothing but for version checking // for backward compatibility. don't remove twice call - first one does nothing but for version checking
registerResult = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr()); result = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr());
} else { } else {
registerResult = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion()); result = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion());
} }
if (registerResult) {
if (result) {
serverState = server.getServerState(); serverState = server.getServerState();
// client side check for incompatible versions // client side check for incompatible versions
if (client.getVersion().compareTo(serverState.getVersion()) != 0) { if (client.getVersion().compareTo(serverState.getVersion()) != 0) {
String err = "Client and server versions are incompatible."; throw new MageVersionException(client.getVersion(), serverState.getVersion());
setLastError(err);
logger.info(err);
disconnect(false);
return false;
} }
if (!connection.getUsername().equals("Admin")) { if (!connection.getUsername().equals("Admin")) {
server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr()); server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr());
updateDatabase(connection.isForceDBComparison(), serverState); updateDatabase(connection.isForceDBComparison(), serverState);
} }
logger.info("Logged-in as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());
logger.info("Logging: DONE");
client.connected(getUserName() + '@' + connection.getHost() + ':' + connection.getPort() + ' '); client.connected(getUserName() + '@' + connection.getHost() + ':' + connection.getPort() + ' ');
return true; return true;
} }
logger.info("Logging: FAIL");
disconnect(false); disconnect(false);
return false; return false;
} }
@ -241,20 +269,24 @@ public class SessionImpl implements Session {
@Override @Override
public boolean stopConnecting() { public boolean stopConnecting() {
canceled = true; canceled = true;
if (lastRemotingTask != null) {
lastRemotingTask.cancel();
}
return true; return true;
} }
private boolean establishJBossRemotingConnection(final Connection connection) { private boolean doRemoteConnection(final Connection connection) {
// connect to server and setup all data, can be canceled
if (isConnected()) { if (isConnected()) {
disconnect(true); disconnect(true);
} }
this.connection = connection; this.connection = connection;
this.canceled = false; this.canceled = false;
sessionState = SessionState.CONNECTING; sessionState = SessionState.CONNECTING;
boolean result = handleRemotingTaskExceptions(new RemotingTask() { lastRemotingTask = new RemotingTask() {
@Override @Override
public boolean run() throws Throwable { public boolean work() throws Throwable {
logger.info("Trying to connect to XMAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Connect: connecting to server " + connection.getHost() + ':' + connection.getPort());
System.setProperty("http.nonProxyHosts", "code.google.com"); System.setProperty("http.nonProxyHosts", "code.google.com");
System.setProperty("socksNonProxyHosts", "code.google.com"); System.setProperty("socksNonProxyHosts", "code.google.com");
@ -265,6 +297,9 @@ public class SessionImpl implements Session {
System.clearProperty("http.proxyHost"); System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort"); System.clearProperty("http.proxyPort");
if (connection.getProxyType() != Connection.ProxyType.NONE) {
logger.info("Connect: using proxy " + connection.getProxyHost() + ":" + connection.getProxyPort());
}
switch (connection.getProxyType()) { switch (connection.getProxyType()) {
case SOCKS: case SOCKS:
System.setProperty("socksProxyHost", connection.getProxyHost()); System.setProperty("socksProxyHost", connection.getProxyHost());
@ -392,16 +427,25 @@ public class SessionImpl implements Session {
sessionId = callbackClient.getSessionId(); sessionId = callbackClient.getSessionId();
sessionState = SessionState.CONNECTED; sessionState = SessionState.CONNECTED;
logger.info("Connected to MAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.info("Connect: DONE");
return true; return true;
} }
}); };
boolean result;
try {
result = doRemoteWorkAndHandleErrors(lastRemotingTask);
} finally {
lastRemotingTask = null;
}
if (result) { if (result) {
return true; return true;
} } else {
disconnect(false); disconnect(false);
return false; return false;
} }
}
private void updateDatabase(boolean forceDBComparison, ServerState serverState) { private void updateDatabase(boolean forceDBComparison, ServerState serverState) {
// download NEW cards/sets, but do not download data fixes (it's an old and rare feature from old clients, e.g. one client for different servers with different cards) // download NEW cards/sets, but do not download data fixes (it's an old and rare feature from old clients, e.g. one client for different servers with different cards)
@ -463,7 +507,7 @@ public class SessionImpl implements Session {
@Override @Override
public synchronized void disconnect(boolean askForReconnect) { public synchronized void disconnect(boolean askForReconnect) {
if (isConnected()) { if (isConnected()) {
logger.info("DISCONNECT (still connected)"); logger.info("Disconnecting...");
sessionState = SessionState.DISCONNECTING; sessionState = SessionState.DISCONNECTING;
} }
if (connection == null || sessionState == SessionState.DISCONNECTED) { if (connection == null || sessionState == SessionState.DISCONNECTED) {
@ -471,16 +515,18 @@ public class SessionImpl implements Session {
} }
try { try {
if (callbackClient.isConnected()) {
callbackClient.removeListener(callbackHandler); callbackClient.removeListener(callbackHandler);
callbackClient.disconnect(); callbackClient.disconnect();
}
TransporterClient.destroyTransporterClient(server); TransporterClient.destroyTransporterClient(server);
} catch (Throwable ex) { } catch (Throwable ex) {
logger.fatal("Error disconnecting ...", ex); logger.fatal("Disconnecting FAIL", ex);
} }
if (sessionState == SessionState.DISCONNECTING || sessionState == SessionState.CONNECTING) { if (sessionState == SessionState.DISCONNECTING || sessionState == SessionState.CONNECTING) {
sessionState = SessionState.DISCONNECTED; sessionState = SessionState.DISCONNECTED;
logger.info("Disconnected ... "); logger.info("Disconnecting DONE");
if (askForReconnect) { if (askForReconnect) {
client.showError("Network error. You have been disconnected from " + connection.getHost()); client.showError("Network error. You have been disconnected from " + connection.getHost());
} }
@ -491,7 +537,6 @@ public class SessionImpl implements Session {
@Override @Override
public synchronized void reconnect(Throwable throwable) { public synchronized void reconnect(Throwable throwable) {
logger.info("RECONNECT - Connected: " + isConnected());
client.disconnected(true); client.disconnected(true);
} }
@ -522,7 +567,7 @@ public class SessionImpl implements Session {
@Override @Override
public void handleConnectionException(Throwable throwable, Client client) { public void handleConnectionException(Throwable throwable, Client client) {
logger.info("connection to server lost - " + throwable.getMessage(), throwable); logger.info("Connect: lost connection to server.", throwable);
reconnect(throwable); reconnect(throwable);
} }
} }
@ -1538,14 +1583,24 @@ public class SessionImpl implements Session {
} }
private void handleThrowable(Throwable t) { private void handleThrowable(Throwable t) {
logger.fatal("Communication error", t);
// ignore interrupted exceptions -- it's connection problem or user's close
if (t instanceof InterruptedException) { if (t instanceof InterruptedException) {
logger.error("Was interrupted", new Throwable()); //logger.error("Connection error: was interrupted", t);
Thread.currentThread().interrupt();
return;
} }
// Probably this can cause hanging the client under certain circumstances as the disconnect method is synchronized if (t instanceof RuntimeException) {
// so check if it's needed RuntimeException re = (RuntimeException) t;
// disconnect(true); if (t.getCause() instanceof InterruptedException) {
//logger.error("Connection error: was interrupted by runtime exception", t.getCause());
Thread.currentThread().interrupt();
return;
}
}
logger.fatal("Connection error: other", t);
} }
private void handleMageException(MageException ex) { private void handleMageException(MageException ex) {
@ -1592,7 +1647,7 @@ public class SessionImpl implements Session {
@Override @Override
public boolean ping() { public boolean ping() {
try { try {
if (isConnected()) { if (isConnected() && sessionId != null) {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
if (!server.ping(sessionId, pingInfo)) { if (!server.ping(sessionId, pingInfo)) {
logger.error("Ping failed: " + this.getUserName() + " Session: " + sessionId + " to MAGE server at " + connection.getHost() + ':' + connection.getPort()); logger.error("Ping failed: " + this.getUserName() + " Session: " + sessionId + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());

View file

@ -11,9 +11,9 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public static final int MAGE_VERSION_MAJOR = 1; public static final int MAGE_VERSION_MAJOR = 1;
public static final int MAGE_VERSION_MINOR = 4; public static final int MAGE_VERSION_MINOR = 4;
public static final int MAGE_VERSION_PATCH = 34; public static final int MAGE_VERSION_PATCH = 35;
public static final String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0 public static final String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0
public static final String MAGE_VERSION_MINOR_PATCH = "V0.2"; // default public static final String MAGE_VERSION_MINOR_PATCH = "V5"; // default
// strict mode // strict mode
private static final boolean MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME = true; // set true on uncompatible github changes, set false after new major release (after MAGE_VERSION_PATCH changes) private static final boolean MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME = true; // set true on uncompatible github changes, set false after new major release (after MAGE_VERSION_PATCH changes)

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-counter-plugin</artifactId> <artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage.server.console</artifactId> <artifactId>mage.server.console</artifactId>

View file

@ -174,7 +174,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
/** /**
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String args[]) { public static void main(String[] args) {
logger.info("Starting MAGE server console version " + version); logger.info("Starting MAGE server console version " + version);
logger.info("Logging level: " + logger.getEffectiveLevel()); logger.info("Logging level: " + logger.getEffectiveLevel());
@ -210,7 +210,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
} }
@Override @Override
public void disconnected(boolean errorCall) { public void disconnected(boolean askToReconnect) {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
consolePanel1.stop(); consolePanel1.stop();
setStatusText("Not connected"); setStatusText("Not connected");

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-deck-constructed</artifactId> <artifactId>mage-deck-constructed</artifactId>

View file

@ -60,7 +60,7 @@ public class FreeformCommander extends Constructed {
for (Map.Entry<String, Integer> entry : counts.entrySet()) { for (Map.Entry<String, Integer> entry : counts.entrySet()) {
if (entry.getValue() > 1) { if (entry.getValue() > 1) {
if (!basicLandNames.contains(entry.getKey())) { if (!basicLandNames.contains(entry.getKey()) && !anyNumberCardsAllowed.contains(entry.getKey())) {
invalid.put(entry.getKey(), "Too many: " + entry.getValue()); invalid.put(entry.getKey(), "Too many: " + entry.getValue());
valid = false; valid = false;
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-deck-limited</artifactId> <artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-brawlduel</artifactId> <artifactId>mage-game-brawlduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-brawlfreeforall</artifactId> <artifactId>mage-game-brawlfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId> <artifactId>mage-game-canadianhighlanderduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-commanderduel</artifactId> <artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-commanderfreeforall</artifactId> <artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-freeforall</artifactId> <artifactId>mage-game-freeforall</artifactId>

View file

@ -0,0 +1,50 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.35</version>
</parent>
<artifactId>mage-game-freeformcommanderduel</artifactId>
<packaging>jar</packaging>
<name>Mage Game Freeform Commander Two Player</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<finalName>mage-game-freeformcommanderduel</finalName>
</build>
<properties/>
</project>

View file

@ -0,0 +1,36 @@
package mage.game;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan;
/**
* @author JayDi85
*/
public class FreeformCommanderDuel extends GameCommanderImpl {
public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife);
}
public FreeformCommanderDuel(final FreeformCommanderDuel game) {
super(game);
}
@Override
public MatchType getGameType() {
return new FreeformCommanderDuelType();
}
@Override
public int getNumPlayers() {
return 2;
}
@Override
public FreeformCommanderDuel copy() {
return new FreeformCommanderDuel(this);
}
}

View file

@ -0,0 +1,31 @@
package mage.game;
import mage.game.match.MatchImpl;
import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan;
/**
* @author JayDi85
*/
public class FreeformCommanderDuelMatch extends MatchImpl {
public FreeformCommanderDuelMatch(MatchOptions options) {
super(options);
}
@Override
public void startGame() throws GameException {
int startLife = 20;
boolean alsoHand = true;
boolean checkCommanderDamage = true;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
FreeformCommanderDuel game = new FreeformCommanderDuel(options.getAttackOption(), options.getRange(), mulligan, startLife);
game.setCheckCommanderDamage(checkCommanderDamage);
game.setStartMessage(this.createGameStartMessage());
game.setAlsoHand(alsoHand);
game.setAlsoLibrary(true);
initGame(game);
games.add(game);
}
}

View file

@ -0,0 +1,29 @@
package mage.game;
import mage.game.match.MatchType;
/**
* @author JayDi85
*/
public class FreeformCommanderDuelType extends MatchType {
public FreeformCommanderDuelType() {
this.name = "Freeform Commander Two Player Duel";
this.maxPlayers = 2;
this.minPlayers = 2;
this.numTeams = 0;
this.useAttackOption = false;
this.useRange = false;
this.sideboardingAllowed = false;
}
protected FreeformCommanderDuelType(final FreeformCommanderDuelType matchType) {
super(matchType);
}
@Override
public FreeformCommanderDuelType copy() {
return new FreeformCommanderDuelType(this);
}
}

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId> <artifactId>mage-game-freeformcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-momirduel</artifactId> <artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-momirfreeforall</artifactId> <artifactId>mage-game-momirfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId> <artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-tinyleadersduel</artifactId> <artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-game-twoplayerduel</artifactId> <artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-ai-draftbot</artifactId> <artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-ai-ma</artifactId> <artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-ai</artifactId> <artifactId>mage-player-ai</artifactId>

View file

@ -150,6 +150,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetPlayer) { if (target.getOriginalTarget() instanceof TargetPlayer) {
return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game); return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game);
} }
if (target.getOriginalTarget() instanceof TargetDiscard) { if (target.getOriginalTarget() instanceof TargetDiscard) {
findPlayables(game); findPlayables(game);
if (!unplayable.isEmpty()) { if (!unplayable.isEmpty()) {
@ -174,38 +175,43 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetControlledPermanent) { if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
List<Permanent> targets; List<Permanent> targets;
targets = threats(abilityControllerId, sourceId, ((TargetControlledPermanent) target).getFilter(), game, target.getTargets()); TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
if (!outcome.isGood()) { if (!outcome.isGood()) {
Collections.reverse(targets); Collections.reverse(targets);
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
if (((TargetControlledPermanent) target).canTarget(abilityControllerId, permanent.getId(), sourceId, game, false) && !target.getTargets().contains(permanent.getId())) { if (origTarget.canTarget(abilityControllerId, permanent.getId(), sourceId, game, false) && !target.getTargets().contains(permanent.getId())) {
target.add(permanent.getId(), game); target.add(permanent.getId(), game);
return true; return true;
} }
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetPermanent) { if (target.getOriginalTarget() instanceof TargetPermanent) {
TargetPermanent origTarget = (TargetPermanent) target.getOriginalTarget();
List<Permanent> targets; List<Permanent> targets;
if (outcome.isCanTargetAll()) { if (outcome.isCanTargetAll()) {
targets = threats(null, sourceId, ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(null, sourceId, origTarget.getFilter(), game, target.getTargets());
} else { } else {
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, sourceId, ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, sourceId, ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(randomOpponentId, sourceId, origTarget.getFilter(), game, target.getTargets());
} }
if (targets.isEmpty() && target.isRequired()) { if (targets.isEmpty() && target.isRequired()) {
if (!outcome.isGood()) { if (!outcome.isGood()) {
targets = threats(abilityControllerId, sourceId, ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, sourceId, ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(randomOpponentId, sourceId, origTarget.getFilter(), game, target.getTargets());
} }
} }
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
if (target.canTarget(abilityControllerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) { if (target.canTarget(abilityControllerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) {
// stop to add targets if not needed and outcome is no advantage for AI player // stop to add targets if not needed and outcome is no advantage for AI player
@ -246,17 +252,18 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetAnyTarget) { if (target.getOriginalTarget() instanceof TargetAnyTarget) {
List<Permanent> targets; List<Permanent> targets;
TargetAnyTarget t = ((TargetAnyTarget) target); TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargetted = target.getTargets(); List<UUID> alreadyTargetted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), null, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), null, game)) {
if (alreadyTargetted != null && !alreadyTargetted.contains(permanent.getId())) { if (alreadyTargetted != null && !alreadyTargetted.contains(permanent.getId())) {
target.add(permanent.getId(), game); target.add(permanent.getId(), game);
return true; return true;
@ -276,17 +283,18 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return false; return false;
} }
} }
if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) { if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) {
List<Permanent> targets; List<Permanent> targets;
TargetCreatureOrPlayer t = ((TargetCreatureOrPlayer) target); TargetCreatureOrPlayer origTarget = (TargetCreatureOrPlayer) target.getOriginalTarget();
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), null, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), null, game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
target.add(permanent.getId(), game); target.add(permanent.getId(), game);
return true; return true;
@ -309,9 +317,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) { if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
List<Permanent> targets; List<Permanent> targets;
TargetPermanentOrPlayer t = ((TargetPermanentOrPlayer) target); TargetPermanentOrPlayer origTarget = (TargetPermanentOrPlayer) target.getOriginalTarget();
List<Permanent> ownedTargets = threats(abilityControllerId, sourceId, ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); List<Permanent> ownedTargets = threats(abilityControllerId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
List<Permanent> opponentTargets = threats(randomOpponentId, sourceId, ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); List<Permanent> opponentTargets = threats(randomOpponentId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
if (outcome.isGood()) { if (outcome.isGood()) {
targets = ownedTargets; targets = ownedTargets;
} else { } else {
@ -319,7 +327,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(permanent.getId(), game)) { if (target.canTarget(permanent.getId(), game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
target.add(permanent.getId(), game); target.add(permanent.getId(), game);
return true; return true;
@ -353,7 +361,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(permanent.getId(), game)) { if (target.canTarget(permanent.getId(), game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
target.add(permanent.getId(), game); target.add(permanent.getId(), game);
return true; return true;
@ -362,6 +370,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetCardInGraveyard) { if (target.getOriginalTarget() instanceof TargetCardInGraveyard) {
List<Card> cards = new ArrayList<>(); List<Card> cards = new ArrayList<>();
for (Player player : game.getPlayers().values()) { for (Player player : game.getPlayers().values()) {
@ -395,15 +404,15 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetSource) { if (target.getOriginalTarget() instanceof TargetSource) {
Set<UUID> targets; Set<UUID> targets;
TargetSource t = ((TargetSource) target); targets = target.possibleTargets(sourceId, abilityControllerId, game);
targets = t.possibleTargets(sourceId, abilityControllerId, game);
for (UUID targetId : targets) { for (UUID targetId : targets) {
MageObject targetObject = game.getObject(targetId); MageObject targetObject = game.getObject(targetId);
if (targetObject != null) { if (targetObject != null) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(targetObject.getId(), game)) { if (target.canTarget(targetObject.getId(), game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(targetObject.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(targetObject.getId())) {
target.add(targetObject.getId(), game); target.add(targetObject.getId(), game);
return true; return true;
@ -444,8 +453,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return setTargetPlayer(outcome, target, source, source.getSourceId(), abilityControllerId, randomOpponentId, game); return setTargetPlayer(outcome, target, source, source.getSourceId(), abilityControllerId, randomOpponentId, game);
} }
if (target.getOriginalTarget() instanceof TargetDiscard || target.getOriginalTarget() instanceof TargetCardInHand) { if (target.getOriginalTarget() instanceof TargetDiscard
|| target.getOriginalTarget() instanceof TargetCardInHand) {
if (outcome.isGood()) { if (outcome.isGood()) {
// good
Cards cards = new CardsImpl(target.possibleTargets(source.getSourceId(), getId(), game)); Cards cards = new CardsImpl(target.possibleTargets(source.getSourceId(), getId(), game));
ArrayList<Card> cardsInHand = new ArrayList<>(cards.getCards(game)); ArrayList<Card> cardsInHand = new ArrayList<>(cards.getCards(game));
while (!target.isChosen() while (!target.isChosen()
@ -463,6 +474,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
} }
} else { } else {
// bad
findPlayables(game); findPlayables(game);
if (!unplayable.isEmpty()) { if (!unplayable.isEmpty()) {
for (int i = unplayable.size() - 1; i >= 0; i--) { for (int i = unplayable.size() - 1; i >= 0; i--) {
@ -487,9 +499,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetControlledPermanent) { if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
List<Permanent> targets; List<Permanent> targets;
targets = threats(abilityControllerId, source.getSourceId(), ((TargetControlledPermanent) target).getFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source.getSourceId(), origTarget.getFilter(), game, target.getTargets());
if (!outcome.isGood()) { if (!outcome.isGood()) {
Collections.reverse(targets); Collections.reverse(targets);
} }
@ -504,9 +518,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetPermanent) { if (target.getOriginalTarget() instanceof TargetPermanent) {
List<Permanent> targets; List<Permanent> targets;
TargetPermanent t = (TargetPermanent) target.getOriginalTarget(); TargetPermanent origTarget = (TargetPermanent) target.getOriginalTarget();
boolean outcomeTargets = true; boolean outcomeTargets = true;
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), ((TargetPermanent) target).getFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), ((TargetPermanent) target).getFilter(), game, target.getTargets());
@ -520,7 +535,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
//targets = game.getBattlefield().getActivePermanents(((TargetPermanent)target).getFilter(), playerId, game); //targets = game.getBattlefield().getActivePermanents(((TargetPermanent)target).getFilter(), playerId, game);
} }
if (targets.isEmpty() && target.isRequired()) { if (targets.isEmpty() && target.isRequired()) {
targets = game.getBattlefield().getActivePermanents(t.getFilter(), playerId, game); targets = game.getBattlefield().getActivePermanents(origTarget.getFilter(), playerId, game);
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
@ -532,13 +547,14 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) { if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) {
List<Permanent> targets; List<Permanent> targets;
TargetCreatureOrPlayer t = ((TargetCreatureOrPlayer) target); TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target);
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source.getSourceId(), ((FilterCreatureOrPlayer) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source.getSourceId(), ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, source.getSourceId(), ((FilterCreatureOrPlayer) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(randomOpponentId, source.getSourceId(), ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} }
if (targets.isEmpty()) { if (targets.isEmpty()) {
@ -552,11 +568,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
if (targets.isEmpty() && target.isRequired(source)) { if (targets.isEmpty() && target.isRequired(source)) {
targets = game.getBattlefield().getActivePermanents(((FilterCreatureOrPlayer) t.getFilter()).getCreatureFilter(), playerId, game); targets = game.getBattlefield().getActivePermanents(((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), playerId, game);
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), source, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
return tryAddTarget(target, permanent.getId(), source, game); return tryAddTarget(target, permanent.getId(), source, game);
} }
@ -574,13 +590,14 @@ public class ComputerPlayer extends PlayerImpl implements Player {
//if (!target.isRequired()) //if (!target.isRequired())
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetAnyTarget) { if (target.getOriginalTarget() instanceof TargetAnyTarget) {
List<Permanent> targets; List<Permanent> targets;
TargetAnyTarget t = ((TargetAnyTarget) target); TargetAnyTarget origTarget = ((TargetAnyTarget) target);
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source.getSourceId(), ((FilterCreaturePlayerOrPlaneswalker) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source.getSourceId(), ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, source.getSourceId(), ((FilterCreaturePlayerOrPlaneswalker) t.getFilter()).getCreatureFilter(), game, target.getTargets()); targets = threats(randomOpponentId, source.getSourceId(), ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} }
if (targets.isEmpty()) { if (targets.isEmpty()) {
@ -594,11 +611,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
if (targets.isEmpty() && target.isRequired(source)) { if (targets.isEmpty() && target.isRequired(source)) {
targets = game.getBattlefield().getActivePermanents(((FilterCreaturePlayerOrPlaneswalker) t.getFilter()).getCreatureFilter(), playerId, game); targets = game.getBattlefield().getActivePermanents(((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), playerId, game);
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), source, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
tryAddTarget(target, permanent.getId(), source, game); tryAddTarget(target, permanent.getId(), source, game);
} }
@ -616,13 +633,14 @@ public class ComputerPlayer extends PlayerImpl implements Player {
//if (!target.isRequired()) //if (!target.isRequired())
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) { if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
List<Permanent> targets; List<Permanent> targets;
TargetPermanentOrPlayer t = ((TargetPermanentOrPlayer) target); TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target);
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
} }
if (targets.isEmpty()) { if (targets.isEmpty()) {
@ -636,11 +654,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
if (targets.isEmpty() && target.isRequired(source)) { if (targets.isEmpty() && target.isRequired(source)) {
targets = game.getBattlefield().getActivePermanents(((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), playerId, game); targets = game.getBattlefield().getActivePermanents(((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), playerId, game);
} }
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), source, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
return tryAddTarget(target, permanent.getId(), source, game); return tryAddTarget(target, permanent.getId(), source, game);
} }
@ -650,13 +668,27 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetPlayerOrPlaneswalker) { if (target.getOriginalTarget() instanceof TargetPlayerOrPlaneswalker) {
List<Permanent> targets; List<Permanent> targets;
TargetPlayerOrPlaneswalker t = ((TargetPlayerOrPlaneswalker) target); TargetPlayerOrPlaneswalker origTarget = ((TargetPlayerOrPlaneswalker) target);
// TODO: if effect is bad and no opponent's targets available then AI can't target yourself but must by rules
/*
battlefield:Computer:Mountain:5
hand:Computer:Viashino Pyromancer:3
battlefield:Human:Shalai, Voice of Plenty:1
*/
// TODO: in multiplayer game there many opponents - if random opponents don't have targets then AI must use next opponent, but it skips
// (e.g. you randomOpponentId must be replaced by List<UUID> randomOpponents)
// normal cycle (good for you, bad for opponents)
// possible good/bad permanents
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) t.getFilter()).getPermanentFilter(), game, target.getTargets()); targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
} }
// possible good/bad players
if (targets.isEmpty()) { if (targets.isEmpty()) {
if (outcome.isGood()) { if (outcome.isGood()) {
if (target.canTarget(getId(), abilityControllerId, source, game)) { if (target.canTarget(getId(), abilityControllerId, source, game)) {
@ -667,18 +699,22 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
} }
// can't find targets (e.g. effect is bad, but you need take targets from yourself)
if (targets.isEmpty() && target.isRequired(source)) { if (targets.isEmpty() && target.isRequired(source)) {
targets = game.getBattlefield().getActivePermanents(((TargetPlayerOrPlaneswalker) t.getFilter()).getFilterPermanent(), playerId, game); targets = game.getBattlefield().getActivePermanents(origTarget.getFilterPermanent(), playerId, game);
} }
// try target permanent
for (Permanent permanent : targets) { for (Permanent permanent : targets) {
List<UUID> alreadyTargeted = target.getTargets(); List<UUID> alreadyTargeted = target.getTargets();
if (t.canTarget(abilityControllerId, permanent.getId(), source, game)) { if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) { if (alreadyTargeted != null && !alreadyTargeted.contains(permanent.getId())) {
return tryAddTarget(target, permanent.getId(), source, game); return tryAddTarget(target, permanent.getId(), source, game);
} }
} }
} }
// try target player as normal
if (outcome.isGood()) { if (outcome.isGood()) {
if (target.canTarget(getId(), abilityControllerId, source, game)) { if (target.canTarget(getId(), abilityControllerId, source, game)) {
return tryAddTarget(target, abilityControllerId, source, game); return tryAddTarget(target, abilityControllerId, source, game);
@ -703,6 +739,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
//if (!target.isRequired()) //if (!target.isRequired())
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetCardInLibrary) { if (target.getOriginalTarget() instanceof TargetCardInLibrary) {
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getLibrary().getCards(game)); List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getLibrary().getCards(game));
Card card = pickTarget(cards, outcome, target, source, game); Card card = pickTarget(cards, outcome, target, source, game);
@ -711,6 +748,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard) { if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard) {
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards((FilterCard) target.getFilter(), game)); List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards((FilterCard) target.getFilter(), game));
while (!target.isChosen() && !cards.isEmpty()) { while (!target.isChosen() && !cards.isEmpty()) {
@ -722,6 +760,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetSpell) { if (target.getOriginalTarget() instanceof TargetSpell) {
if (!game.getStack().isEmpty()) { if (!game.getStack().isEmpty()) {
for (StackObject o : game.getStack()) { for (StackObject o : game.getStack()) {
@ -732,17 +771,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetSpellOrPermanent) { if (target.getOriginalTarget() instanceof TargetSpellOrPermanent) {
// TODO: Also check if a spell should be selected // TODO: Also check if a spell should be selected
TargetSpellOrPermanent origTarget = (TargetSpellOrPermanent) target.getOriginalTarget();
List<Permanent> targets; List<Permanent> targets;
boolean outcomeTargets = true; boolean outcomeTargets = true;
if (outcome.isGood()) { if (outcome.isGood()) {
targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), ((TargetSpellOrPermanent) target).getPermanentFilter(), game, target.getTargets()); targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
} else { } else {
targets = threats(randomOpponentId, source == null ? null : source.getSourceId(), ((TargetSpellOrPermanent) target).getPermanentFilter(), game, target.getTargets()); targets = threats(randomOpponentId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
} }
if (targets.isEmpty() && target.isRequired(source)) { if (targets.isEmpty() && target.isRequired(source)) {
targets = threats(null, source == null ? null : source.getSourceId(), ((TargetSpellOrPermanent) target).getPermanentFilter(), game, target.getTargets()); targets = threats(null, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
Collections.reverse(targets); Collections.reverse(targets);
outcomeTargets = false; outcomeTargets = false;
} }
@ -765,6 +806,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetCardInOpponentsGraveyard) { if (target.getOriginalTarget() instanceof TargetCardInOpponentsGraveyard) {
List<Card> cards = new ArrayList<>(); List<Card> cards = new ArrayList<>();
for (UUID uuid : game.getOpponents(abilityControllerId)) { for (UUID uuid : game.getOpponents(abilityControllerId)) {
@ -780,6 +822,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
//if (!target.isRequired()) //if (!target.isRequired())
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetDefender) { if (target.getOriginalTarget() instanceof TargetDefender) {
// TODO: Improve, now planeswalker is always chosen if it exits // TODO: Improve, now planeswalker is always chosen if it exits
List<Permanent> targets; List<Permanent> targets;
@ -834,6 +877,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetActivatedAbility) { if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
List<StackObject> stackObjects = new ArrayList<>(); List<StackObject> stackObjects = new ArrayList<>();
for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) { for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
@ -924,6 +968,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return false; return false;
} }
if (target.getOriginalTarget() instanceof TargetCreatureOrPlaneswalkerAmount) { if (target.getOriginalTarget() instanceof TargetCreatureOrPlaneswalkerAmount) {
List<Permanent> targets; List<Permanent> targets;
if (outcome.isGood()) { if (outcome.isGood()) {
@ -965,6 +1010,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
} }
} }
log.warn("No proper AI target handling: " + target.getClass().getName()); log.warn("No proper AI target handling: " + target.getClass().getName());
return false; return false;
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-ai-mcts</artifactId> <artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-aiminimax</artifactId> <artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-player-human</artifactId> <artifactId>mage-player-human</artifactId>

View file

@ -934,19 +934,23 @@ public class HumanPlayer extends PlayerImpl {
if (object != null) { if (object != null) {
Zone zone = game.getState().getZone(object.getId()); Zone zone = game.getState().getZone(object.getId());
if (zone != null) { if (zone != null) {
if (object instanceof Card // look at card or try to cast/activate abilities
&& ((Card) object).isFaceDown(game)
&& lookAtFaceDownCard((Card) object, game)) {
result = true;
} else {
Player actingPlayer = null; Player actingPlayer = null;
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = null;
if (playerId.equals(game.getPriorityPlayerId())) { if (playerId.equals(game.getPriorityPlayerId())) {
actingPlayer = this; actingPlayer = this;
} else if (getPlayersUnderYourControl().contains(game.getPriorityPlayerId())) { } else if (getPlayersUnderYourControl().contains(game.getPriorityPlayerId())) {
actingPlayer = game.getPlayer(game.getPriorityPlayerId()); actingPlayer = game.getPlayer(game.getPriorityPlayerId());
} }
if (actingPlayer != null) { if (actingPlayer != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = actingPlayer.getUseableActivatedAbilities(object, zone, game); useableAbilities = actingPlayer.getUseableActivatedAbilities(object, zone, game);
}
if (object instanceof Card
&& ((Card) object).isFaceDown(game)
&& lookAtFaceDownCard((Card) object, game, useableAbilities == null ? 0 : useableAbilities.size())) {
result = true;
} else {
if (useableAbilities != null if (useableAbilities != null
&& !useableAbilities.isEmpty()) { && !useableAbilities.isEmpty()) {
activateAbility(useableAbilities, object, game); activateAbility(useableAbilities, object, game);
@ -955,7 +959,6 @@ public class HumanPlayer extends PlayerImpl {
} }
} }
} }
}
return result; return result;
} else return response.getManaType() == null; } else return response.getManaType() == null;
return true; return true;

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-tournament-boosterdraft</artifactId> <artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-tournament-constructed</artifactId> <artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-tournament-sealed</artifactId> <artifactId>mage-tournament-sealed</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
@ -25,6 +25,7 @@
<module>Mage.Game.TinyLeadersDuel</module> <module>Mage.Game.TinyLeadersDuel</module>
<module>Mage.Game.CanadianHighlanderDuel</module> <module>Mage.Game.CanadianHighlanderDuel</module>
<module>Mage.Game.PennyDreadfulCommanderFreeForAll</module> <module>Mage.Game.PennyDreadfulCommanderFreeForAll</module>
<module>Mage.Game.FreeformCommanderDuel</module>
<module>Mage.Game.FreeformCommanderFreeForAll</module> <module>Mage.Game.FreeformCommanderFreeForAll</module>
<module>Mage.Game.BrawlDuel</module> <module>Mage.Game.BrawlDuel</module>
<module>Mage.Game.BrawlFreeForAll</module> <module>Mage.Game.BrawlFreeForAll</module>

View file

@ -79,6 +79,7 @@
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/> <gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
<gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/> <gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/>
<gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/> <gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/>
<gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>
<gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/> <gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-server</artifactId> <artifactId>mage-server</artifactId>
@ -184,6 +184,12 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage-game-freeformcommanderduel</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>

View file

@ -73,6 +73,7 @@
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel-${project.version}.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/> <gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel-${project.version}.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
<gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel-${project.version}.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/> <gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel-${project.version}.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/>
<gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall-${project.version}.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/> <gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall-${project.version}.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/>
<gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel-${project.version}.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall-${project.version}.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall-${project.version}.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel-${project.version}.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel-${project.version}.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>
<gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall-${project.version}.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/> <gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall-${project.version}.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/>

View file

@ -1,11 +1,5 @@
package mage.server; package mage.server;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import mage.server.User.UserState; import mage.server.User.UserState;
import mage.server.record.UserStats; import mage.server.record.UserStats;
import mage.server.record.UserStatsRepository; import mage.server.record.UserStatsRepository;
@ -13,6 +7,12 @@ import mage.server.util.ThreadExecutor;
import mage.view.UserView; import mage.view.UserView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
* manages users - if a user is disconnected and 10 minutes have passed with no * manages users - if a user is disconnected and 10 minutes have passed with no
* activity the user is removed * activity the user is removed
@ -22,6 +22,9 @@ import org.apache.log4j.Logger;
public enum UserManager { public enum UserManager {
instance; instance;
private static final int SERVER_TIMEOUTS_USER_DISCONNECT_FROM_SERVER_AFTER_SECS = 3 * 60; // removes from all games and chats too (can be seen in users list with disconnected status)
private static final int SERVER_TIMEOUTS_USER_REMOVE_FROM_SERVER_AFTER_SECS = 8 * 60; // removes from users list
private static final Logger logger = Logger.getLogger(UserManager.class); private static final Logger logger = Logger.getLogger(UserManager.class);
protected final ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor(); protected final ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor();
@ -58,7 +61,7 @@ public enum UserManager {
public Optional<User> getUser(UUID userId) { public Optional<User> getUser(UUID userId) {
if (!users.containsKey(userId)) { if (!users.containsKey(userId)) {
logger.warn(String.format("User with id %s could not be found", userId), new Throwable()); // TODO: remove after session freezes fixed //logger.warn(String.format("User with id %s could not be found", userId), new Throwable()); // TODO: remove after session freezes fixed
return Optional.empty(); return Optional.empty();
} else { } else {
return Optional.of(users.get(userId)); return Optional.of(users.get(userId));
@ -155,16 +158,15 @@ public enum UserManager {
/** /**
* Is the connection lost for more than 3 minutes, the user will be set to * Is the connection lost for more than 3 minutes, the user will be set to
* offline status. The user will be removed in validity check after 15 * offline status. The user will be removed in validity check after 8
* minutes of no activities * minutes of no activities
*
*/ */
private void checkExpired() { private void checkExpired() {
try { try {
Calendar calendarExp = Calendar.getInstance(); Calendar calendarExp = Calendar.getInstance();
calendarExp.add(Calendar.MINUTE, -3); calendarExp.add(Calendar.SECOND, -1 * SERVER_TIMEOUTS_USER_DISCONNECT_FROM_SERVER_AFTER_SECS);
Calendar calendarRemove = Calendar.getInstance(); Calendar calendarRemove = Calendar.getInstance();
calendarRemove.add(Calendar.MINUTE, -8); calendarRemove.add(Calendar.SECOND, -1 * SERVER_TIMEOUTS_USER_REMOVE_FROM_SERVER_AFTER_SECS);
List<User> toRemove = new ArrayList<>(); List<User> toRemove = new ArrayList<>();
logger.debug("Start Check Expired"); logger.debug("Start Check Expired");
ArrayList<User> userList = new ArrayList<>(); ArrayList<User> userList = new ArrayList<>();
@ -179,18 +181,18 @@ public enum UserManager {
try { try {
if (user.getUserState() == UserState.Offline) { if (user.getUserState() == UserState.Offline) {
if (user.isExpired(calendarRemove.getTime())) { if (user.isExpired(calendarRemove.getTime())) {
// removes from users list
toRemove.add(user); toRemove.add(user);
} }
} else { } else {
if (user.isExpired(calendarExp.getTime())) { if (user.isExpired(calendarExp.getTime())) {
// set disconnected status and removes from all activities (tourney/tables/games/drafts/chats)
if (user.getUserState() == UserState.Connected) { if (user.getUserState() == UserState.Connected) {
user.lostConnection(); user.lostConnection();
disconnect(user.getId(), DisconnectReason.BecameInactive); disconnect(user.getId(), DisconnectReason.BecameInactive);
} }
removeUserFromAllTablesAndChat(user.getId(), DisconnectReason.SessionExpired); removeUserFromAllTablesAndChat(user.getId(), DisconnectReason.SessionExpired);
user.setUserState(UserState.Offline); user.setUserState(UserState.Offline);
// Remove the user from all tournaments
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -215,7 +217,6 @@ public enum UserManager {
/** /**
* This method recreated the user list that will be send to all clients * This method recreated the user list that will be send to all clients
*
*/ */
private void updateUserInfoList() { private void updateUserInfoList() {
try { try {

View file

@ -49,6 +49,9 @@ import java.util.zip.GZIPOutputStream;
*/ */
public class GameController implements GameCallback { public class GameController implements GameCallback {
private static final int GAME_TIMEOUTS_CHECK_JOINING_STATUS_EVERY_SECS = 15; // checks and inform players about joining status
private static final int GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS = 4 * 60; // leave player from game if it don't join and inactive on server
private static final ExecutorService gameExecutor = ThreadExecutor.instance.getGameExecutor(); private static final ExecutorService gameExecutor = ThreadExecutor.instance.getGameExecutor();
private static final Logger logger = Logger.getLogger(GameController.class); private static final Logger logger = Logger.getLogger(GameController.class);
@ -226,7 +229,7 @@ public class GameController implements GameCallback {
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("Send info about player not joined yet:", ex); logger.fatal("Send info about player not joined yet:", ex);
} }
}, 15, 15, TimeUnit.SECONDS); }, GAME_TIMEOUTS_CHECK_JOINING_STATUS_EVERY_SECS, GAME_TIMEOUTS_CHECK_JOINING_STATUS_EVERY_SECS, TimeUnit.SECONDS);
checkStart(); checkStart();
} }
@ -320,6 +323,7 @@ public class GameController implements GameCallback {
} }
private void sendInfoAboutPlayersNotJoinedYet() { private void sendInfoAboutPlayersNotJoinedYet() {
// runs every 15 secs untill all players join
for (Player player : game.getPlayers().values()) { for (Player player : game.getPlayers().values()) {
if (!player.hasLeft() && player.isHuman()) { if (!player.hasLeft() && player.isHuman()) {
Optional<User> requestedUser = getUserByPlayerId(player.getId()); Optional<User> requestedUser = getUserByPlayerId(player.getId());
@ -333,12 +337,12 @@ public class GameController implements GameCallback {
logger.debug("Player " + player.getName() + " (disconnected) has joined gameId: " + game.getId()); logger.debug("Player " + player.getName() + " (disconnected) has joined gameId: " + game.getId());
} }
ChatManager.instance.broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
if (user.getSecondsDisconnected() > 240) { if (user.getSecondsDisconnected() > GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS) {
// TODO: 2019.04.22 - if user playing another game on server but not joining (that's the reason?), then that's check will never trigger
// Cancel player join possibility lately after 4 minutes // Cancel player join possibility lately after 4 minutes
logger.debug("Player " + player.getName() + " - canceled game (after 240 seconds) gameId: " + game.getId()); logger.debug("Player " + player.getName() + " - canceled game (after 240 seconds) gameId: " + game.getId());
player.leave(); player.leave();
} }
} }
} else if (!player.hasLeft()) { } else if (!player.hasLeft()) {
logger.debug("Player " + player.getName() + " canceled game (no user) gameId: " + game.getId()); logger.debug("Player " + player.getName() + " canceled game (no user) gameId: " + game.getId());

View file

@ -12,6 +12,7 @@ import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.GameCommanderImpl;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.RandomUtil; import mage.util.RandomUtil;
@ -31,7 +32,8 @@ import java.util.stream.Collectors;
*/ */
public final class SystemUtil { public final class SystemUtil {
private SystemUtil(){} private SystemUtil() {
}
public static final DateFormat dateFormat = new SimpleDateFormat("yy-M-dd HH:mm:ss"); public static final DateFormat dateFormat = new SimpleDateFormat("yy-M-dd HH:mm:ss");
@ -485,6 +487,8 @@ public final class SystemUtil {
gameZone = Zone.COMMAND; gameZone = Zone.COMMAND;
} else if ("plane".equalsIgnoreCase(command.zone)) { } else if ("plane".equalsIgnoreCase(command.zone)) {
gameZone = Zone.COMMAND; gameZone = Zone.COMMAND;
} else if ("commander".equalsIgnoreCase(command.zone)) {
gameZone = Zone.COMMAND;
} else { } else {
logger.warn("Unknown zone [" + command.zone + "]: " + line); logger.warn("Unknown zone [" + command.zone + "]: " + line);
continue; continue;
@ -513,10 +517,25 @@ public final class SystemUtil {
} }
} }
game.loadCards(cardsToLoad, player.getId()); game.loadCards(cardsToLoad, player.getId());
if ("commander".equalsIgnoreCase(command.zone) && cardsToLoad.size() > 0) {
// as commander (only commander games, look at init code in GameCommanderImpl)
if (game instanceof GameCommanderImpl) {
GameCommanderImpl gameCommander = (GameCommanderImpl) game;
for (Card card : cardsToLoad) {
player.addCommanderId(card.getId());
gameCommander.initCommander(card, player);
}
} else {
logger.fatal("Commander card can be used in commander game only: " + command.cardName);
}
} else {
// as other card
for (Card card : cardsToLoad) { for (Card card : cardsToLoad) {
swapWithAnyCard(game, player, card, gameZone); swapWithAnyCard(game, player, card, gameZone);
} }
} }
}
} catch (Exception e) { } catch (Exception e) {
logger.fatal("", e); logger.fatal("", e);
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.34</version> <version>1.4.35</version>
</parent> </parent>
<artifactId>mage-sets</artifactId> <artifactId>mage-sets</artifactId>

View file

@ -81,7 +81,7 @@ class AchHansRunEffect extends OneShotEffect {
FilterCard nameFilter = new FilterCard(); FilterCard nameFilter = new FilterCard();
nameFilter.add(new NamePredicate(cardName)); nameFilter.add(new NamePredicate(cardName));
TargetCardInLibrary target = new TargetCardInLibrary(1, 1, nameFilter); TargetCardInLibrary target = new TargetCardInLibrary(1, 1, nameFilter);
if (!controller.searchLibrary(target, game)) { if (!controller.searchLibrary(target, source, game)) {
return false; return false;
} }
Card card = controller.getLibrary().remove(target.getFirstTarget(), game); Card card = controller.getLibrary().remove(target.getFirstTarget(), game);

View file

@ -63,7 +63,7 @@ class AcquireEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (opponent != null && controller != null) { if (opponent != null && controller != null) {
TargetCardInLibrary target = new TargetCardInLibrary(filter); TargetCardInLibrary target = new TargetCardInLibrary(filter);
controller.searchLibrary(target, game, opponent.getId()); controller.searchLibrary(target, source, game, opponent.getId());
Card targetCard = game.getCard(target.getFirstTarget()); Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard != null) { if (targetCard != null) {
controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game);

Some files were not shown because too many files have changed in this diff Show more