diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form index 335e487e586..c31f8b1d979 100644 --- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form @@ -66,7 +66,10 @@ - + + + + @@ -80,6 +83,7 @@ + @@ -152,6 +156,15 @@ + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java index 824f3bb4e32..eb52213bb5a 100644 --- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java @@ -76,7 +76,8 @@ public class TournamentPanel extends javax.swing.JPanel { matchesModel = new TournamentMatchesTableModel(); initComponents(); - + btnQuitTournament.setVisible(false); + df = DateFormat.getDateTimeInstance(); tablePlayers.createDefaultColumnsFromModel(); @@ -124,6 +125,7 @@ public class TournamentPanel extends javax.swing.JPanel { else { hideTournament(); } + } public UUID getTournamentId() { @@ -169,6 +171,20 @@ public class TournamentPanel extends javax.swing.JPanel { matchesModel.loadData(tournament); this.tablePlayers.repaint(); this.tableMatches.repaint(); + + // player is active in tournament + btnQuitTournament.setVisible(false); + if (tournament.getEndTime() == null) { + for (TournamentPlayerView player : tournament.getPlayers()) { + if (player.getName().equals(session.getUserName())) { + if (!player.hasQuit()) { + btnQuitTournament.setVisible(true); + } + break; + } + } + } + } public void startTasks() { @@ -204,6 +220,7 @@ public class TournamentPanel extends javax.swing.JPanel { txtStartTime = new javax.swing.JTextField(); lablEndTime = new javax.swing.JLabel(); txtEndTime = new javax.swing.JTextField(); + btnQuitTournament = new javax.swing.JButton(); btnCloseWindow = new javax.swing.JButton(); jSplitPane2 = new javax.swing.JSplitPane(); jSplitPane1 = new javax.swing.JSplitPane(); @@ -246,6 +263,14 @@ public class TournamentPanel extends javax.swing.JPanel { txtEndTime.setText("jTextField2"); txtEndTime.setFocusable(false); + btnQuitTournament.setText("Quit Tournament"); + btnQuitTournament.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnQuitTournament.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnQuitTournamentActionPerformed(evt); + } + }); + btnCloseWindow.setText("Close Window"); btnCloseWindow.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); btnCloseWindow.addActionListener(new java.awt.event.ActionListener() { @@ -278,7 +303,9 @@ public class TournamentPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnCloseWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(btnCloseWindow, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnQuitTournament, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); actionPanelLayout.setVerticalGroup( @@ -289,7 +316,8 @@ public class TournamentPanel extends javax.swing.JPanel { .addComponent(lblName, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblStartTime) - .addComponent(txtStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(txtStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnQuitTournament)) .addGap(9, 9, 9) .addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(lblType) @@ -345,10 +373,19 @@ public class TournamentPanel extends javax.swing.JPanel { hideTournament(); }//GEN-LAST:event_btnCloseWindowActionPerformed + private void btnQuitTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuitTournamentActionPerformed + // TODO add your handling code here: + if (JOptionPane.showConfirmDialog(this, "Are you sure you want to quit the tournament?", "Confirm quit tournament", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + MageFrame.getSession().quitTournament(tournamentId); + } + + }//GEN-LAST:event_btnQuitTournamentActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel actionPanel; private javax.swing.JButton btnCloseWindow; + private javax.swing.JButton btnQuitTournament; private mage.client.chat.ChatPanel chatPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index d57d09e9807..1eec04c50ef 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -119,6 +119,7 @@ public interface MageServer { //tournament methods void startTournament(String sessionId, UUID roomId, UUID tableId) throws MageException; void joinTournament(UUID draftId, String sessionId) throws MageException; + void quitTournament(UUID tournamentId, String sessionId) throws MageException; TournamentView getTournament(UUID tournamentId) throws MageException; //draft methods diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java index 861a83bddef..8b5827aa6b1 100644 --- a/Mage.Common/src/mage/remote/SessionImpl.java +++ b/Mage.Common/src/mage/remote/SessionImpl.java @@ -953,6 +953,20 @@ public class SessionImpl implements Session { } return false; } + @Override + public boolean quitTournament(UUID tournamentId) { + try { + if (isConnected()) { + server.quitTournament(tournamentId, sessionId); + return true; + } + } catch (MageException ex) { + handleMageException(ex); + } catch (Throwable t) { + handleThrowable(t); + } + return false; + } @Override public boolean undo(UUID gameId) { diff --git a/Mage.Common/src/mage/remote/interfaces/GamePlay.java b/Mage.Common/src/mage/remote/interfaces/GamePlay.java index 473441adba4..7a90c05f370 100644 --- a/Mage.Common/src/mage/remote/interfaces/GamePlay.java +++ b/Mage.Common/src/mage/remote/interfaces/GamePlay.java @@ -55,6 +55,8 @@ public interface GamePlay { boolean quitMatch(UUID gameId); + boolean quitTournament(UUID tournamentId); + boolean submitDeck(UUID tableId, DeckCardLists deck); boolean updateDeck(UUID tableId, DeckCardLists deck); diff --git a/Mage.Common/src/mage/view/TournamentPlayerView.java b/Mage.Common/src/mage/view/TournamentPlayerView.java index a95c8d816c0..77a3b5c9995 100644 --- a/Mage.Common/src/mage/view/TournamentPlayerView.java +++ b/Mage.Common/src/mage/view/TournamentPlayerView.java @@ -29,6 +29,7 @@ package mage.view; import java.io.Serializable; +import mage.constants.TournamentPlayerState; import mage.game.tournament.TournamentPlayer; /** @@ -42,6 +43,7 @@ public class TournamentPlayerView implements Serializable { private String state; private String results; private int points; + private boolean quit; TournamentPlayerView(TournamentPlayer player) { this.name = player.getPlayer().getName(); @@ -52,6 +54,7 @@ public class TournamentPlayerView implements Serializable { this.state = sb.toString(); this.points = player.getPoints(); this.results = player.getResults(); + this.quit = player.getState().equals(TournamentPlayerState.ELIMINATED) || player.getState().equals(TournamentPlayerState.CANCELED); } public String getName() { @@ -69,4 +72,9 @@ public class TournamentPlayerView implements Serializable { public String getResults() { return results; } + + public boolean hasQuit() { + return quit; + } + } diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index cf6e7997fdd..a043f79988b 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -584,6 +584,17 @@ public class MageServerImpl implements MageServer { }); } + @Override + public void quitTournament(final UUID tournamentId, final String sessionId) throws MageException { + execute("quitTournament", sessionId, new Action() { + @Override + public void execute() { + UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); + TournamentManager.getInstance().quit(tournamentId, userId); + } + }); + } + @Override public void undo(final UUID gameId, final String sessionId) throws MageException { execute("undo", sessionId, new Action() { diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index 90777277f17..eeb90caefab 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -45,6 +45,7 @@ import mage.game.match.MatchOptions; import mage.game.tournament.Tournament; import mage.game.tournament.TournamentPairing; import mage.game.tournament.TournamentPlayer; +import mage.players.Player; import mage.server.ChatManager; import mage.server.TableManager; import mage.server.UserManager; @@ -237,10 +238,10 @@ public class TournamentController { public void submitDeck(UUID playerId, Deck deck) { if (tournamentSessions.containsKey(playerId)) { TournamentPlayer player = tournament.getPlayer(playerId); - if (player != null) { + if (player != null && !player.hasQuit()) { + tournamentSessions.get(playerId).submitDeck(deck); ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has submitted his tournament deck", MessageColor.BLACK); - } - tournamentSessions.get(playerId).submitDeck(deck); + } } } @@ -257,23 +258,37 @@ public class TournamentController { } } -// public UUID getSessionId() { -// return this.sessionId; -// } - public UUID getChatId() { return chatId; } - public void kill(UUID userId) { - if (userPlayerMap.containsKey(userId)) { - tournamentSessions.get(userPlayerMap.get(userId)).setKilled(); - tournamentSessions.remove(userPlayerMap.get(userId)); - leave(userId); - userPlayerMap.remove(userId); + public void quit(UUID userId) { + UUID playerId = userPlayerMap.get(userId); + if (playerId != null) { + TournamentPlayer player = tournament.getPlayer(playerId); + if (player != null) { + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has quit the tournament", MessageColor.BLACK); + String info; + if (tournament.isDoneConstructing()) { + info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString(); + } else { + info = "during Construction phase"; + } + player.setQuit(info); + } } } + public void kill(UUID userId) { + quit(userId); +// if (userPlayerMap.containsKey(userId)) { +// tournamentSessions.get(userPlayerMap.get(userId)).setKilled(); +// tournamentSessions.remove(userPlayerMap.get(userId)); +// leave(userId); +// userPlayerMap.remove(userId); +// } + } + private void leave(UUID userId) { tournament.leave(getPlayerId(userId)); } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java index b07c83e6ef8..dea7a0d9049 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java @@ -57,6 +57,11 @@ public class TournamentManager { controllers.get(tournamentId).join(userId); } + public void quit(UUID tournamentId, UUID userId) { + controllers.get(tournamentId).quit(userId); + } + + public void kill(UUID tournamentId, UUID userId) { controllers.get(tournamentId).kill(userId); } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index 8d2cf601d30..c5510165ad2 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -121,6 +121,7 @@ public class TournamentSession { public void setKilled() { killed = true; + TournamentManager.getInstance().kill(tournament.getId(), userId); } private synchronized void setupTimeout(int seconds) { diff --git a/Mage/src/mage/abilities/decorator/ConditionalActivatedAbility.java b/Mage/src/mage/abilities/decorator/ConditionalActivatedAbility.java index 7eac034cbcf..824eaaaa534 100644 --- a/Mage/src/mage/abilities/decorator/ConditionalActivatedAbility.java +++ b/Mage/src/mage/abilities/decorator/ConditionalActivatedAbility.java @@ -23,36 +23,36 @@ import mage.game.Game; */ public class ConditionalActivatedAbility extends ActivatedAbilityImpl { - private Condition condition; - private String staticText = ""; + private Condition condition; + private String ruleText = ""; - private static final Effects emptyEffects = new Effects(); + private static final Effects emptyEffects = new Effects(); - public ConditionalActivatedAbility(Zone zone, Effect effect, ManaCosts cost, Condition condition, String rule) { + public ConditionalActivatedAbility(Zone zone, Effect effect, ManaCosts cost, Condition condition, String rule) { super(zone, effect, cost); this.condition = condition; - this.staticText = rule; + this.ruleText = rule; } public ConditionalActivatedAbility(Zone zone, Effect effect, Costs costs, Condition condition, String rule) { super(zone, effect, costs); - this.condition = condition; - this.staticText = rule; + this.condition = condition; + this.ruleText = rule; } public ConditionalActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition, String rule) { super(zone, effect, cost); - this.condition = condition; - this.staticText = rule; + this.condition = condition; + this.ruleText = rule; } - public ConditionalActivatedAbility(ConditionalActivatedAbility ability) { + public ConditionalActivatedAbility(final ConditionalActivatedAbility ability) { super(ability); - this.condition = ability.condition; - this.staticText = ability.staticText; + this.condition = ability.condition; + this.ruleText = ability.ruleText; } - @Override + @Override public Effects getEffects(Game game, EffectType effectType) { if (!condition.apply(game, this)) { return emptyEffects; @@ -60,8 +60,8 @@ public class ConditionalActivatedAbility extends ActivatedAbilityImpl