Added some tooltips to user table headers. History is shown in tournament player table now. Changed ratio column to numberic format.

This commit is contained in:
LevelX2 2016-02-06 21:22:51 +01:00
parent 82fed1ed87
commit 687ab7ec6b
18 changed files with 239 additions and 89 deletions

View file

@ -42,7 +42,7 @@
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.3</version>
</dependency>
</dependency>
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
@ -73,12 +73,12 @@
<artifactId>forms_rt</artifactId>
<version>7.0.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage-counter-plugin</artifactId>
@ -131,8 +131,13 @@
<artifactId>tritonus_share</artifactId>
<version>0.3.6</version>
</dependency>
<dependency>
<groupId>net.java.balloontip</groupId>
<artifactId>balloontip</artifactId>
<version>1.2.4.1</version>
</dependency>
</dependencies>
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->
<repositories>
<repository>
@ -140,7 +145,7 @@
<url>file://${project.basedir}/../repository</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
@ -183,7 +188,7 @@
<finalName>mage-client</finalName>
</build>
<properties>
<manifest.file>src/main/resources/META-INF/MANIFEST.MF</manifest.file>
</properties>

View file

@ -128,6 +128,9 @@ import mage.remote.SessionImpl;
import mage.utils.MageVersion;
import mage.view.GameEndView;
import mage.view.UserRequestMessage;
import net.java.balloontip.BalloonTip;
import net.java.balloontip.positioners.LeftAbovePositioner;
import net.java.balloontip.styles.EdgedBalloonStyle;
import net.java.truevfs.access.TArchiveDetector;
import net.java.truevfs.access.TConfig;
import net.java.truevfs.kernel.spec.FsAccessOption;
@ -176,6 +179,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static long startTime;
private BalloonTip balloonTip;
/**
* @return the session
*/
@ -298,6 +303,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
});
// balloonTip = new BalloonTip(desktopPane, "", new ModernBalloonStyle(0, 0, Color.WHITE, Color.YELLOW, Color.BLUE), false);
balloonTip = new BalloonTip(desktopPane, "", new EdgedBalloonStyle(Color.WHITE, Color.BLUE), false);
balloonTip.setPositioner(new LeftAbovePositioner(0, 0));
mageToolbar.add(new javax.swing.JToolBar.Separator());
mageToolbar.add(createWindowsButton());
@ -352,6 +361,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_CHECK, "false").equals("true")) {
checkForNewImages();
}
updateMemUsageTask.execute();
LOGGER.info("Client start up time: " + ((System.currentTimeMillis() - startTime) / 1000 + " seconds"));
if (autoConnect()) {
@ -360,6 +370,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
connectDialog.showDialog();
}
setWindowTitle();
}
});
@ -1043,11 +1054,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (setActive) {
setActive(tablesPane);
} else // if other panel was already shown, mamke sure it's topmost again
{
if (topPanebefore != null) {
if (topPanebefore != null) {
setActive(topPanebefore);
}
}
}
public void hideGames() {
@ -1291,6 +1300,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
DRAFTS.put(draftId, draftPanel);
}
public BalloonTip getBalloonTip() {
return balloonTip;
}
@Override
public void connected(final String message) {
if (SwingUtilities.isEventDispatchThread()) {

View file

@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>

View file

@ -24,14 +24,13 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
/*
/*
* MagePane.java
*
* Created on 15-Dec-2009, 9:34:25 PM
*/
package mage.client;
import java.awt.KeyboardFocusManager;
@ -46,9 +45,11 @@ import org.apache.log4j.Logger;
*/
public abstract class MagePane extends javax.swing.JInternalFrame {
private static final Logger logger = Logger.getLogger(MagePane.class);
private static final Logger LOGGER = Logger.getLogger(MagePane.class);
/** Creates new form MagePane */
/**
* Creates new form MagePane
*/
public MagePane() {
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
initComponents();
@ -90,10 +91,10 @@ public abstract class MagePane extends javax.swing.JInternalFrame {
}
/** 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.
/**
* 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
@ -115,8 +116,6 @@ public abstract class MagePane extends javax.swing.JInternalFrame {
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

View file

@ -60,7 +60,8 @@ import org.apache.log4j.Logger;
*/
public class TableWaitingDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(TableWaitingDialog.class);
private static final Logger LOGGER = Logger.getLogger(TableWaitingDialog.class);
private static final int[] DEFAULT_COLUMS_WIDTH = {20, 50, 100, 100, 100};
private UUID tableId;
private UUID roomId;
@ -68,7 +69,6 @@ public class TableWaitingDialog extends MageDialog {
private Session session;
private final TableWaitModel tableWaitModel;
private UpdateSeatsTask updateTask;
private static final int[] defaultColumnsWidth = {20, 50, 100, 100, 100};
/**
* Creates new form TableWaitingDialog
@ -88,7 +88,7 @@ public class TableWaitingDialog extends MageDialog {
chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
tableSeats.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableSeats, defaultColumnsWidth, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
TableUtil.setColumnWidthAndOrder(tableSeats, DEFAULT_COLUMS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer());
MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart);
@ -280,7 +280,7 @@ public class TableWaitingDialog extends MageDialog {
}
} catch (Exception e) {
//swallow exception
logger.error(e);
LOGGER.error(e);
}
closeDialog();
}//GEN-LAST:event_btnCancelActionPerformed

View file

@ -34,14 +34,21 @@
package mage.client.table;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import mage.client.MageFrame;
import mage.client.chat.ChatPanelBasic;
import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA;
import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_ORDER;
@ -52,6 +59,7 @@ import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.remote.MageRemoteException;
import mage.view.RoomUsersView;
import mage.view.UsersView;
import net.java.balloontip.utils.ToolTipUtils;
/**
*
@ -79,6 +87,8 @@ public class PlayersChatPanel extends javax.swing.JPanel {
jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel));
TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER);
userTableModel.initHeaderTooltips();
jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem);
@ -169,10 +179,61 @@ public class PlayersChatPanel extends javax.swing.JPanel {
return "";
}
public void initHeaderTooltips() {
ColumnHeaderToolTips tips = new ColumnHeaderToolTips();
for (int c = 0; c < jTablePlayers.getColumnCount(); c++) {
String tooltipText = "";
switch (c) {
case 0:
tooltipText = "<HTML><b>The flag the user has assigned to his profile</b>"
+ "<br>You can assign the flag in the connect to server dialog window";
break;
case 1:
tooltipText = "<HTML><b>Name of the user</b>"
+ "<br>(the number behind the header text is the number of currently connected users to the server)";
break;
case 2:
tooltipText = "<HTML><b>Number of matches the user played so far</b>"
+ "<br>Q = number of matches quit"
+ "<br>I = number of matches lost because of idle timeout"
+ "<br>T = number of matches lost because of match timeout";
break;
case 3:
tooltipText = "<HTML><b>%-Ratio of matches played to matches quit</b>"
+ "<br>this calculation does not include tournament matches";
break;
case 4:
tooltipText = "<HTML><b>Number of tournaments the user played so far</b>"
+ "<br>D = number of tournaments left during draft phase"
+ "<br>C = number of tournaments left during constructing phase"
+ "<br>R = number of tournaments left during rounds";
break;
case 5:
tooltipText = "<HTML><b>%-Ratio of tournament matches played to tournament matches quit</b>"
+ "<br>this calculation does not include non tournament matches";
break;
case 6:
tooltipText = "<HTML><b>Current activities of the player</b>"
+ "<BR>the header itself shows the number of currently active games"
+ "<BR>T: = number of games threads "
+ "<BR><i>(that can vary from active games because of sideboarding or crashed games)</i>"
+ "<BR>limt: the maximum of games the server is configured to"
+ "<BR><i>(if the number of started games exceed that limit, the games have to wait"
+ "<BR>until active games end)</i>";
break;
case 7:
tooltipText = "<HTML><b>Latency of the user's connection to the server</b>";
break;
}
tips.setToolTip(c, tooltipText);
}
JTableHeader header = jTablePlayers.getTableHeader();
header.addMouseMotionListener(tips);
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
@ -185,6 +246,9 @@ public class PlayersChatPanel extends javax.swing.JPanel {
switch (columnIndex) {
case 0:
return Icon.class;
case 3:
case 5:
return Integer.class;
default:
return String.class;
}
@ -290,4 +354,41 @@ public class PlayersChatPanel extends javax.swing.JPanel {
private javax.swing.JTabbedPane jTabbedPaneText;
private javax.swing.JTable jTablePlayers;
// End of variables declaration//GEN-END:variables
class ColumnHeaderToolTips extends MouseMotionAdapter {
int curCol;
Map<Integer, String> tips = new HashMap<>();
public void setToolTip(Integer mCol, String tooltip) {
if (tooltip == null) {
tips.remove(mCol);
} else {
tips.put(mCol, tooltip);
}
}
@Override
public void mouseMoved(MouseEvent evt) {
JTableHeader header = (JTableHeader) evt.getSource();
JTable table = header.getTable();
TableColumnModel colModel = table.getColumnModel();
int vColIndex = colModel.getColumnIndexAtX(evt.getX());
TableColumn col = null;
if (vColIndex >= 0) {
col = colModel.getColumn(table.convertColumnIndexToModel(vColIndex));
}
if (table.convertColumnIndexToModel(vColIndex) != curCol) {
if (col != null) {
MageFrame.getInstance().getBalloonTip().setAttachedComponent(header);
MageFrame.getInstance().getBalloonTip().setTextContents(tips.get(table.convertColumnIndexToModel(vColIndex)));
ToolTipUtils.balloonToToolTip(MageFrame.getInstance().getBalloonTip(), 600, 10000);
} else {
MageFrame.getInstance().getBalloonTip().setTextContents("");
}
curCol = table.convertColumnIndexToModel(vColIndex);
}
}
}
}

View file

@ -674,4 +674,4 @@
</SubComponents>
</Container>
</SubComponents>
</Form>
</Form>

View file

@ -100,7 +100,8 @@ import org.apache.log4j.Logger;
*/
public class TablesPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(TablesPanel.class);
private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 60};
private TableTableModel tableModel;
private MatchesTableModel matchesModel;
@ -119,8 +120,6 @@ public class TablesPanel extends javax.swing.JPanel {
JToggleButton[] filterButtons;
private static final int[] defaultColumnsWidth = {35, 150, 120, 180, 80, 120, 80, 60, 40, 60};
/**
* Creates new form TablesPanel
*/
@ -138,7 +137,7 @@ public class TablesPanel extends javax.swing.JPanel {
activeTablesSorter = new MageTableRowSorter(tableModel);
tableTables.setRowSorter(activeTablesSorter);
TableUtil.setColumnWidthAndOrder(tableTables, defaultColumnsWidth,
TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH,
PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER);
tableCompleted.setRowSorter(new MageTableRowSorter(matchesModel));
@ -187,18 +186,18 @@ public class TablesPanel extends javax.swing.JPanel {
try {
frame.setSelected(true);
} catch (PropertyVetoException ve) {
logger.error(ve);
LOGGER.error(ve);
}
}
}
} catch (InterruptedException ex) {
logger.error(ex);
LOGGER.error(ex);
}
return;
}
if (isTournament) {
logger.info("Joining tournament " + tableId);
LOGGER.info("Joining tournament " + tableId);
if (deckType.startsWith("Limited")) {
if (!status.endsWith("PW")) {
session.joinTournamentTable(roomId, tableId, session.getUserName(), "Human", 1, null, "");
@ -209,7 +208,7 @@ public class TablesPanel extends javax.swing.JPanel {
joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited"));
}
} else {
logger.info("Joining table " + tableId);
LOGGER.info("Joining table " + tableId);
joinTableDialog.showDialog(roomId, tableId, false, false);
}
break;
@ -220,18 +219,18 @@ public class TablesPanel extends javax.swing.JPanel {
break;
case "Show":
if (isTournament) {
logger.info("Showing tournament table " + tableId);
LOGGER.info("Showing tournament table " + tableId);
session.watchTable(roomId, tableId);
}
break;
case "Watch":
if (!isTournament) {
logger.info("Watching table " + tableId);
LOGGER.info("Watching table " + tableId);
session.watchTable(roomId, tableId);
}
break;
case "Replay":
logger.info("Replaying game " + gameId);
LOGGER.info("Replaying game " + gameId);
session.replayGame(gameId);
break;
}
@ -258,7 +257,7 @@ public class TablesPanel extends javax.swing.JPanel {
break;
case "Show":;
if (matchesModel.isTournament(modelRow)) {
logger.info("Showing tournament table " + matchesModel.getTableId(modelRow));
LOGGER.info("Showing tournament table " + matchesModel.getTableId(modelRow));
session.watchTable(roomId, matchesModel.getTableId(modelRow));
}
break;
@ -1177,7 +1176,7 @@ public class TablesPanel extends javax.swing.JPanel {
}//GEN-LAST:event_btnStateFinishedActionPerformed
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);
}

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
/*
/*
* TournamentPanel.java
*
* Created on 20-Jan-2011, 9:18:30 PM
@ -72,7 +72,10 @@ import org.apache.log4j.Logger;
*/
public class TournamentPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(TournamentPanel.class);
private static final Logger LOGGER = Logger.getLogger(TournamentPanel.class);
private static final int[] DEFAULT_COLUMNS_WIDTH_PLAYERS = {30, 150, 150, 60, 400, 100};
private static final int[] DEFAULT_COLUMNS_WIDTH_MATCHES = {60, 140, 140, 400, 80};
private UUID tournamentId;
private boolean firstInitDone = false;
@ -82,9 +85,6 @@ public class TournamentPanel extends javax.swing.JPanel {
private UpdateTournamentTask updateTask;
private final DateFormat df;
private static final int[] defaultColumnsWidthPlayers = {30, 150, 150, 60, 400};
private static final int[] defaultColumnsWidthMatches = {60, 140, 140, 400, 80};
/**
* Creates new form TournamentPanel
*/
@ -99,11 +99,11 @@ public class TournamentPanel extends javax.swing.JPanel {
df = DateFormat.getDateTimeInstance();
tablePlayers.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tablePlayers, defaultColumnsWidthPlayers, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER);
TableUtil.setColumnWidthAndOrder(tablePlayers, DEFAULT_COLUMNS_WIDTH_PLAYERS, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER);
tablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
tableMatches.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableMatches, defaultColumnsWidthMatches, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER);
TableUtil.setColumnWidthAndOrder(tableMatches, DEFAULT_COLUMNS_WIDTH_MATCHES, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER);
chatPanel1.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
chatPanel1.setChatType(ChatPanelBasic.ChatType.TOURNAMENT);
@ -123,7 +123,7 @@ public class TournamentPanel extends javax.swing.JPanel {
// session.replayGame(gameId);
// }
if (state.startsWith("Dueling") && actionText.equals("Watch")) {
logger.info("Watching game " + gameId);
LOGGER.info("Watching game " + gameId);
session.watchTournamentTable(tableId);
}
}
@ -545,7 +545,7 @@ public class TournamentPanel extends javax.swing.JPanel {
class TournamentPlayersTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Loc", "Player Name", "State", "Points", "Results"};
private final String[] columnNames = new String[]{"Loc", "Player Name", "State", "Points", "Results", "History"};
private TournamentPlayerView[] players = new TournamentPlayerView[0];
public void loadData(TournamentView tournament) {
@ -576,6 +576,8 @@ class TournamentPlayersTableModel extends AbstractTableModel {
return Integer.toString(players[arg0].getPoints());
case 4:
return players[arg0].getResults();
case 5:
return players[arg0].getHistory();
}
return "";
}

View file

@ -42,6 +42,7 @@ public class TournamentPlayerView implements Serializable, Comparable {
private final String name;
private final String state;
private final String results;
private final String history;
private final int points;
private final boolean quit;
@ -57,6 +58,7 @@ public class TournamentPlayerView implements Serializable, Comparable {
this.points = tournamentPlayer.getPoints();
this.results = tournamentPlayer.getResults();
this.quit = !tournamentPlayer.isInTournament();
this.history = tournamentPlayer.getPlayer().getUserData().getHistory();
this.flagName = tournamentPlayer.getPlayer().getUserData().getFlagName();
}
@ -88,4 +90,9 @@ public class TournamentPlayerView implements Serializable, Comparable {
public String getFlagName() {
return flagName;
}
public String getHistory() {
return history;
}
}

View file

@ -40,9 +40,9 @@ public class UsersView implements Serializable {
private final String flagName;
private final String userName;
private final String matchHistory;
private final String matchQuitRatio;
private final int matchQuitRatio;
private final String tourneyHistory;
private final String tourneyQuitRatio;
private final int tourneyQuitRatio;
private final String infoGames;
private final String infoPing;
@ -50,9 +50,9 @@ public class UsersView implements Serializable {
String tourneyHistory, int tourneyQuitRatio, String infoGames, String infoPing) {
this.flagName = flagName;
this.matchHistory = matchHistory;
this.matchQuitRatio = Integer.toString(matchQuitRatio);
this.matchQuitRatio = matchQuitRatio;
this.tourneyHistory = tourneyHistory;
this.tourneyQuitRatio = Integer.toString(tourneyQuitRatio);
this.tourneyQuitRatio = tourneyQuitRatio;
this.userName = userName;
this.infoGames = infoGames;
this.infoPing = infoPing;
@ -70,7 +70,7 @@ public class UsersView implements Serializable {
return matchHistory;
}
public String getMatchQuitRatio() {
public int getMatchQuitRatio() {
return matchQuitRatio;
}
@ -78,7 +78,7 @@ public class UsersView implements Serializable {
return tourneyHistory;
}
public String getTourneyQuitRatio() {
public int getTourneyQuitRatio() {
return tourneyQuitRatio;
}

View file

@ -63,9 +63,9 @@ import org.apache.log4j.Logger;
*/
public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private static final Logger logger = Logger.getLogger(GamesRoomImpl.class);
private static final Logger LOGGER = Logger.getLogger(GamesRoomImpl.class);
private static final ScheduledExecutorService updateExecutor = Executors.newSingleThreadScheduledExecutor();
private static final ScheduledExecutorService UPDATE_EXECUTOR = Executors.newSingleThreadScheduledExecutor();
private static List<TableView> tableView = new ArrayList<>();
private static List<MatchView> matchView = new ArrayList<>();
private static List<RoomUsersView> roomUsersView = new ArrayList<>();
@ -73,13 +73,13 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>();
public GamesRoomImpl() {
updateExecutor.scheduleAtFixedRate(new Runnable() {
UPDATE_EXECUTOR.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
update();
} catch (Exception ex) {
logger.fatal("Games room update exception! " + ex.toString(), ex);
LOGGER.fatal("Games room update exception! " + ex.toString(), ex);
}
}
@ -118,7 +118,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
user.getMatchHistory(), user.getMatchQuitRatio(), user.getTourneyHistory(),
user.getTourneyQuitRatio(), user.getGameInfo(), user.getPingInfo()));
} catch (Exception ex) {
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
LOGGER.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
users.add(new UsersView(
(user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world",
user.getName() != null ? user.getName() : "<no name>",
@ -197,8 +197,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
if (table != null) {
table.cleanUp();
tables.remove(tableId);
if (logger.isDebugEnabled()) {
logger.debug("Table removed: " + tableId);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Table removed: " + tableId);
}
}
}

View file

@ -55,12 +55,12 @@ import mage.game.permanent.token.Token;
*/
public class WardenOfTheFirstTree extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent();
private static final FilterCreaturePermanent FILTER = new FilterCreaturePermanent();
private static final FilterCreaturePermanent FILTER2 = new FilterCreaturePermanent();
static {
filter.add(new SubtypePredicate("Warrior"));
filter2.add(new SubtypePredicate("Spirit"));
FILTER.add(new SubtypePredicate("Warrior"));
FILTER2.add(new SubtypePredicate("Spirit"));
}
public WardenOfTheFirstTree(UUID ownerId) {
@ -80,21 +80,21 @@ public class WardenOfTheFirstTree extends CardImpl {
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new ConditionalContinuousEffect(
new BecomesCreatureSourceEffect(new WardenOfTheFirstTree2(), "", Duration.Custom),
new LockedInCondition(new SourceMatchesFilterCondition(filter)),
"If {this} is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink"),
new BecomesCreatureSourceEffect(new WardenOfTheFirstTree2(), "", Duration.Custom),
new LockedInCondition(new SourceMatchesFilterCondition(FILTER)),
"If {this} is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink"),
new ManaCostsImpl("{2}{W/B}{W/B}")
));
));
// {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new ConditionalOneShotEffect(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)),
new SourceMatchesFilterCondition(filter2),
"If {this} is a Spirit, put five +1/+1 counters on it"),
new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)),
new SourceMatchesFilterCondition(FILTER2),
"If {this} is a Spirit, put five +1/+1 counters on it"),
new ManaCostsImpl("{3}{W/B}{W/B}{W/B}")
));
));
}
public WardenOfTheFirstTree(final WardenOfTheFirstTree card) {

View file

@ -44,10 +44,10 @@ import mage.target.common.TargetCardInGraveyard;
*/
public class PulseOfMurasa extends CardImpl {
private static final FilterCard filter = new FilterCard("creature or land card in a graveyard");
private static final FilterCard FILTER = new FilterCard("creature or land card in a graveyard");
static {
filter.add(Predicates.or(
FILTER.add(Predicates.or(
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.LAND)));
}
@ -58,9 +58,9 @@ public class PulseOfMurasa extends CardImpl {
// Return target creature or land card from a graveyard to its owner's hand.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter));
this.getSpellAbility().addTarget(new TargetCardInGraveyard(FILTER));
// You gain 6 life.
getSpellAbility().addEffect(new GainLifeEffect(6));
this.getSpellAbility().addEffect(new GainLifeEffect(6));
}
public PulseOfMurasa(final PulseOfMurasa card) {

View file

@ -120,4 +120,26 @@ public class WardenOfTheFirstTreeTest extends CardTestPlayerBase {
* power/toughness instead of 1/1. I have had it enter with both 2/2 and
* 4/4, neither of which are actual values the card can hold.
*/
@Test
public void testTwoWarden() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// {1}{W/B}: Warden of the First Tree becomes a Human Warrior with base power and toughness 3/3.
// {2}{W/B}{W/B}: If Warden of the First Tree is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink.
// {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it.
addCard(Zone.HAND, playerA, "Warden of the First Tree", 2); // {G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Warden of the First Tree");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/B}:");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}{W/B}{W/B}:");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Warden of the First Tree");
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Warden of the First Tree", 1, 1, Filter.ComparisonScope.Any);
assertPowerToughness(playerA, "Warden of the First Tree", 3, 3, Filter.ComparisonScope.Any);
}
}

View file

@ -33,7 +33,6 @@ import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
* Describes condition when source matches specified filter
*
@ -41,17 +40,17 @@ import mage.game.permanent.Permanent;
*/
public class SourceMatchesFilterCondition implements Condition {
private FilterPermanent filter;
private FilterPermanent FILTER;
public SourceMatchesFilterCondition(FilterPermanent filter) {
this.filter = filter;
this.FILTER = filter;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
if (FILTER.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
return true;
}
}

View file

@ -176,7 +176,10 @@ public class UserData implements Serializable {
}
public String getHistory() {
return "Matches:" + this.matchHistory + " Tourneys:" + this.tourneyHistory;
if (UserGroup.COMPUTER.equals(this.groupId)) {
return "";
}
return "Matches: " + this.matchHistory + " (" + this.matchQuitRatio + "%) Tourneys: " + this.tourneyHistory + " (" + this.tourneyQuitRatio + "%)";
}
public void setMatchHistory(String history) {

View file

@ -12,7 +12,7 @@ public enum UserGroup {
ADMIN(7),
OWNER(15);
private int groupId;
private final int groupId;
UserGroup(int groupId) {
this.groupId = groupId;