Merge changes

This commit is contained in:
magenoxx 2014-05-03 11:00:05 +05:30
commit 9f2466f42f
63 changed files with 1515 additions and 421 deletions

8
.gitignore vendored
View file

@ -24,15 +24,17 @@ Mage.Server.Plugins/Mage.Player.AIMCTS/target
Mage.Server.Plugins/Mage.Player.Human/target
Mage.Server.Plugins/Mage.Draft.8PlayerBooster/target
Mage.Server.Plugins/Mage.Tournament.BoosterDraft/target
/Mage.Server.Plugins/Mage.Tournament.Constructed/target
Mage.Server.Plugins/Mage.Tournament.Constructed/target
Mage.Server.Plugins/Mage.Tournament.Sealed/target
Mage.Server.Plugins/Mage.Player.AI.DraftBot/target
Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/target/
Mage.Server/config/init.txt
Mage.Server/saved
Mage.Server/target
Mage.Server/db
Mage.Server/cache
Mage.Server/mageserver.log
Mage.Server/magediag.log
Mage.Sets/target
Mage.Tests/target
Mage.Tests/cache
@ -69,8 +71,8 @@ Mage.Server.Plugins/Mage.Draft.8PlayerBooster/target
\.rej$
\.conflict\~$
/Mage.Server.Plugins/Mage.Player.AIMCTS/target/
/Mage.Server.Console/target/
*.classpath
*.iml
/submitted
/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/target/

View file

@ -0,0 +1,28 @@
NAME:Fates Foreseen
1 [THS:45] Crackling Triton
1 [JOU:38] Font of Fortunes
2 [BNG:36] Divination
1 [JOU:32] Cloaked Siren
2 [JOU:101] Knowledge and Power
2 [JOU:52] Sigiled Starfish
1 [JOU:51] Scourge of Fleets
1 [JOU:103] Magma Spray
2 [JOU:105] Pensive Minotaur
1 [JOU:90] Bladetusk Boar
2 [BNG:112] Stormcaller of Keranos
2 [THS:123] Flamespeaker Adept
2 [JOU:107] Riddle of Lightning
1 [JOU:92] Cyclops of Eternal Fury
1 [THS:52] Lost in a Labyrinth
1 [JOU:97] Font of Ire
1 [THS:57] Omenspeaker
1 [THS:59] Prescient Chimera
2 [JOU:49] Rise of Eagles
1 [JOU:47] Pull from the Deep
1 [JOU:113] Spite of Mogis
1 [JOU:43] Interpret the Signs
2 [JOU:111] Sigiled Skink
1 [THS:137] Rage of Purphoros
13 [C13:349] Mountain
1 [THS:60] Prognostic Sphinx
13 [DDM:37] Island

View file

@ -0,0 +1,28 @@
NAME:Mortals of Myth
1 [JOU:131] Nature's Panoply
1 [THS:33] Spear of Heliod
2 [JOU:5] Banishing Light
1 [JOU:20] Oreskos Swiftclaw
1 [JOU:6] Dawnbringer Charioteers
1 [BNG:3] Akroan Skyguard
1 [JOU:21] Phalanx Formation
2 [JOU:2] Ajani's Presence
1 [BNG:8] Elite Skirmisher
2 [JOU:3] Akroan Mastiff
1 [BNG:29] Vanguard of Brimaz
11 [DDM:84] Forest
1 [JOU:26] Skyspear Cavalry
2 [JOU:28] Supply-Line Cranes
1 [JOU:22] Quarry Colossus
1 [THS:26] Phalanx Leader
15 [C13:337] Plains
1 [BNG:135] Raised by Wolves
2 [JOU:124] Golden Hind
1 [JOU:141] Solidarity of Heroes
1 [THS:36] Wingsteed Rider
2 [JOU:14] Lagonna-Band Trailblazer
1 [JOU:11] Font of Vigor
1 [JOU:119] Consign to Dust
2 [JOU:118] Colossal Heroics
2 [JOU:134] Pheres-Band Thunderhoof
2 [JOU:19] Oppressive Rays

View file

@ -0,0 +1,27 @@
NAME:Pantheon's Power
1 [JOU:78] Pharika's Chosen
2 [JOU:77] Nyx Infusion
1 [JOU:9] Eagle of the Watch
2 [BNG:79] Odunos River Trawler
1 [JOU:4] Armament of Nyx
1 [BNG:58] Archetype of Finality
1 [JOU:5] Banishing Light
1 [BNG:4] Archetype of Courage
2 [JOU:3] Akroan Mastiff
2 [JOU:73] Grim Guardian
11 [C13:337] Plains
1 [JOU:71] Font of Return
1 [BNG:68] Fate Unraveler
1 [JOU:66] Doomwake Giant
2 [JOU:67] Dreadbringer Lampads
2 [JOU:18] Nyx-Fleece Ram
1 [JOU:60] Aspect of Gorgon
2 [JOU:13] Harvestguard Alseids
1 [JOU:63] Cast into Darkness
1 [JOU:62] Brain Maggot
1 [JOU:11] Font of Vigor
15 [DDM:79] Swamp
2 [JOU:157] Underworld Coinsmith
2 [JOU:85] Thoughtrender Lamia
2 [JOU:19] Oppressive Rays
1 [JOU:81] Rotted Hulk

View file

@ -0,0 +1,28 @@
NAME:The Wilds and the Deep
1 [JOU:130] Market Festival
1 [BNG:32] Archetype of Imagination
1 [JOU:56] Triton Shorestalker
1 [JOU:38] Font of Fortunes
1 [THS:176] Savage Surge
2 [BNG:150] Kiora's Follower
1 [THS:148] Agent of Horizons
15 [DDM:84] Forest
1 [THS:164] Nessian Asp
1 [JOU:32] Cloaked Siren
1 [THS:165] Nessian Courser
1 [JOU:54] Thassa's Ire
1 [JOU:126] Heroes' Bane
1 [JOU:144] Swarmborn Giant
2 [JOU:149] Fleetfeather Cockatrice
2 [JOU:123] Font of Fertility
2 [JOU:124] Golden Hind
1 [THS:150] Arbor Colossus
2 [BNG:142] Swordwise Centaur
1 [JOU:41] Hubris
2 [THS:181] Time to Feed
1 [THS:156] Defend the Hearth
1 [JOU:117] Bassara Tower Archer
2 [JOU:136] Ravenous Leucrocota
2 [THS:62] Sealock Monster
11 [DDM:37] Island
2 [JOU:132] Nessian Game Warden

View file

@ -0,0 +1,26 @@
NAME:Voracious Rage
1 [JOU:78] Pharika's Chosen
2 [BNG:70] Felhide Brawler
2 [BNG:153] Ragemonger
2 [THS:195] Kragma Warcaller
1 [JOU:102] Lightning Diadem
2 [JOU:103] Magma Spray
1 [BNG:111] Searing Blood
3 [JOU:105] Pensive Minotaur
1 [THS:92] Insatiable Harpy
1 [JOU:108] Rollick of Abandon
1 [THS:121] Fanatic of Mogis
1 [JOU:70] Felhide Petrifier
2 [JOU:96] Flurry of Horns
1 [BNG:85] Warchanter of Mogis
1 [THS:130] Minotaur Skullcleaver
3 [THS:117] Deathbellow Raider
1 [JOU:112] Spawn of Thraxes
1 [THS:138] Rageblood Shaman
1 [JOU:63] Cast into Darkness
2 [JOU:114] Starfall
11 [DDM:79] Swamp
14 [C13:349] Mountain
1 [BNG:105] Pinnacle of Rage
2 [THS:114] Borderland Minotaur
2 [JOU:83] Spiteful Blow

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<NonVisualComponents>
<Container class="javax.swing.JPanel" name="jPanel2">
@ -56,7 +56,7 @@
<Component id="tabPane" min="-2" pref="277" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnOk" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="37" max="32767" attributes="0"/>
<EmptySpace min="0" pref="8" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -75,7 +75,9 @@
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
<SubComponents>
<Container class="javax.swing.JLayeredPane" name="pnlText">
<Properties>
@ -90,38 +92,54 @@
<Property name="opaque" type="boolean" value="true"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout$JLayeredPaneConstraintsDescription">
<JLayeredPaneConstraints x="20" y="150" width="570" height="90" layer="0" position="-1"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="20" y="150" width="570" height="90"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lblGameInfo">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="18" style="3"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="gameInfo"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="11" y="1" width="550" height="25"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="lblMatchInfo">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="24" style="3"/>
<Font name="Tahoma" size="18" style="3"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="matchInfo"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout$JLayeredPaneConstraintsDescription">
<JLayeredPaneConstraints x="11" y="42" width="550" height="40" layer="0" position="-1"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="10" y="30" width="550" height="25"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="lblResultText">
<Component class="javax.swing.JLabel" name="lblAdditionalInfo">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="24" style="3"/>
<Font name="Tahoma" size="18" style="3"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="result text"/>
<Property name="text" type="java.lang.String" value="additionalInfo"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout$JLayeredPaneConstraintsDescription">
<JLayeredPaneConstraints x="11" y="1" width="550" height="40" layer="0" position="-1"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="10" y="60" width="550" height="25"/>
</Constraint>
</Constraints>
</Component>
@ -135,8 +153,8 @@
<Property name="horizontalAlignment" type="int" value="0"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout$JLayeredPaneConstraintsDescription">
<JLayeredPaneConstraints x="0" y="0" width="610" height="250" layer="0" position="-1"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="0" y="0" width="610" height="250"/>
</Constraint>
</Constraints>
</Component>

View file

@ -45,13 +45,12 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.ImageIcon;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import mage.client.MageFrame;
import mage.client.game.GamePanel;
import mage.client.util.audio.AudioManager;
import mage.client.util.Format;
import mage.client.util.ImageHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.BufferedImageBuilder;
import mage.view.GameEndView;
import mage.view.PlayerView;
@ -65,7 +64,8 @@ public class GameEndDialog extends MageDialog {
private final DateFormat df = DateFormat.getDateTimeInstance();;
/** Creates new form GameEndDialog */
/** Creates new form GameEndDialog
* @param gameEndView */
public GameEndDialog(GameEndView gameEndView) {
initComponents();
@ -80,13 +80,14 @@ public class GameEndDialog extends MageDialog {
ImageIcon icon = new ImageIcon(imageResult);
lblResultImage.setIcon(icon);
this.lblResultText.setText(gameEndView.getResultMessage());
this.lblGameInfo.setText(gameEndView.getGameInfo());
this.lblMatchInfo.setText(gameEndView.getMatchInfo());
this.lblAdditionalInfo.setText(gameEndView.getAdditionalInfo());
String autoSave = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_LOG_AUTO_SAVE, "true");
if (autoSave.equals("true")) {
this.saveGameLog(gameEndView);
}
// game duration
txtDurationGame.setText(Format.getDuration(gameEndView.getStartTime(), gameEndView.getEndTime()));
@ -110,17 +111,6 @@ public class GameEndDialog extends MageDialog {
}
txtMatchScore.setText(gameEndView.getMatchView().getResult());
if (gameEndView.getNameMatchWinner() != null) {
if (gameEndView.getClientPlayer().getName().equals(gameEndView.getNameMatchWinner())) {
lblMatchInfo.setText("You won the match!");
} else {
lblMatchInfo.setText(new StringBuilder(gameEndView.getNameMatchWinner()).append(" won the match!").toString());
}
} else {
int winsNeeded = gameEndView.getWinsNeeded() - gameEndView.getWins();
lblMatchInfo.setText(new StringBuilder("You need ").append(winsNeeded == 1 ? "one win ":winsNeeded + " wins ").append("to win the match.").toString());
}
}
private void saveGameLog(GameEndView gameEndView) {
@ -169,8 +159,9 @@ public class GameEndDialog extends MageDialog {
tabPane = new javax.swing.JTabbedPane();
tabResult = new javax.swing.JLayeredPane();
pnlText = new javax.swing.JLayeredPane();
lblGameInfo = new javax.swing.JLabel();
lblMatchInfo = new javax.swing.JLabel();
lblResultText = new javax.swing.JLabel();
lblAdditionalInfo = new javax.swing.JLabel();
lblResultImage = new javax.swing.JLabel();
tabStatistics = new javax.swing.JPanel();
lblDurationGame = new javax.swing.JLabel();
@ -202,25 +193,31 @@ public class GameEndDialog extends MageDialog {
pnlText.setBorder(javax.swing.BorderFactory.createEtchedBorder());
pnlText.setOpaque(true);
lblMatchInfo.setFont(new java.awt.Font("Tahoma", 3, 24)); // NOI18N
lblGameInfo.setFont(new java.awt.Font("Tahoma", 3, 18)); // NOI18N
lblGameInfo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblGameInfo.setText("gameInfo");
pnlText.add(lblGameInfo);
lblGameInfo.setBounds(11, 1, 550, 25);
lblMatchInfo.setFont(new java.awt.Font("Tahoma", 3, 18)); // NOI18N
lblMatchInfo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblMatchInfo.setText("matchInfo");
lblMatchInfo.setBounds(11, 42, 550, 40);
pnlText.add(lblMatchInfo, javax.swing.JLayeredPane.DEFAULT_LAYER);
pnlText.add(lblMatchInfo);
lblMatchInfo.setBounds(10, 30, 550, 25);
lblResultText.setFont(new java.awt.Font("Tahoma", 3, 24)); // NOI18N
lblResultText.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblResultText.setText("result text");
lblResultText.setBounds(11, 1, 550, 40);
pnlText.add(lblResultText, javax.swing.JLayeredPane.DEFAULT_LAYER);
lblAdditionalInfo.setFont(new java.awt.Font("Tahoma", 3, 18)); // NOI18N
lblAdditionalInfo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblAdditionalInfo.setText("additionalInfo");
pnlText.add(lblAdditionalInfo);
lblAdditionalInfo.setBounds(10, 60, 550, 25);
tabResult.add(pnlText);
pnlText.setBounds(20, 150, 570, 90);
tabResult.add(pnlText, javax.swing.JLayeredPane.DEFAULT_LAYER);
lblResultImage.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
lblResultImage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
tabResult.add(lblResultImage);
lblResultImage.setBounds(0, 0, 610, 250);
tabResult.add(lblResultImage, javax.swing.JLayeredPane.DEFAULT_LAYER);
tabPane.addTab("Result", tabResult);
@ -249,22 +246,17 @@ public class GameEndDialog extends MageDialog {
tabStatisticsLayout.setHorizontalGroup(
tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tabStatisticsLayout.createSequentialGroup()
.addContainerGap()
.addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tabStatisticsLayout.createSequentialGroup()
.addContainerGap()
.addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblDurationMatch, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblMatchScore, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(tabStatisticsLayout.createSequentialGroup()
.addContainerGap()
.addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblDurationGame, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblLife, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addComponent(lblPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblDurationMatch, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblMatchScore, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblDurationGame, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblLife, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtPlayerInfo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(txtDurationGame, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
.addComponent(txtDurationGame, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 494, Short.MAX_VALUE)
.addComponent(txtLife, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
.addComponent(txtDurationMatch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
.addComponent(txtMatchScore, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE))
@ -292,7 +284,7 @@ public class GameEndDialog extends MageDialog {
.addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(txtPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(99, Short.MAX_VALUE))
.addContainerGap(105, Short.MAX_VALUE))
);
tabPane.addTab("Statistics", tabStatistics);
@ -322,7 +314,7 @@ public class GameEndDialog extends MageDialog {
.addComponent(tabPane, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnOk)
.addGap(0, 25, Short.MAX_VALUE))
.addGap(0, 8, Short.MAX_VALUE))
);
pack();
@ -335,14 +327,15 @@ public class GameEndDialog extends MageDialog {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnOk;
private javax.swing.JPanel jPanel2;
private javax.swing.JLabel lblAdditionalInfo;
private javax.swing.JLabel lblDurationGame;
private javax.swing.JLabel lblDurationMatch;
private javax.swing.JLabel lblGameInfo;
private javax.swing.JLabel lblLife;
private javax.swing.JLabel lblMatchInfo;
private javax.swing.JLabel lblMatchScore;
private javax.swing.JLabel lblPlayerInfo;
private javax.swing.JLabel lblResultImage;
private javax.swing.JLabel lblResultText;
private javax.swing.JLayeredPane pnlText;
private javax.swing.JTabbedPane tabPane;
private javax.swing.JLayeredPane tabResult;

View file

@ -71,10 +71,12 @@ public class NewTournamentDialog extends MageDialog {
private TableView table;
private UUID playerId;
private UUID roomId;
private Session session;
private final Session session;
private String lastSessionId;
private final List<TournamentPlayerPanel> players = new ArrayList<>();
private final List<JComboBox> packs = new ArrayList<>();
private final int CONSTRUCTION_TIME_MIN = 6;
private final int CONSTRUCTION_TIME_MAX = 30;
/** Creates new form NewTournamentDialog */
public NewTournamentDialog() {
@ -84,7 +86,7 @@ public class NewTournamentDialog extends MageDialog {
txtName.setText("Tournament");
this.spnNumWins.setModel(new SpinnerNumberModel(2, 1, 5, 1));
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
this.spnConstructTime.setModel(new SpinnerNumberModel(10, 10, 30, 5));
this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2));
this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1));
}
@ -427,9 +429,8 @@ public class NewTournamentDialog extends MageDialog {
if (tournamentType.isLimited()) {
if (tOptions.getLimitedOptions() == null) {
tOptions.setLimitedOptions(new LimitedOptions());
}
tOptions.getLimitedOptions().setConstructionTime(60);
// tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60);
}
tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60);
if (tournamentType.isCubeBooster()) {
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
} else {
@ -646,7 +647,11 @@ public class NewTournamentDialog extends MageDialog {
break;
}
}
this.spnConstructTime.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_CONSTR_TIME, "600"))/60);
int constructionTime = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_CONSTR_TIME, "600")) / 60;
if (constructionTime < CONSTRUCTION_TIME_MIN || constructionTime > CONSTRUCTION_TIME_MAX) {
constructionTime = CONSTRUCTION_TIME_MIN;
}
this.spnConstructTime.setValue(constructionTime);
String tournamentTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TYPE, "Sealed Elimination");
for (TournamentTypeView tournamentTypeView : session.getTournamentTypes()) {
if (tournamentTypeView.getName().equals(tournamentTypeName)) {

View file

@ -30,50 +30,55 @@
<Group type="102" attributes="0">
<Component id="actionPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSplitPane2" pref="511" max="32767" attributes="0"/>
<Component id="jSplitPane2" pref="454" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="actionPanel">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="e3" green="e3" id="Control Highlight" palette="2" red="e3" type="palette"/>
</Property>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Arial" size="10" style="0"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="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"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblName" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lblName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblState" min="-2" max="-2" attributes="0"/>
<Component id="txtName" pref="260" max="32767" attributes="0"/>
<Component id="txtTournamentState" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lblType" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="txtName" pref="175" max="32767" attributes="0"/>
<Component id="txtType" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblStartTime" min="-2" max="-2" attributes="0"/>
<Component id="lblTournamentState" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="txtTournamentState" max="32767" attributes="0"/>
<Component id="txtStartTime" pref="203" max="32767" attributes="0"/>
</Group>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtType" alignment="0" min="-2" pref="440" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="txtEndTime" min="-2" pref="203" max="-2" attributes="0"/>
<EmptySpace type="unrelated" pref="47" max="32767" attributes="0"/>
<Component id="btnQuitTournament" min="-2" pref="129" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="154" max="-2" attributes="0"/>
<Component id="btnCloseWindow" min="-2" pref="129" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtStartTime" min="-2" pref="220" max="-2" attributes="0"/>
<Component id="lblStartTime" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblEndTime" min="-2" max="-2" attributes="0"/>
<Component id="txtEndTime" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace pref="126" max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="btnQuitTournament" max="32767" attributes="0"/>
<Component id="btnCloseWindow" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -81,87 +86,128 @@
<DimensionLayout dim="1">
<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="7" max="-2" attributes="0"/>
<Component id="lblName" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lblType" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtType" min="-2" max="-2" attributes="0"/>
<Component id="btnQuitTournament" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
<Component id="btnCloseWindow" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="txtName" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblState" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblStartTime" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblEndTime" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="txtTournamentState" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtStartTime" alignment="3" max="32767" attributes="0"/>
<Component id="txtEndTime" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblName" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="txtName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblStartTime" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtStartTime" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnQuitTournament" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtEndTime" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblType" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtType" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCloseWindow" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblTournamentState" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtTournamentState" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lblName">
<Properties>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="text" type="java.lang.String" value="Name:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtName">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[50, 22]"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblType">
<Properties>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="text" type="java.lang.String" value="Type:"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtNameActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtType">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblStartTime">
<Properties>
<Property name="text" type="java.lang.String" value="Start / end time:"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtStartTime">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtEndTime">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblTournamentState">
<Properties>
<Property name="text" type="java.lang.String" value="State:"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtTournamentState">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value=""/>
@ -185,10 +231,53 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCloseWindowActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblName">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" value="Name:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblType">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" value="Type:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblState">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" value="State:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblStartTime">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" value="Start time:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblEndTime">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" value="End time:"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JSplitPane" name="jSplitPane2">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="e3" green="e3" id="Control Highlight" palette="2" red="e3" type="palette"/>
</Property>
<Property name="resizeWeight" type="double" value="1.0"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
@ -267,6 +356,9 @@
</SubComponents>
</Container>
<Component class="mage.client.chat.ChatPanel" name="chatPanel1">
<Properties>
<Property name="startMessageDone" type="boolean" value="true"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>

View file

@ -52,6 +52,7 @@ import mage.client.MageFrame;
import mage.client.chat.ChatPanel;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.ButtonColumn;
import mage.client.util.Format;
import mage.remote.Session;
import mage.view.RoundView;
import mage.view.TournamentGameView;
@ -208,9 +209,20 @@ public class TournamentPanel extends javax.swing.JPanel {
firstInitDone = true;
}
switch (tournament.getTournamentState()) {
case "Constructing":
String constructionTime = Format.getDuration(tournament.getConstructionTime() - (tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime())/1000);
txtTournamentState.setText(new StringBuilder(tournament.getTournamentState()).append(" (").append(constructionTime).append(")").toString());
break;
case "Dueling":
String duelingTime = Format.getDuration((tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime())/1000);
txtTournamentState.setText(new StringBuilder(tournament.getTournamentState()).append(" (").append(duelingTime).append(")").toString());
break;
default:
txtTournamentState.setText(tournament.getTournamentState());
break;
}
txtTournamentState.setText(tournament.getTournamentState());
if (txtEndTime == null) {
return;
}
@ -263,17 +275,18 @@ public class TournamentPanel extends javax.swing.JPanel {
private void initComponents() {
actionPanel = new javax.swing.JPanel();
lblName = new javax.swing.JLabel();
txtName = new javax.swing.JTextField();
lblType = new javax.swing.JLabel();
txtType = new javax.swing.JTextField();
lblStartTime = new javax.swing.JLabel();
txtStartTime = new javax.swing.JTextField();
txtEndTime = new javax.swing.JTextField();
lblTournamentState = new javax.swing.JLabel();
txtTournamentState = new javax.swing.JTextField();
btnQuitTournament = new javax.swing.JButton();
btnCloseWindow = new javax.swing.JButton();
lblName = new javax.swing.JLabel();
lblType = new javax.swing.JLabel();
lblState = new javax.swing.JLabel();
lblStartTime = new javax.swing.JLabel();
lblEndTime = new javax.swing.JLabel();
jSplitPane2 = new javax.swing.JSplitPane();
jSplitPane1 = new javax.swing.JSplitPane();
jScrollPane1 = new javax.swing.JScrollPane();
@ -284,36 +297,49 @@ public class TournamentPanel extends javax.swing.JPanel {
setPreferredSize(new java.awt.Dimension(908, 580));
lblName.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
lblName.setText("Name:");
actionPanel.setBackground(java.awt.SystemColor.controlHighlight);
actionPanel.setFont(new java.awt.Font("Arial", 0, 10)); // NOI18N
txtName.setEditable(false);
txtName.setHorizontalAlignment(javax.swing.JTextField.LEFT);
txtName.setBorder(javax.swing.BorderFactory.createEtchedBorder());
txtName.setFocusable(false);
txtName.setMaximumSize(new java.awt.Dimension(50, 22));
lblType.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
lblType.setText("Type:");
txtName.setOpaque(false);
txtName.setRequestFocusEnabled(false);
txtName.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtNameActionPerformed(evt);
}
});
txtType.setEditable(false);
txtType.setHorizontalAlignment(javax.swing.JTextField.LEFT);
txtType.setBorder(javax.swing.BorderFactory.createEtchedBorder());
txtType.setFocusable(false);
lblStartTime.setText("Start / end time:");
txtType.setOpaque(false);
txtType.setRequestFocusEnabled(false);
txtStartTime.setEditable(false);
txtStartTime.setHorizontalAlignment(javax.swing.JTextField.CENTER);
txtStartTime.setBorder(javax.swing.BorderFactory.createEtchedBorder());
txtStartTime.setFocusable(false);
txtStartTime.setOpaque(false);
txtStartTime.setRequestFocusEnabled(false);
txtEndTime.setEditable(false);
txtEndTime.setHorizontalAlignment(javax.swing.JTextField.CENTER);
txtEndTime.setBorder(javax.swing.BorderFactory.createEtchedBorder());
txtEndTime.setFocusable(false);
lblTournamentState.setText("State:");
txtEndTime.setOpaque(false);
txtEndTime.setRequestFocusEnabled(false);
txtTournamentState.setEditable(false);
txtTournamentState.setHorizontalAlignment(javax.swing.JTextField.CENTER);
txtTournamentState.setBorder(javax.swing.BorderFactory.createEtchedBorder());
txtTournamentState.setFocusable(false);
txtTournamentState.setOpaque(false);
txtTournamentState.setRequestFocusEnabled(false);
btnQuitTournament.setText("Quit Tournament");
btnQuitTournament.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
@ -331,59 +357,88 @@ public class TournamentPanel extends javax.swing.JPanel {
}
});
lblName.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
lblName.setText("Name:");
lblType.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
lblType.setText("Type:");
lblState.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
lblState.setText("State:");
lblStartTime.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
lblStartTime.setText("Start time:");
lblEndTime.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
lblEndTime.setText("End time:");
javax.swing.GroupLayout actionPanelLayout = new javax.swing.GroupLayout(actionPanel);
actionPanel.setLayout(actionPanelLayout);
actionPanelLayout.setHorizontalGroup(
actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(actionPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lblName)
.addComponent(lblType))
.addComponent(lblState)
.addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
.addComponent(txtTournamentState))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(txtType))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblStartTime)
.addComponent(lblTournamentState))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(txtTournamentState)
.addComponent(txtStartTime, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE))
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblType)
.addComponent(txtType, javax.swing.GroupLayout.PREFERRED_SIZE, 440, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(actionPanelLayout.createSequentialGroup()
.addGap(6, 6, 6)
.addComponent(txtEndTime, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, 47, Short.MAX_VALUE)
.addComponent(btnQuitTournament, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, actionPanelLayout.createSequentialGroup()
.addGap(154, 154, 154)
.addComponent(btnCloseWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblStartTime))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblEndTime)
.addComponent(txtEndTime))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 126, Short.MAX_VALUE)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnQuitTournament, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnCloseWindow, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
actionPanelLayout.setVerticalGroup(
actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(actionPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.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(btnQuitTournament)
.addComponent(txtEndTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblType)
.addComponent(txtType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnCloseWindow)
.addComponent(lblTournamentState)
.addComponent(txtTournamentState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(actionPanelLayout.createSequentialGroup()
.addGap(7, 7, 7)
.addComponent(lblName))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, actionPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblType)))
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(actionPanelLayout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnQuitTournament))
.addGap(13, 13, 13)
.addComponent(btnCloseWindow))
.addGroup(actionPanelLayout.createSequentialGroup()
.addGap(6, 6, 6)
.addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblState)
.addComponent(lblStartTime)
.addComponent(lblEndTime))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(actionPanelLayout.createSequentialGroup()
.addComponent(txtTournamentState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(actionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtStartTime)
.addComponent(txtEndTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
.addContainerGap())
);
jSplitPane2.setBackground(java.awt.SystemColor.controlHighlight);
jSplitPane2.setResizeWeight(1.0);
jSplitPane2.setToolTipText("");
@ -407,6 +462,8 @@ public class TournamentPanel extends javax.swing.JPanel {
jSplitPane1.setBottomComponent(jScrollPane2);
jSplitPane2.setLeftComponent(jSplitPane1);
chatPanel1.setStartMessageDone(true);
jSplitPane2.setRightComponent(chatPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@ -421,7 +478,8 @@ public class TournamentPanel extends javax.swing.JPanel {
.addGroup(layout.createSequentialGroup()
.addComponent(actionPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 511, Short.MAX_VALUE))
.addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 454, Short.MAX_VALUE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
@ -436,6 +494,10 @@ public class TournamentPanel extends javax.swing.JPanel {
}//GEN-LAST:event_btnQuitTournamentActionPerformed
private void txtNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtNameActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_txtNameActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel actionPanel;
@ -446,9 +508,10 @@ public class TournamentPanel extends javax.swing.JPanel {
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JSplitPane jSplitPane2;
private javax.swing.JLabel lblEndTime;
private javax.swing.JLabel lblName;
private javax.swing.JLabel lblStartTime;
private javax.swing.JLabel lblTournamentState;
private javax.swing.JLabel lblState;
private javax.swing.JLabel lblType;
private javax.swing.JTable tableMatches;
private javax.swing.JTable tablePlayers;

View file

@ -12,6 +12,7 @@ public interface Action {
/**
* Executes action.
* @throws mage.MageException
*/
void execute() throws MageException;
}

View file

@ -206,7 +206,7 @@ public class SessionImpl implements Session {
serverState = server.getServerState();
updateDatabase();
logger.info(new StringBuilder("Connected as ").append(this.getUserName()).append(" to MAGE server at ").append(connection.getHost()).append(":").append(connection.getPort()).toString());
client.connected(new StringBuilder("Connected as ").append(this.getUserName()).append(" to ").append(connection.getHost()).append(":").append(connection.getPort()).append(" ").toString());
client.connected(new StringBuilder(this.getUserName()).append("@").append(connection.getHost()).append(":").append(connection.getPort()).append(" ").toString());
return true;
}
disconnect(false);

View file

@ -1,11 +1,10 @@
package mage.utils.timer;
import mage.MageException;
import mage.interfaces.Action;
import org.apache.log4j.Logger;
import java.util.Timer;
import java.util.TimerTask;
import mage.MageException;
import mage.interfaces.Action;
import org.apache.log4j.Logger;
/**
* @author noxx
@ -14,14 +13,11 @@ public class PriorityTimer extends TimerTask {
private static final Logger logger = Logger.getLogger(PriorityTimer.class);
private final long delay;
private final Action taskOnTimeout;
private int count;
private long delay;
private Action taskOnTimeout;
private Action taskOnTick;
private States state = States.NONE;
enum States {

View file

@ -41,7 +41,6 @@ import mage.cards.SplitCard;
import mage.constants.CardType;
import mage.constants.MageObjectType;
import mage.constants.Rarity;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;

View file

@ -45,16 +45,17 @@ import mage.players.Player;
public class GameEndView implements Serializable {
private PlayerView clientPlayer = null;
private List<PlayerView> players = new ArrayList<PlayerView>();
private Date startTime;
private Date endTime;
private String resultMessage;
private final List<PlayerView> players = new ArrayList<>();
private final Date startTime;
private final Date endTime;
private String gameInfo;
private final String matchInfo;
private final String additionalInfo;
private boolean won;
private MatchView matchView;
private final MatchView matchView;
private int wins;
private int loses;
private int winsNeeded;
private String nameMatchWinner = null;
private final int winsNeeded;
public GameEndView(GameState state, Game game, UUID playerId, Match match) {
startTime = game.getStartTime();
@ -68,6 +69,7 @@ public class GameEndView implements Serializable {
if (playerView.getPlayerId().equals(playerId)) {
clientPlayer = playerView;
you = player;
won = you.hasWon(); // needed to control image
}
players.add(playerView);
if (player.hasWon()) {
@ -75,29 +77,58 @@ public class GameEndView implements Serializable {
}
}
if (you != null) {
won = you.hasWon();
if (you.hasWon()) {
resultMessage = new StringBuilder("You won the game on turn ").append(game.getTurnNum()).append(".").toString();
gameInfo = new StringBuilder("You won the game on turn ").append(game.getTurnNum()).append(".").toString();
} else if (winner > 0) {
resultMessage = new StringBuilder("You lost the game on turn ").append(game.getTurnNum()).append(".").toString();
gameInfo = new StringBuilder("You lost the game on turn ").append(game.getTurnNum()).append(".").toString();
} else {
resultMessage = new StringBuilder("Game is a draw on Turn ").append(game.getTurnNum()).append(".").toString();
gameInfo = new StringBuilder("Game is a draw on Turn ").append(game.getTurnNum()).append(".").toString();
}
}
matchView = new MatchView(match);
winsNeeded = match.getOptions().getWinsNeeded();
for (MatchPlayer mPlayer: match.getPlayers()) {
if (mPlayer.getPlayer().equals(you)) {
wins = mPlayer.getWins();
loses = mPlayer.getLoses();
MatchPlayer matchWinner = null;
winsNeeded = match.getOptions().getWinsNeeded();
StringBuilder additonalText = new StringBuilder();
for (MatchPlayer matchPlayer: match.getPlayers()) {
if (matchPlayer.getPlayer().equals(you)) {
wins = matchPlayer.getWins();
}
if (mPlayer.getWins() == winsNeeded) {
nameMatchWinner = mPlayer.getName();
if (matchPlayer.isMatchWinner()) {
matchWinner = matchPlayer;
}
if (matchPlayer.hasTimerTimeout()) {
if (matchPlayer.getPlayer().equals(you)) {
additonalText.append("You run out of time. ");
} else {
additonalText.append(matchPlayer.getName()).append(" runs out of time. ");
}
} else if (matchPlayer.hasQuit()) {
if (matchPlayer.getPlayer().equals(you)) {
additonalText.append("You have quit the match. ");
} else {
additonalText.append(matchPlayer.getName()).append(" has quit the match. ");
}
} else if (matchPlayer.getPlayer().hasIdleTimeout()) {
if (matchPlayer.getPlayer().equals(you)) {
additonalText.append("You lost the match for beeing idle. ");
} else {
additonalText.append(matchPlayer.getName()).append(" lost for beeing idle. ");
}
}
}
if (matchWinner != null) {
if (matchWinner.getPlayer().equals(you)) {
matchInfo = "You won the match!";
} else {
matchInfo = new StringBuilder(matchWinner.getName()).append(" won the match!").toString();
}
} else {
matchInfo = new StringBuilder("You need ").append(winsNeeded - wins == 1 ? "one more win ":winsNeeded - wins + " more wins ").append("to win the match.").toString();
}
additionalInfo = additonalText.toString();
}
public Date getStartTime() {
@ -112,8 +143,16 @@ public class GameEndView implements Serializable {
return players;
}
public String getResultMessage() {
return resultMessage;
public String getGameInfo() {
return gameInfo;
}
public String getMatchInfo() {
return matchInfo;
}
public String getAdditionalInfo() {
return additionalInfo;
}
public boolean hasWon() {
@ -136,10 +175,6 @@ public class GameEndView implements Serializable {
return winsNeeded;
}
public String getNameMatchWinner() {
return nameMatchWinner;
}
public PlayerView getClientPlayer() {
return clientPlayer;
}

View file

@ -72,14 +72,18 @@ public class MatchView implements Serializable {
}
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
for (MatchPlayer player: match.getPlayers()) {
sb1.append(player.getName());
if(player.hasQuit()) {
sb1.append(" [quit] ");
for (MatchPlayer matchPlayer: match.getPlayers()) {
sb1.append(matchPlayer.getName());
if(matchPlayer.hasQuit()) {
if (matchPlayer.hasTimerTimeout()) {
sb1.append(" [timer] ");
} else {
sb1.append(" [quit] ");
}
}
sb1.append(", ");
sb2.append(player.getName()).append(" ");
sb2.append(player.getWins()).append("-").append(player.getLoses()).append(", ");
sb2.append(matchPlayer.getName()).append(" ");
sb2.append(matchPlayer.getWins()).append("-").append(matchPlayer.getLoses()).append(", ");
}
players = sb1.substring(0, sb1.length() - 2);
result = sb2.substring(0, sb2.length() - 2);

View file

@ -47,7 +47,7 @@ import mage.target.targetpointer.TargetPointer;
public class StackAbilityView extends CardView {
private static final long serialVersionUID = 1L;
private CardView sourceCard;
private final CardView sourceCard;
public StackAbilityView(Game game, StackAbility ability, String sourceName, CardView sourceCard) {
this.id = ability.getId();
@ -55,7 +55,7 @@ public class StackAbilityView extends CardView {
this.sourceCard = sourceCard;
this.sourceCard.setMageObjectType(mageObjectType);
this.name = "Ability";
this.rules = new ArrayList<String>();
this.rules = new ArrayList<>();
rules.add(ability.getRule(sourceName));
this.power = ability.getPower().toString();
this.toughness = ability.getToughness().toString();
@ -65,17 +65,19 @@ public class StackAbilityView extends CardView {
this.superTypes = ability.getSupertype();
this.color = ability.getColor();
this.manaCost = ability.getManaCost().getSymbols();
this.counters = sourceCard.getCounters();
updateTargets(game, ability);
}
private void updateTargets(Game game, StackAbility ability) {
List<String> names = new ArrayList<String>();
List<String> names = new ArrayList<>();
for(UUID modeId : ability.getModes().getSelectedModes()) {
ability.getModes().setMode(ability.getModes().get(modeId));
if (ability.getTargets().size() > 0) {
setTargets(ability.getTargets());
} else {
List<UUID> targetList = new ArrayList<UUID>();
List<UUID> targetList = new ArrayList<>();
for (Effect effect : ability.getEffects()) {
TargetPointer targetPointer = effect.getTargetPointer();
if (targetPointer instanceof FixedTarget) {

View file

@ -39,7 +39,6 @@ import mage.game.Seat;
import mage.game.Table;
import mage.game.match.MatchPlayer;
import mage.game.tournament.TournamentPlayer;
import org.jboss.logging.Logger;
/**
*

View file

@ -54,7 +54,7 @@ public class TournamentGameView implements Serializable {
this.matchId = pair.getMatch().getId();
this.gameId = game.getId();
this.players = pair.getPlayer1().getPlayer().getName() + " - " + pair.getPlayer2().getPlayer().getName();
if (game.isGameOver()) {
if (game.hasEnded()) {
this.state = "Finished";
this.result = game.getWinner();
}

View file

@ -50,7 +50,9 @@ public class TournamentView implements Serializable {
private final Date startTime;
private final Date endTime;
private final Date stepStartTime;
private final Date serverTime;
private final int constructionTime;
private final boolean watchingAllowed;
private final List<RoundView> rounds = new ArrayList<>();
@ -60,10 +62,18 @@ public class TournamentView implements Serializable {
public TournamentView(Tournament tournament) {
tournamentName = tournament.getOptions().getName();
tournamentType = tournament.getOptions().getTournamentType();
if (tournament.getNumberRounds() > 0) {
tournamentType = tournament.getOptions().getTournamentType() + " " + tournament.getNumberRounds()+ " rounds";
} else {
tournamentType = tournament.getOptions().getTournamentType();
}
startTime = tournament.getStartTime();
endTime = tournament.getEndTime();
stepStartTime = tournament.getStepStartTime();
constructionTime = tournament.getOptions().getLimitedOptions().getConstructionTime();
watchingAllowed = tournament.getOptions().isWatchingAllowed();
serverTime = new Date();
tournamentState = tournament.getTournamentState();
for (TournamentPlayer player: tournament.getPlayers()) {
@ -109,5 +119,17 @@ public class TournamentView implements Serializable {
public String getTournamentState() {
return tournamentState;
}
public Date getStepStartTime() {
return stepStartTime;
}
public int getConstructionTime() {
return constructionTime;
}
public Date getServerTime() {
return serverTime;
}
}

View file

@ -467,7 +467,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
logger.trace("interrupted - " + val);
return val;
}
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.isGameOver()) {
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.gameOver(null)) {
logger.trace("Add actions -- reached end state, node count=" + SimulationNode2.nodeCount + ", depth=" + depth);
val = GameStateEvaluator2.evaluate(playerId, game);
UUID currentPlayerId = node.getGame().getPlayerList().get();
@ -488,7 +488,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
}
}
if (game.isGameOver()) {
if (game.gameOver(null)) {
val = GameStateEvaluator2.evaluate(playerId, game);
} else if (node.getChildren().size() > 0) {
//declared attackers or blockers or triggered abilities
@ -534,7 +534,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
logger.debug("Sim Prio [" + depth + "] -- repeated action: " + action.toString());
continue;
}
if (!sim.isGameOver() && action.isUsesStack()) {
if (!sim.gameOver(null) && action.isUsesStack()) {
// only pass if the last action uses the stack
sim.getPlayer(currentPlayer.getId()).pass(game);
sim.getPlayerList().getNext();
@ -797,7 +797,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
break;
case CLEANUP:
game.getPhase().getStep().beginStep(game, activePlayerId);
if (!game.checkStateAndTriggered() && !game.isGameOver()) {
if (!game.checkStateAndTriggered() && !game.gameOver(null)) {
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
game.getTurn().setPhase(new BeginningPhase());
game.getPhase().setStep(new UntapStep());

View file

@ -229,7 +229,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
return GameStateEvaluator2.evaluate(playerId, game);
}
// Condition to stop deeper simulation
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.isGameOver()) {
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.gameOver(null)) {
val = GameStateEvaluator2.evaluate(playerId, game);
if (logger.isTraceEnabled()) {
StringBuilder sb = new StringBuilder("Add Actions -- reached end state <").append(val).append(">");
@ -265,7 +265,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
}
}
if (game.isGameOver()) {
if (game.gameOver(null)) {
val = GameStateEvaluator2.evaluate(playerId, game);
}
else if (stepFinished) {
@ -494,7 +494,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId()));
Combat simCombat = sim.getCombat().copy();
finishCombat(sim);
if (sim.isGameOver()) {
if (sim.gameOver(null)) {
val = GameStateEvaluator2.evaluate(playerId, sim);
}
else if (!counter) {
@ -568,7 +568,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
logger.debug("interrupted");
return;
}
if (!game.isGameOver()) {
if (!game.gameOver(null)) {
game.getPhase().setStep(step);
if (!step.skipStep(game, game.getActivePlayerId())) {
step.beginStep(game, game.getActivePlayerId());
@ -617,7 +617,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
logger.debug("interrupted");
return;
}
if (!game.isGameOver()) {
if (!game.gameOver(null)) {
game.getTurn().getPhase().endPhase(game, game.getActivePlayerId());
game.getTurn().setPhase(new EndPhase());
if (game.getTurn().getPhase().beginPhase(game, game.getActivePlayerId())) {

View file

@ -33,7 +33,7 @@ public class GameStateEvaluator2 {
public static int evaluate(UUID playerId, Game game) {
Player player = game.getPlayer(playerId);
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
if (game.isGameOver()) {
if (game.gameOver(null)) {
if (player.hasLost() || opponent.hasWon()) {
return LOSE_GAME_SCORE;
}

View file

@ -60,11 +60,13 @@ public class ActionSimulator {
public int evaluateState() {
Player opponent = game.getPlayer(game.getOpponents(player.getId()).iterator().next());
if (game.isGameOver()) {
if (player.hasLost() || opponent.hasWon())
if (game.gameOver(null)) {
if (player.hasLost() || opponent.hasWon()) {
return Integer.MIN_VALUE;
if (opponent.hasLost() || player.hasWon())
}
if (opponent.hasLost() || player.hasWon()) {
return Integer.MAX_VALUE;
}
}
int value = player.getLife();
value -= opponent.getLife();

View file

@ -58,11 +58,11 @@ public class MCTSNode {
private int visits = 0;
private int wins = 0;
private MCTSNode parent;
private List<MCTSNode> children = new ArrayList<MCTSNode>();
private final List<MCTSNode> children = new ArrayList<MCTSNode>();
private Ability action;
private Game game;
private Combat combat;
private String stateValue;
private final String stateValue;
private UUID playerId;
private boolean terminal = false;
@ -71,7 +71,7 @@ public class MCTSNode {
public MCTSNode(Game game) {
this.game = game;
this.stateValue = game.getState().getValue(false, game);
this.terminal = game.isGameOver();
this.terminal = game.gameOver(null);
setPlayer();
nodeCount = 1;
}
@ -79,7 +79,7 @@ public class MCTSNode {
protected MCTSNode(MCTSNode parent, Game game, Ability action) {
this.game = game;
this.stateValue = game.getState().getValue(false, game);
this.terminal = game.isGameOver();
this.terminal = game.gameOver(null);
this.parent = parent;
this.action = action;
setPlayer();
@ -90,20 +90,21 @@ public class MCTSNode {
this.game = game;
this.combat = combat;
this.stateValue = game.getState().getValue(false, game);
this.terminal = game.isGameOver();
this.terminal = game.gameOver(null);
this.parent = parent;
setPlayer();
nodeCount++;
}
private void setPlayer() {
if (game.getStep().getStepPart() == StepPart.PRIORITY)
if (game.getStep().getStepPart() == StepPart.PRIORITY) {
playerId = game.getPriorityPlayerId();
else {
if (game.getStep().getType() == PhaseStep.DECLARE_BLOCKERS)
} else {
if (game.getStep().getType() == PhaseStep.DECLARE_BLOCKERS) {
playerId = game.getCombat().getDefenders().iterator().next();
else
} else {
playerId = game.getActivePlayerId();
}
}
}

View file

@ -330,7 +330,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
return GameStateEvaluator.evaluate(playerId, game);
}
int val;
if (node.depth > maxDepth || game.isGameOver()) {
if (node.depth > maxDepth || game.gameOver(null)) {
logger.debug(indent(node.depth) + "simulating -- reached end state");
val = GameStateEvaluator.evaluate(playerId, game);
}
@ -357,7 +357,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
}
}
if (game.isGameOver()) {
if (game.gameOver(null)) {
val = GameStateEvaluator.evaluate(playerId, game);
}
else if (node.getChildren().size() > 0) {
@ -403,7 +403,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
logger.debug(indent(node.depth) + "found useless action: " + action);
continue;
}
if (!sim.isGameOver() && action.isUsesStack()) {
if (!sim.gameOver(null) && action.isUsesStack()) {
// only pass if the last action uses the stack
sim.getPlayer(currentPlayer.getId()).pass(game);
sim.getPlayerList().getNext();
@ -587,7 +587,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
break;
case CLEANUP:
game.getPhase().getStep().beginStep(game, activePlayerId);
if (!game.checkStateAndTriggered() && !game.isGameOver()) {
if (!game.checkStateAndTriggered() && !game.gameOver(null)) {
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
game.getTurn().setPhase(new BeginningPhase());
game.getPhase().setStep(new UntapStep());

View file

@ -185,7 +185,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
logger.debug(indent(node.depth) + "interrupted");
return GameStateEvaluator.evaluate(playerId, game);
}
if (node.depth > maxDepth || game.isGameOver()) {
if (node.depth > maxDepth || game.gameOver(null)) {
logger.debug(indent(node.depth) + "simulating -- reached end state");
val = GameStateEvaluator.evaluate(playerId, game);
}
@ -205,7 +205,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
}
}
if (game.isGameOver()) {
if (game.gameOver(null)) {
val = GameStateEvaluator.evaluate(playerId, game);
}
else if (stepFinished) {
@ -406,7 +406,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId()));
Combat simCombat = sim.getCombat().copy();
finishCombat(sim);
if (sim.isGameOver()) {
if (sim.gameOver(null)) {
val = GameStateEvaluator.evaluate(playerId, sim);
}
else if (!counter) {
@ -448,7 +448,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
return GameStateEvaluator.evaluate(playerId, game);
}
Integer val = null;
if (!game.isGameOver()) {
if (!game.gameOver(null)) {
logger.debug(indent(node.depth) + "simulating -- ending turn");
simulateToEnd(game);
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
@ -476,7 +476,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
logger.debug("interrupted");
return;
}
if (!game.isGameOver()) {
if (!game.gameOver(null)) {
game.getPhase().setStep(step);
if (!step.skipStep(game, game.getActivePlayerId())) {
step.beginStep(game, game.getActivePlayerId());
@ -524,7 +524,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
logger.debug("interrupted");
return;
}
if (!game.isGameOver()) {
if (!game.gameOver(null)) {
game.getTurn().getPhase().endPhase(game, game.getActivePlayerId());
game.getTurn().setPhase(new EndPhase());
if (game.getTurn().getPhase().beginPhase(game, game.getActivePlayerId())) {

View file

@ -70,7 +70,7 @@ public class GameStateEvaluator {
public static int evaluate(UUID playerId, Game game, boolean ignoreTapped) {
Player player = game.getPlayer(playerId);
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
if (game.isGameOver()) {
if (game.gameOver(null)) {
if (player.hasLost() || opponent.hasWon())
return LOSE_SCORE;
if (opponent.hasLost() || player.hasWon())

View file

@ -172,9 +172,7 @@ public class MageServerImpl implements MageServer {
logger.debug("Tournament table " + table.getTableId() + " created");
LogServiceImpl.instance.log(LogKeys.KEY_TOURNAMENT_TABLE_CREATED, sessionId, userId.toString(), table.getTableId().toString());
return table;
} catch (NumberFormatException ex) {
handleException(ex);
} catch (MageException ex) {
} catch (Exception ex) {
handleException(ex);
}
return null;

View file

@ -284,11 +284,7 @@ public class Main {
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder", ex);
} catch (IllegalAccessException ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
} catch (InstantiationException ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
} catch (MalformedURLException ex) {
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;
@ -301,11 +297,7 @@ public class Main {
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Tournament type not found:" + plugin.getName() + " / "+ plugin.getJar() + " - check plugin folder", ex);
} catch (IllegalAccessException ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
} catch (InstantiationException ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
} catch (MalformedURLException ex) {
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;

View file

@ -593,7 +593,6 @@ public class TableController {
* @return true if table can be closed
*/
public boolean endGameAndStartNextGame() {
boolean matchIsOver = false;
// get player that chooses who goes first
UUID choosingPlayerId = match.getChooser();
match.endGame();
@ -604,27 +603,24 @@ public class TableController {
}
GameManager.getInstance().removeGame(match.getGame().getId());
try {
if (!match.isMatchOver()) {
if (!match.hasEnded()) {
table.sideboard();
setupTimeout(Match.SIDEBOARD_TIME);
match.sideboard();
cancelTimeout();
if (!match.isMatchOver()) {
if (!match.hasEnded()) {
startGame(choosingPlayerId);
} else {
matchIsOver = true;
closeTable();
}
}
else {
// if match has only one game
matchIsOver = true;
closeTable();
}
} catch (GameException ex) {
logger.fatal(null, ex);
}
return matchIsOver;
return match.hasEnded();
}
/**

View file

@ -412,7 +412,7 @@ public class GameController implements GameCallback {
.append(ConfigSettings.getInstance().getMaxSecondsIdle())
.append(" seconds ) - Auto concede.");
ChatManager.getInstance().broadcast(chatId, "", sb.toString() , MessageColor.BLACK, true, MessageType.STATUS);
concede(userId);
game.idleTimeout(getPlayerId(userId));
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.coldsnap;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EmptyEffect;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.counters.common.ChargeCounter;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LevelX2
*/
public class LightningStorm extends CardImpl<LightningStorm> {
public LightningStorm(UUID ownerId) {
super(ownerId, 89, "Lightning Storm", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{R}{R}");
this.expansionSetCode = "CSP";
this.color.setRed(true);
// Lightning Storm deals X damage to target creature or player, where X is 3 plus the number of charge counters on it.
Effect effect = new DamageTargetEffect(new LightningStormCountCondition(CounterType.CHARGE));
effect.setText("{this} deals X damage to target creature or player, where X is 3 plus the number of charge counters on it");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer(true));
// Discard a land card: Put two charge counters on Lightning Storm. You may choose a new target for it. Any player may activate this ability but only if Lightning Storm is on the stack.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.STACK,
new LightningStormAddCounterEffect() ,
new DiscardTargetCost(new TargetCardInHand(new FilterLandCard())));
ability.setMayActivate(TargetController.ANY);
ability.addEffect(new EmptyEffect("Any player may activate this ability but only if {this} is on the stack"));
this.addAbility(ability);
}
public LightningStorm(final LightningStorm card) {
super(card);
}
@Override
public LightningStorm copy() {
return new LightningStorm(this);
}
}
class LightningStormCountCondition implements DynamicValue {
private final CounterType counter;
public LightningStormCountCondition(CounterType counter) {
this.counter = counter;
}
public LightningStormCountCondition(final LightningStormCountCondition countersCount) {
this.counter = countersCount.counter;
}
@Override
public int calculate(Game game, Ability sourceAbility) {
Spell spell = game.getStack().getSpell(sourceAbility.getSourceId());
if (spell != null) {
return spell.getCounters().getCount(counter) + 3;
}
return 0;
}
@Override
public DynamicValue copy() {
return new LightningStormCountCondition(this);
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "3 plus the number of charge counters on it";
}
}
class LightningStormAddCounterEffect extends OneShotEffect<LightningStormAddCounterEffect> {
public LightningStormAddCounterEffect() {
super(Outcome.Benefit);
this.staticText = "Put two charge counters on {this}. You may choose a new target for it.";
}
public LightningStormAddCounterEffect(final LightningStormAddCounterEffect effect) {
super(effect);
}
@Override
public LightningStormAddCounterEffect copy() {
return new LightningStormAddCounterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) {
spell.addCounters(new ChargeCounter(2), game);
return spell.chooseNewTargets(game, source.getControllerId(), false, false);
}
return false;
}
}

View file

@ -28,6 +28,8 @@
package mage.sets.commander2013;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.UUID;
@ -100,31 +102,38 @@ class UnexpectedlyAbsentEffect extends OneShotEffect<UnexpectedlyAbsentEffect> {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player owner = game.getPlayer(permanent.getOwnerId());
if (owner != null) {
int xValue = Math.min(source.getManaCostsToPay().getX(), owner.getLibrary().size());
Cards cards = new CardsImpl(Zone.PICK);
List<UUID> cardIds = new ArrayList<>();
for (int i = 0; i < xValue; i++) {
Card card = owner.getLibrary().getFromTop(game);
cards.add(card);
cardIds.add(card.getId());
}
// return cards back to library
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
ListIterator<UUID> l = cardIds.listIterator();
while(l.hasPrevious()) {
UUID cardId = l.previous();
Card card = cards.get(cardId, game);
if (card != null) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player owner = game.getPlayer(permanent.getOwnerId());
if (owner != null) {
int xValue = Math.min(source.getManaCostsToPay().getX(), owner.getLibrary().size());
Cards cards = new CardsImpl(Zone.PICK);
Deque<UUID> cardIds = new LinkedList<>();
for (int i = 0; i < xValue; i++) {
Card card = owner.getLibrary().removeFromTop(game);
cards.add(card);
cardIds.push(card.getId());
}
// return cards back to library
game.informPlayers(new StringBuilder(controller.getName())
.append(" puts ").append(permanent.getName())
.append(" beneath the top ").append(xValue)
.append(" cards of ").append(owner.getName()).append("'s library").toString());
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
while(!cardIds.isEmpty()) {
UUID cardId = cardIds.poll();
Card card = cards.get(cardId, game);
if (card != null) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
}
return true;
}
return true;
}
}
return false;
}
}

View file

@ -34,7 +34,7 @@ import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.Target;
@ -46,7 +46,7 @@ import mage.target.TargetPermanent;
*/
public class ConsignToDust extends CardImpl<ConsignToDust> {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("artifacts and/or enchantments");
private static final FilterPermanent filter = new FilterPermanent("artifacts and/or enchantments");
static {
filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ENCHANTMENT)));

View file

@ -27,10 +27,10 @@
*/
package mage.sets.journeyintonyx;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Deque;
import java.util.LinkedList;
import java.util.UUID;
import java.util.logging.Logger;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -106,17 +106,20 @@ class QuarryColossusReturnLibraryEffect extends OneShotEffect<QuarryColossusRetu
int plains = game.getBattlefield().countAll(new FilterPermanent("Plains", "Plains you control"), source.getControllerId(), game);
int xValue = Math.min(plains, owner.getLibrary().size());
Cards cards = new CardsImpl();
List<UUID> cardIds = new ArrayList<>();
Deque<UUID> cardIds = new LinkedList<>();
for (int i = 0; i < xValue; i++) {
Card card = owner.getLibrary().getFromTop(game);
Card card = owner.getLibrary().removeFromTop(game);
cards.add(card);
cardIds.add(card.getId());
cardIds.push(card.getId());
}
// return cards back to library
controller.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true);
ListIterator<UUID> libraryCards = cardIds.listIterator();
while(libraryCards.hasPrevious()) {
UUID cardId = libraryCards.previous();
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
game.informPlayers(new StringBuilder(controller.getName())
.append(" puts ").append(permanent.getName())
.append(" beneath the top ").append(xValue)
.append(" cards of ").append(owner.getName()).append("'s library").toString());
while(!cardIds.isEmpty()) {
UUID cardId = cardIds.poll();
Card card = cards.get(cardId, game);
if (card != null) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);

View file

@ -0,0 +1,162 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.judgment;
import java.util.UUID;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.costs.common.ExileXFromYourGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
/**
*
* @author LevelX2
*/
public class FlashOfInsight extends CardImpl<FlashOfInsight> {
private static final FilterCard filter = new FilterCard("blue cards from your graveyard");
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
}
public FlashOfInsight(UUID ownerId) {
super(ownerId, 40, "Flash of Insight", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{X}{1}{U}");
this.expansionSetCode = "JUD";
this.color.setBlue(true);
// Look at the top X cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
this.getSpellAbility().addEffect(new FlashOfInsightEffect());
// Flashback-{1}{U}, Exile X blue cards from your graveyard.
Ability ability = new FlashbackAbility(new ManaCostsImpl("{1}{U}"), TimingRule.INSTANT);
ability.addCost(new ExileXFromYourGraveCost(filter));
this.addAbility(ability);
}
public FlashOfInsight(final FlashOfInsight card) {
super(card);
}
@Override
public FlashOfInsight copy() {
return new FlashOfInsight(this);
}
}
class FlashOfInsightEffect extends OneShotEffect<FlashOfInsightEffect> {
public FlashOfInsightEffect() {
super(Outcome.DrawCard);
this.staticText = "Look at the top X cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order";
}
public FlashOfInsightEffect(final FlashOfInsightEffect effect) {
super(effect);
}
@Override
public FlashOfInsightEffect copy() {
return new FlashOfInsightEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (player == null || sourceObject == null) {
return false;
}
int xValue;
xValue = source.getManaCostsToPay().getX();
Cards cards = new CardsImpl(Zone.PICK);
int count = Math.min(player.getLibrary().size(), xValue);
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards(sourceObject.getName(), cards, game);
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
game.informPlayers(sourceObject.getName() + ": " + player.getName() + " puts a card into his or her hand");
}
}
target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true);
if (cards.size() > 0) {
game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ")
.append(player.getName()).append(" puts ")
.append(cards.size() == 1 ? "a":cards.size())
.append(" card").append(cards.size() > 1 ? "s":"")
.append(" on the bottom of his or her library").toString());
}
while (cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
}
target.clearChosen();
}
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
}
return true;
}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.legends;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.UntapAllLandsControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author LevelX2
*/
public class Reset extends CardImpl<Reset> {
public Reset(UUID ownerId) {
super(ownerId, 73, "Reset", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{U}{U}");
this.expansionSetCode = "LEG";
this.color.setBlue(true);
// Cast Reset only during an opponent's turn after his or her upkeep step.
Ability ability = new SimpleStaticAbility(Zone.ALL, new ResetReplacementEffect());
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// Untap all lands you control.
this.getSpellAbility().addEffect(new UntapAllLandsControllerEffect());
}
public Reset(final Reset card) {
super(card);
}
@Override
public Reset copy() {
return new Reset(this);
}
}
class ResetReplacementEffect extends ReplacementEffectImpl<ResetReplacementEffect> {
ResetReplacementEffect() {
super(Duration.EndOfGame, Outcome.Detriment);
staticText = "Cast {this} only during an opponent's turn after his or her upkeep step";
}
ResetReplacementEffect(final ResetReplacementEffect effect) {
super(effect);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType().equals(GameEvent.EventType.CAST_SPELL) && event.getSourceId().equals(source.getSourceId())) {
if (game.getTurn().getStepType().equals(PhaseStep.UNTAP)
|| game.getTurn().getStepType().equals(PhaseStep.UPKEEP)
|| !game.getOpponents(source.getControllerId()).contains(game.getActivePlayerId())) {
return true;
}
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public ResetReplacementEffect copy() {
return new ResetReplacementEffect(this);
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.lorwyn;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageEverythingEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author LevelX2
*/
public class AshlingThePilgrim extends CardImpl<AshlingThePilgrim> {
public AshlingThePilgrim(UUID ownerId) {
super(ownerId, 149, "Ashling the Pilgrim", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.expansionSetCode = "LRW";
this.supertype.add("Legendary");
this.subtype.add("Elemental");
this.subtype.add("Shaman");
this.color.setRed(true);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {1}{R}: Put a +1/+1 counter on Ashling the Pilgrim. If this is the third time this ability has resolved this turn, remove all +1/+1 counters from Ashling the Pilgrim, and it deals that much damage to each creature and each player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), new ManaCostsImpl("{1}{R}"));
ability.addEffect(new AshlingThePilgrimEffect());
this.addAbility(ability);
}
public AshlingThePilgrim(final AshlingThePilgrim card) {
super(card);
}
@Override
public AshlingThePilgrim copy() {
return new AshlingThePilgrim(this);
}
}
class AshlingThePilgrimEffect extends OneShotEffect<AshlingThePilgrimEffect> {
class ActivationInfo {
public int zoneChangeCounter;
public int turn;
public int activations;
}
public AshlingThePilgrimEffect() {
super(Outcome.Damage);
this.staticText = "If this is the third time this ability has resolved this turn, remove all +1/+1 counters from {this}, and it deals that much damage to each creature and each player";
}
public AshlingThePilgrimEffect(final AshlingThePilgrimEffect effect) {
super(effect);
}
@Override
public AshlingThePilgrimEffect copy() {
return new AshlingThePilgrimEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null && sourcePermanent != null) {
ActivationInfo info;
Object object = game.getState().getValue(source.getSourceId() + "ActivationInfo");
if (object instanceof ActivationInfo) {
info = (ActivationInfo) object;
if (info.turn != game.getTurnNum() || sourcePermanent.getZoneChangeCounter() != info.zoneChangeCounter) {
info.turn = game.getTurnNum();
info.zoneChangeCounter = sourcePermanent.getZoneChangeCounter();
info.activations = 0;
}
} else {
info = new ActivationInfo();
info.turn = game.getTurnNum();
info.zoneChangeCounter = sourcePermanent.getZoneChangeCounter();
game.getState().setValue(source.getSourceId() + "ActivationInfo", info);
}
info.activations++;
if (info.activations == 3) {
int damage = sourcePermanent.getCounters().getCount(CounterType.P1P1);
if (damage > 0) {
sourcePermanent.removeCounters(CounterType.P1P1.getName(), damage, game);
return new DamageEverythingEffect(damage, new FilterCreaturePermanent()).apply(game, source);
}
}
return true;
}
return false;
}
}

View file

@ -889,6 +889,10 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
return sb.toString();
}
public String getTargetDescription(Targets targets, Game game) {
return getTargetDescriptionForLog(targets, game);
}
protected String getTargetDescriptionForLog(Targets targets, Game game) {
StringBuilder sb = new StringBuilder();
if (targets.size() > 0) {

View file

@ -35,12 +35,15 @@ import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import mage.constants.CardType;
import java.io.File;
import java.sql.SQLException;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import mage.constants.CardType;
/**
*
@ -52,7 +55,7 @@ public enum CardRepository {
private static final String JDBC_URL = "jdbc:sqlite:db/cards.db";
private static final String VERSION_ENTITY_NAME = "card";
private static final long CARD_DB_VERSION = 30;
private static final long CARD_DB_VERSION = 31;
private final Random random = new Random();
private Dao<CardInfo, Object> cardDao;

View file

@ -29,14 +29,14 @@ public enum MageObjectType {
CARD ("Card", false, true),
COPY_CARD ("Copy of a Card", false, true),
TOKEN ("Token", true, true),
SPELL ("Spell", false, false),
SPELL ("Spell", false, true),
PERMANENT ("Permanent", true, true),
EMBLEM ("Emblem", false, false),
COMMANDER ("Commander", false, false);
private String text;
private boolean permanent;
private boolean canHaveCounters;
private final String text;
private final boolean permanent;
private final boolean canHaveCounters;
MageObjectType(String text, boolean permanent, boolean canHaveCounters) {

View file

@ -13,7 +13,7 @@ public enum TableState {
CONSTRUCTING ("Constructing"),
FINISHED ("Finished");
private String text;
private final String text;
TableState(String text) {
this.text = text;

View file

@ -122,7 +122,8 @@ public interface Game extends MageItem, Serializable {
UUID getActivePlayerId();
UUID getPriorityPlayerId();
void leave(UUID playerId);
boolean isGameOver();
boolean gameOver(UUID playerId);
boolean hasEnded();
Battlefield getBattlefield();
SpellStack getStack();
Exile getExile();
@ -218,6 +219,8 @@ public interface Game extends MageItem, Serializable {
void mulligan(UUID playerId);
void endMulligan(UUID playerId);
void quit(UUID playerId);
void timerTimeout(UUID playerId);
void idleTimeout(UUID playerId);
void concede(UUID playerId);
void undo(UUID playerId);
void emptyManaPools();

View file

@ -418,8 +418,26 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
}
/**
* Starts check if game over or if playerId is given
* let the player concede.
*
* @param playerId
* @return
*/
@Override
public synchronized boolean isGameOver() {
public synchronized boolean gameOver(UUID playerId) {
if (playerId == null) {
boolean result = checkIfGameIsOver();
return result;
} else {
leave(playerId);
return true;
}
}
private boolean checkIfGameIsOver() {
if (state.isGameOver()) {
return true;
}
@ -447,6 +465,11 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
return false;
}
@Override
public boolean hasEnded() {
return endTime != null;
}
@Override
public String getWinner() {
if (winnerId == null) {
@ -546,13 +569,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
Player player = getPlayer(players.get());
boolean wasPaused = state.isPaused();
state.resume();
if (!isGameOver()) {
if (!gameOver(null)) {
fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString());
if (checkStopOnTurnOption()) {
return;
}
state.getTurn().resumePlay(this, wasPaused);
if (!isPaused() && !isGameOver()) {
if (!isPaused() && !gameOver(null)) {
endOfTurn();
player = players.getNext(this);
state.setTurnNum(state.getTurnNum() + 1);
@ -562,10 +585,10 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
protected void play(UUID nextPlayerId) {
if (!isPaused() && !isGameOver()) {
if (!isPaused() && !gameOver(null)) {
PlayerList players = state.getPlayerList(nextPlayerId);
Player player = getPlayer(players.get());
while (!isPaused() && !isGameOver()) {
while (!isPaused() && !gameOver(null)) {
if (!playTurn(player)) {
break;
@ -583,7 +606,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
player = players.getNext(this);
}
}
if (isGameOver()) {
if (gameOver(null)) {
winnerId = findWinnersAndLosers();
logger.info(new StringBuilder("Game with gameId ").append(this.getId()).append(" ended."));
}
@ -597,7 +620,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
state.setActivePlayerId(player.getId());
player.becomesActivePlayer();
state.getTurn().play(this, player.getId());
if (isPaused() || isGameOver()) {
if (isPaused() || gameOver(null)) {
return false;
}
endOfTurn();
@ -865,9 +888,30 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
@Override
public synchronized void quit(UUID playerId) {
Player player = state.getPlayer(playerId);
if (player != null) {
fireInformEvent(player.getName() + " quits the match.");
if (player != null) {
player.quit(this);
}else {
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
}
}
@Override
public synchronized void timerTimeout(UUID playerId) {
Player player = state.getPlayer(playerId);
if (player != null) {
player.timerTimeout(this);
} else {
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
}
}
@Override
public synchronized void idleTimeout(UUID playerId) {
Player player = state.getPlayer(playerId);
if (player != null) {
player.idleTimeout(this);
} else {
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
}
}
@ -923,7 +967,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
int bookmark = 0;
clearAllBookmarks();
try {
while (!isPaused() && !isGameOver()) {
while (!isPaused() && !gameOver(null)) {
if (!resuming) {
state.getPlayers().resetPassed();
state.getPlayerList().setCurrent(activePlayerId);
@ -933,13 +977,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
fireUpdatePlayersEvent();
Player player;
while (!isPaused() && !isGameOver()) {
while (!isPaused() && !gameOver(null)) {
try {
//if (bookmark == 0)
//bookmark = bookmarkState();
player = getPlayer(state.getPlayerList().get());
state.setPriorityPlayerId(player.getId());
while (!player.isPassed() && player.isInGame() && !isPaused() && !isGameOver()) {
while (!player.isPassed() && player.isInGame() && !isPaused() && !gameOver(null)) {
if (!resuming) {
if (checkStateAndTriggered()) {
applyEffects();
@ -947,7 +991,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
//resetLKI();
applyEffects();
saveState(false);
if (isPaused() || isGameOver()) {
if (isPaused() || gameOver(null)) {
return;
}
// resetPassed should be called if player performs any action
@ -962,7 +1006,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
resetShortLivingLKI();
resuming = false;
if (isPaused() || isGameOver()) {
if (isPaused() || gameOver(null)) {
return;
}
if (allPassed()) {
@ -1164,9 +1208,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
public boolean checkStateAndTriggered() {
boolean somethingHappened = false;
//20091005 - 115.5
while (!isPaused() && !this.isGameOver()) {
while (!isPaused() && !gameOver(null)) {
if (!checkStateBasedActions() ) {
if (isPaused() || this.isGameOver() || !checkTriggered()) {
if (isPaused() || gameOver(null) || !checkTriggered()) {
break;
}
}
@ -1729,7 +1773,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
return;
}
player.leave();
if (this.isGameOver()) {
if (gameOver(null)) {
// no need to remove objects if only one player is left so the game is over
return;
}

View file

@ -112,8 +112,8 @@ public class Table implements Serializable {
}
public void initTournament() {
setState(TableState.DUELING);
setState(TableState.DUELING);
tournament.setStepStartTime(new Date());
}
public void endTournament() {
@ -122,10 +122,12 @@ public class Table implements Serializable {
public void initDraft() {
setState(TableState.DRAFTING);
tournament.setStepStartTime(new Date());
}
public void construct() {
setState(TableState.CONSTRUCTING);
tournament.setStepStartTime(new Date());
}
/**

View file

@ -191,7 +191,7 @@ public class Combat implements Serializable, Copyable<Combat> {
//20101001 - 508.1d
checkAttackRequirements(player, game);
player.selectAttackers(game, attackerId);
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return;
}
checkAttackRestrictions(player, game);
@ -316,7 +316,7 @@ public class Combat implements Serializable, Copyable<Combat> {
}
while (choose) {
blockController.selectBlockers(game, defenderId);
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return;
}
if (!this.checkBlockRestrictions(defender, game)) {

View file

@ -46,7 +46,7 @@ public class GameEvent {
protected boolean flag;
protected String data;
protected Zone zone;
protected ArrayList<UUID> appliedEffects = new ArrayList<UUID>();
protected ArrayList<UUID> appliedEffects = new ArrayList<>();
public enum EventType {

View file

@ -48,7 +48,8 @@ public interface Match {
UUID getId();
String getName();
boolean isMatchOver();
boolean hasEnded();
boolean checkIfMatchEnds();
List<MatchPlayer> getPlayers();
MatchPlayer getPlayer(UUID playerId);

View file

@ -126,20 +126,31 @@ public abstract class MatchImpl implements Match {
}
@Override
public boolean isMatchOver() {
public boolean hasEnded() {
return endTime != null;
};
@Override
public boolean checkIfMatchEnds() {
int activePlayers = 0;
for (MatchPlayer player: players) {
if (!player.hasQuit()) {
MatchPlayer matchWinner = null;
for (MatchPlayer matchPlayer: players) {
if (!matchPlayer.hasQuit()) {
activePlayers++;
matchWinner = matchPlayer;
}
if (player.getWins() >= options.getWinsNeeded()) {
if (matchPlayer.getWins() >= options.getWinsNeeded()) {
matchPlayer.setMatchWinner(true);
endTime = new Date();
return true;
}
}
if (activePlayers < 2) {
endTime = new Date();
return true;
if (matchWinner != null) {
matchWinner.setMatchWinner(true);
}
endTime = new Date();
return true;
}
return false;
}
@ -200,24 +211,28 @@ public abstract class MatchImpl implements Match {
@Override
public void endGame() {
Game game = getGame();
for (MatchPlayer player: this.players) {
Player p = game.getPlayer(player.getPlayer().getId());
if (p != null) {
for (MatchPlayer matchPlayer: this.players) {
Player player = game.getPlayer(matchPlayer.getPlayer().getId());
if (player != null) {
// get the left time from player priority timer
if (game.getPriorityTime() > 0) {
player.setPriorityTimeLeft(p.getPriorityTimeLeft());
matchPlayer.setPriorityTimeLeft(player.getPriorityTimeLeft());
}
if (p.hasQuit()) {
player.setQuit(true);
if (player.hasQuit()) {
matchPlayer.setQuit(true);
}
if (p.hasWon()) {
player.addWin();
if (player.hasTimerTimeout()) {
matchPlayer.setTimerTimeout(true);
}
if (p.hasLost()) {
player.addLose();
if (player.hasWon()) {
matchPlayer.addWin();
}
if (player.hasLost()) {
matchPlayer.addLose();
}
}
}
checkIfMatchEnds();
game.fireGameEndInfo();
}

View file

@ -39,12 +39,14 @@ import mage.players.Player;
public class MatchPlayer {
private int wins;
private int loses;
private boolean matchWinner;
private Deck deck;
private Player player;
private final String name;
private boolean quit;
private boolean timerTimeout;
private boolean doneSideboarding;
private int priorityTimeLeft;
@ -55,7 +57,9 @@ public class MatchPlayer {
this.loses = 0;
this.doneSideboarding = true;
this.quit = false;
this.timerTimeout = false;
this.name = player.getName();
this.matchWinner = false;
}
public int getPriorityTimeLeft() {
@ -125,7 +129,23 @@ public class MatchPlayer {
this.doneSideboarding = true;
this.quit = quit;
}
public boolean hasTimerTimeout() {
return timerTimeout;
}
public void setTimerTimeout(boolean timerTimeout) {
this.timerTimeout = timerTimeout;
}
public boolean isMatchWinner() {
return matchWinner;
}
public void setMatchWinner(boolean matchWinner) {
this.matchWinner = matchWinner;
}
public void cleanUpOnMatchEnd() {
// Free resources that are not needed after match end
this.deck = null;

View file

@ -372,6 +372,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
public boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget) {
Player player = game.getPlayer(playerId);
if (player != null) {
StringBuilder newTargetDescription = new StringBuilder();
// Fused split spells or spells where "Splice on Arcane" was used can have more than one ability
for (SpellAbility spellAbility : spellAbilities) {
// Some spells can have more than one mode
@ -386,9 +387,11 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
}
}
newTargetDescription.append(getSpellAbility().getTargetDescription(mode.getTargets(), game));
}
}
game.informPlayers(this.getName() + " is now " + newTargetDescription.toString());
return true;
}
return false;
@ -851,26 +854,38 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
@Override
public Counters getCounters() {
return null;
return card.getCounters();
}
@Override
public void addCounters(String name, int amount, Game game) {}
public void addCounters(String name, int amount, Game game) {
card.addCounters(name, amount, game);
}
@Override
public void addCounters(String name, int amount, Game game, ArrayList<UUID> appliedEffects) {}
public void addCounters(String name, int amount, Game game, ArrayList<UUID> appliedEffects) {
card.addCounters(name, amount, game, appliedEffects);
}
@Override
public void addCounters(Counter counter, Game game) {}
public void addCounters(Counter counter, Game game) {
card.addCounters(counter, game);
}
@Override
public void addCounters(Counter counter, Game game, ArrayList<UUID> appliedEffects) {}
public void addCounters(Counter counter, Game game, ArrayList<UUID> appliedEffects) {
card.addCounters(counter, game, appliedEffects);
}
@Override
public void removeCounters(String name, int amount, Game game) {}
public void removeCounters(String name, int amount, Game game) {
card.removeCounters(name, amount, game);
}
@Override
public void removeCounters(Counter counter, Game game) {}
public void removeCounters(Counter counter, Game game) {
card.removeCounters(counter, game);
}
public Card getCard() {
return card;

View file

@ -105,13 +105,10 @@ public class SpellStack extends ArrayDeque<StackObject> {
public Spell getSpell(UUID id) {
for (StackObject stackObject: this) {
if (stackObject.getId().equals(id)) {
if (stackObject instanceof Spell) {
if (stackObject instanceof Spell) {
if (stackObject.getId().equals(id) || stackObject.getSourceId().equals(id)) {
return (Spell)stackObject;
}
else {
return null;
}
}
}
return null;

View file

@ -72,7 +72,7 @@ public class Round {
public boolean isRoundOver() {
boolean roundIsOver = true;
for (TournamentPairing pair: pairs) {
if (pair.getMatch() != null && !pair.getMatch().isMatchOver()) {
if (pair.getMatch() != null && !pair.getMatch().hasEnded()) {
roundIsOver = false;
} else {
if (!pair.isAlreadyPublished()) {

View file

@ -78,6 +78,10 @@ public interface Tournament {
// tournament times
Date getStartTime();
Date getEndTime();
Date getStepStartTime();
void setStepStartTime(Date date);
// tournament type
TournamentType getTournamentType();
void setTournamentType(TournamentType tournamentType);

View file

@ -74,6 +74,7 @@ public abstract class TournamentImpl implements Tournament {
protected Date startTime;
protected Date endTime;
protected Date stepStartTime;
protected boolean abort;
protected String tournamentState;
@ -244,7 +245,7 @@ public abstract class TournamentImpl implements Tournament {
for (Round round: rounds) {
for (TournamentPairing pair: round.getPairs()) {
Match match = pair.getMatch();
if (match != null && match.isMatchOver()) {
if (match != null && match.hasEnded()) {
TournamentPlayer tp1 = pair.getPlayer1();
TournamentPlayer tp2 = pair.getPlayer2();
MatchPlayer mp1 = match.getPlayer(pair.getPlayer1().getPlayer().getId());
@ -302,11 +303,11 @@ public abstract class TournamentImpl implements Tournament {
matchResult.append(p2.getPlayer().getName());
matchResult.append(" (").append(mp1.getWins());
if (mp1.hasQuit()) {
matchResult.append("Q");
matchResult.append(mp1.hasTimerTimeout()?"T":"Q");
}
matchResult.append("-").append(mp2.getWins());
if (mp2.hasQuit()) {
matchResult.append("Q");
matchResult.append(mp2.hasTimerTimeout()?"T":"Q");
}
matchResult.append(") ");
return matchResult.toString();
@ -479,4 +480,18 @@ public abstract class TournamentImpl implements Tournament {
this.tournamentState = tournamentState;
}
@Override
public Date getStepStartTime() {
if (stepStartTime != null) {
return new Date(stepStartTime.getTime());
}
return null;
}
@Override
public void setStepStartTime(Date stepStartTime) {
this.stepStartTime = stepStartTime;
}
}

View file

@ -71,14 +71,17 @@ public class TournamentPairing {
this.match = match;
}
/**
* Called by eliminate tournaments after each match
*/
public void eliminatePlayers() {
if (match.isMatchOver()) {
if (match.hasEnded()) {
MatchPlayer mPlayer1 = match.getPlayer(player1.getPlayer().getId());
MatchPlayer mPlayer2 = match.getPlayer(player2.getPlayer().getId());
if (mPlayer1.hasQuit() || (!mPlayer2.hasQuit() && mPlayer1.getWins() < match.getWinsNeeded())) {
if (mPlayer1.hasQuit() || !mPlayer1.isMatchWinner()) {
player1.setEliminated();
}
if (mPlayer2.hasQuit() || (!mPlayer1.hasQuit() && mPlayer2.getWins() < match.getWinsNeeded())) {
if (mPlayer2.hasQuit() || !mPlayer2.isMatchWinner()) {
player2.setEliminated();
}
}

View file

@ -28,15 +28,8 @@
package mage.game.tournament;
import java.util.List;
import java.util.Random;
import java.util.Set;
import mage.cards.Card;
import mage.cards.decks.Deck;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.constants.Rarity;
import mage.constants.TournamentPlayerState;
import mage.players.Player;
import mage.util.TournamentUtil;

View file

@ -95,7 +95,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
}
public boolean play(Game game, UUID activePlayerId) {
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
@ -104,7 +104,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
if (beginPhase(game, activePlayerId)) {
for (Step step: steps) {
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
currentStep = step;
@ -115,7 +115,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
playStep(game);
}
}
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
count++;
@ -136,7 +136,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
}
public boolean resumePlay(Game game, PhaseStep stepType, boolean wasPaused) {
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
@ -150,7 +150,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
resumeStep(game, wasPaused);
while (it.hasNext()) {
step = it.next();
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
currentStep = step;
@ -159,7 +159,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
}
}
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return false;
}
count++;
@ -194,10 +194,10 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
protected void playStep(Game game) {
if (!currentStep.skipStep(game, activePlayerId)) {
prePriority(game, activePlayerId);
if (!game.isPaused() && !game.isGameOver()) {
if (!game.isPaused() && !game.gameOver(null)) {
currentStep.priority(game, activePlayerId, false);
}
if (!game.isPaused() && !game.isGameOver()) {
if (!game.isPaused() && !game.gameOver(null)) {
postPriority(game, activePlayerId);
}
}
@ -219,11 +219,11 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
prePriority(game, activePlayerId);
}
case PRIORITY:
if (!game.isPaused() && !game.isGameOver()) {
if (!game.isPaused() && !game.gameOver(null)) {
currentStep.priority(game, activePlayerId, resuming);
}
case POST:
if (!game.isPaused() && !game.isGameOver()) {
if (!game.isPaused() && !game.gameOver(null)) {
postPriority(game, activePlayerId);
}
}

View file

@ -47,7 +47,7 @@ public class Turn implements Serializable {
private Phase currentPhase;
private UUID activePlayerId;
private List<Phase> phases = new ArrayList<Phase>();
private final List<Phase> phases = new ArrayList<>();
private boolean declareAttackersStepStarted = false;
public Turn() {
@ -109,7 +109,7 @@ public class Turn implements Serializable {
public void play(Game game, UUID activePlayerId) {
this.setDeclareAttackersStepStarted(false);
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return;
}
@ -123,7 +123,7 @@ public class Turn implements Serializable {
resetCounts();
game.getPlayer(activePlayerId).beginTurn(game);
for (Phase phase: phases) {
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return;
}
currentPhase = phase;
@ -168,7 +168,7 @@ public class Turn implements Serializable {
}
while (it.hasNext()) {
phase = it.next();
if (game.isPaused() || game.isGameOver()) {
if (game.isPaused() || game.gameOver(null)) {
return;
}
currentPhase = phase;

View file

@ -129,6 +129,10 @@ public interface Player extends MageItem, Copyable<Player> {
boolean hasWon();
boolean hasQuit();
void quit(Game game);
boolean hasTimerTimeout();
void timerTimeout(Game game);
boolean hasIdleTimeout();
void idleTimeout(Game game);
boolean hasLeft();
/**
* Player is still active in game (has not left, lost or won the game).

View file

@ -114,7 +114,10 @@ import mage.target.common.TargetDiscard;
import mage.watchers.common.BloodthirstWatcher;
import org.apache.log4j.Logger;
/**
*
* * @param <T>
*/
public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable {
private static final transient Logger log = Logger.getLogger(PlayerImpl.class);
@ -160,6 +163,10 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
protected boolean left;
// set if the player quits the complete match
protected boolean quit;
// set if the player lost match because of priority timeout
protected boolean timerTimeout;
// set if the player lost match because of idle timeout
protected boolean idleTimeout;
protected RangeOfInfluence range;
protected Set<UUID> inRange = new HashSet<>();
@ -234,6 +241,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.left = player.left;
this.quit = player.quit;
this.timerTimeout = player.timerTimeout;
this.idleTimeout = player.idleTimeout;
this.range = player.range;
this.canGainLife = player.canGainLife;
this.canLoseLife = player.canLoseLife;
@ -288,6 +297,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.left = player.hasLeft();
this.quit = player.hasQuit();
this.timerTimeout = player.hasTimerTimeout();
this.idleTimeout = player.hasIdleTimeout();
this.range = player.getRange();
this.canGainLife = player.isCanGainLife();
this.canLoseLife = player.isCanLoseLife();
@ -343,7 +354,11 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
this.wins = false;
this.loses = false;
this.left = false;
this.quit = false; // reset is neccessary because in tournament player will be used for each round
// reset is neccessary because in tournament player will be used for each round
this.quit = false;
this.timerTimeout = false;
this.idleTimeout = false;
this.passed = false;
this.passedTurn = false;
this.passedAllTurns = false;
@ -732,7 +747,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
resetStoredBookmark(game);
return true;
}
if (!game.isGameOver()) { // if player left or game is over no undo is possible - this could lead to wrong winner
if (!game.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner
game.restoreState(bookmark);
}
}
@ -1475,13 +1490,30 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
@Override
public void quit(Game game) {
game.informPlayers(new StringBuilder(getName()).append(" quits the match.").toString());
quit = true;
this.concede(game);
}
@Override
public void timerTimeout(Game game) {
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
quit = true;
timerTimeout = true;
this.concede(game);
}
@Override
public void idleTimeout(Game game) {
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
quit = true;
idleTimeout = true;
this.concede(game);
}
@Override
public void concede(Game game) {
game.leave(playerId);
game.gameOver(playerId);
lost(game);
this.left = true;
}
@ -2117,6 +2149,16 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
return quit;
}
@Override
public boolean hasTimerTimeout() {
return timerTimeout;
}
@Override
public boolean hasIdleTimeout() {
return idleTimeout;
}
@Override
public void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving) {
this.reachedNextTurnAfterLeaving = reachedNextTurnAfterLeaving;