mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Merge origin/master
This commit is contained in:
commit
60e512580f
12 changed files with 203 additions and 90 deletions
|
@ -169,7 +169,7 @@
|
|||
<Group type="102" attributes="0">
|
||||
<Component id="pnlPacks" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pnlRandomPacks" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pnlRandomPacks" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Group type="103" alignment="1" groupAlignment="3" attributes="0">
|
||||
|
@ -521,10 +521,8 @@
|
|||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
|
||||
<Property name="columns" type="int" value="1"/>
|
||||
<Property name="horizontalGap" type="int" value="2"/>
|
||||
<Property name="rows" type="int" value="0"/>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||
<Property name="axis" type="int" value="1"/>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
|
||||
package mage.client.dialog;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.swing.ComboBoxModel;
|
||||
|
@ -122,8 +124,8 @@ public class NewTournamentDialog extends MageDialog {
|
|||
cbAllowSpectators.setSelected(true);
|
||||
setTournamentSettingsFromPrefs();
|
||||
this.setModal(true);
|
||||
this.setLocation(150, 100);
|
||||
}
|
||||
this.setLocation(150, 100);
|
||||
}
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
@ -341,7 +343,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
|
||||
pnlRandomPacks.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
pnlRandomPacks.setToolTipText("");
|
||||
pnlRandomPacks.setLayout(new java.awt.GridLayout(0, 1, 2, 0));
|
||||
pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
|
@ -468,7 +470,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlRandomPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(pnlRandomPacks, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
|
@ -477,7 +479,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
.addComponent(lblNumRounds))
|
||||
.addComponent(lblNbrPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(spnNumPlayers)
|
||||
.addComponent(pnlDraftOptions, javax.swing.GroupLayout.DEFAULT_SIZE, 0, Short.MAX_VALUE))
|
||||
.addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblPlayer1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
|
@ -533,7 +535,18 @@ public class NewTournamentDialog extends MageDialog {
|
|||
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
|
||||
} else if (tournamentType.isRandom()) {
|
||||
tOptions.getLimitedOptions().getSetCodes().clear();
|
||||
tOptions.getLimitedOptions().getSetCodes().addAll(randomPackSelector.getSelectedPacks());
|
||||
ArrayList<String> selected = randomPackSelector.getSelectedPacks();
|
||||
int maxPacks = 3 * (players.size() + 1);
|
||||
if (selected.size() > maxPacks ){
|
||||
StringBuilder infoString = new StringBuilder("More sets were selected than needed. ");
|
||||
infoString.append(maxPacks);
|
||||
infoString.append(" sets will be randomly chosen.");
|
||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), infoString, "Information", JOptionPane.INFORMATION_MESSAGE);
|
||||
Collections.shuffle(selected);
|
||||
tOptions.getLimitedOptions().getSetCodes().addAll(selected.subList(0, maxPacks));
|
||||
}else{
|
||||
tOptions.getLimitedOptions().getSetCodes().addAll(selected);
|
||||
}
|
||||
} else {
|
||||
for (JComboBox pack: packs) {
|
||||
tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode());
|
||||
|
@ -717,6 +730,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
if (pnlRandomPacks.getComponentCount() == 0) {
|
||||
if (randomPackSelector == null) {
|
||||
randomPackSelector = new RandomPacksSelectorDialog();
|
||||
randomPackSelector.setLocationRelativeTo(this);
|
||||
}
|
||||
txtRandomPacks = new JTextArea();
|
||||
txtRandomPacks.setEnabled(false);
|
||||
|
@ -736,9 +750,10 @@ public class NewTournamentDialog extends MageDialog {
|
|||
}
|
||||
txtRandomPacks.setText(packList.toString());
|
||||
}
|
||||
|
||||
txtRandomPacks.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
pnlRandomPacks.add(txtRandomPacks);
|
||||
JButton btnSelectRandomPacks = new JButton();
|
||||
btnSelectRandomPacks.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
btnSelectRandomPacks.setText("Select packs to be included in the pool");
|
||||
btnSelectRandomPacks.setToolTipText(RandomPacksSelectorDialog.randomDraftDescription);
|
||||
btnSelectRandomPacks.addActionListener(new java.awt.event.ActionListener() {
|
||||
|
@ -749,11 +764,11 @@ public class NewTournamentDialog extends MageDialog {
|
|||
}
|
||||
});
|
||||
pnlRandomPacks.add(btnSelectRandomPacks);
|
||||
}
|
||||
}
|
||||
this.pack();
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void showRandomPackSelectorDialog() {
|
||||
randomPackSelector.showDialog();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="0"/>
|
||||
<Property name="title" type="java.lang.String" value="Random Booster Draft Packs Selector"/>
|
||||
<Property name="modal" type="boolean" value="true"/>
|
||||
<Property name="modalExclusionType" type="java.awt.Dialog$ModalExclusionType" editor="org.netbeans.modules.form.editors.EnumEditor">
|
||||
|
@ -16,6 +17,9 @@
|
|||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
|
|
|
@ -8,6 +8,7 @@ package mage.client.dialog;
|
|||
import java.awt.Component;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JOptionPane;
|
||||
import mage.cards.repository.ExpansionInfo;
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
|
||||
|
@ -101,11 +102,17 @@ public class RandomPacksSelectorDialog extends javax.swing.JDialog {
|
|||
pnlApply = new javax.swing.JPanel();
|
||||
btnApply = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
setTitle("Random Booster Draft Packs Selector");
|
||||
setModal(true);
|
||||
setModalExclusionType(java.awt.Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
|
||||
setPreferredSize(new java.awt.Dimension(600, 450));
|
||||
setResizable(false);
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosing(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pnlPacks.setLayout(new java.awt.GridLayout(11, 12));
|
||||
|
||||
|
@ -174,13 +181,21 @@ public class RandomPacksSelectorDialog extends javax.swing.JDialog {
|
|||
}//GEN-LAST:event_btnNoneActionPerformed
|
||||
|
||||
private void btnApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnApplyActionPerformed
|
||||
this.doApply();
|
||||
}//GEN-LAST:event_btnApplyActionPerformed
|
||||
|
||||
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
|
||||
this.doApply();
|
||||
}//GEN-LAST:event_formWindowClosing
|
||||
|
||||
public void doApply() {
|
||||
if (getSelectedPacks().size() < 2) {
|
||||
// at least 2 packs must be selected.
|
||||
JOptionPane.showMessageDialog(this, "At least 2 sets must be selected", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
this.setVisible(false);
|
||||
}
|
||||
}//GEN-LAST:event_btnApplyActionPerformed
|
||||
|
||||
}
|
||||
|
||||
private void setAllCheckBoxes(boolean value) {
|
||||
for (Component pack : pnlPacks.getComponents()) {
|
||||
JCheckBox thePack = (JCheckBox) pack;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
|||
public final static int MAGE_VERSION_MAJOR = 1;
|
||||
public final static int MAGE_VERSION_MINOR = 4;
|
||||
public final static int MAGE_VERSION_PATCH = 2;
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "v2";
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "v3";
|
||||
public final static String MAGE_VERSION_INFO = "";
|
||||
|
||||
private final int major;
|
||||
|
|
|
@ -80,6 +80,13 @@ public class TournamentFactory {
|
|||
if (tournament.getTournamentType().isCubeBooster()) {
|
||||
tournament.getOptions().getLimitedOptions().setDraftCube(CubeFactory.getInstance().createDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName()));
|
||||
tournament.setBoosterInfo(tournament.getOptions().getLimitedOptions().getDraftCubeName());
|
||||
} else if (tournament.getTournamentType().isRandom()) {
|
||||
StringBuilder rv = new StringBuilder( "Random Draft using sets: ");
|
||||
for (Map.Entry<String, Integer> entry: setInfo.entrySet()){
|
||||
rv.append(entry.getKey());
|
||||
rv.append(";");
|
||||
}
|
||||
tournament.setBoosterInfo(rv.toString());
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String,Integer> entry:setInfo.entrySet()) {
|
||||
|
|
|
@ -37,32 +37,31 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
* @author LevelX2
|
||||
*/
|
||||
public class DeathtouchTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
@Test
|
||||
public void simpleDeathtouchDuringCombat() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archangel of Thune");
|
||||
// Creature - Rat 1/1
|
||||
// Deathtouch
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Typhoid Rats");
|
||||
|
||||
|
||||
|
||||
attack(2, playerB, "Typhoid Rats");
|
||||
block(2, playerA, "Archangel of Thune", "Typhoid Rats");
|
||||
|
||||
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
|
||||
assertLife(playerA, 23);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
|
||||
assertGraveyardCount(playerA, "Archangel of Thune", 1);
|
||||
assertGraveyardCount(playerB, "Typhoid Rats", 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a creature getting damage from Marath abilitity dies
|
||||
* from Deathtouch, if Marath is equiped with Deathtouch giving Equipment
|
||||
* and Marath dies from removing the +1/+1 counters.
|
||||
* Checks if a creature getting damage from Marath abilitity dies from
|
||||
* Deathtouch, if Marath is equiped with Deathtouch giving Equipment and
|
||||
* Marath dies from removing the +1/+1 counters.
|
||||
*/
|
||||
@Test
|
||||
public void testMarathWillOfTheWild() {
|
||||
|
@ -73,21 +72,20 @@ public class DeathtouchTest extends CardTestPlayerBase {
|
|||
// Equipped creature has deathtouch and lifelink.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Basilisk Collar");
|
||||
/*
|
||||
{R}{G}{W} Legendary Creature - Elemental Beast
|
||||
Marath, Will of the Wild enters the battlefield with a number of +1/+1 counters on
|
||||
it equal to the amount of mana spent to cast it.
|
||||
{X}, Remove X +1/+1 counters from Marath: Choose one -
|
||||
* Put X +1/+1 counters on target creature
|
||||
* Marath deals X damage to target creature or player
|
||||
* Put an X/X green Elemental creature token onto the battlefield. X can't be 0
|
||||
*/
|
||||
{R}{G}{W} Legendary Creature - Elemental Beast
|
||||
Marath, Will of the Wild enters the battlefield with a number of +1/+1 counters on
|
||||
it equal to the amount of mana spent to cast it.
|
||||
{X}, Remove X +1/+1 counters from Marath: Choose one -
|
||||
* Put X +1/+1 counters on target creature
|
||||
* Marath deals X damage to target creature or player
|
||||
* Put an X/X green Elemental creature token onto the battlefield. X can't be 0
|
||||
*/
|
||||
addCard(Zone.HAND, playerA, "Marath, Will of the Wild", 1);
|
||||
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Archangel of Thune");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN , playerA, "Marath, Will of the Wild");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Marath, Will of the Wild");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Archangel of Thune");
|
||||
|
@ -104,6 +102,45 @@ public class DeathtouchTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMarathWillOfTheWildEleshNorn() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
|
||||
|
||||
// Equipped creature has deathtouch and lifelink.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Basilisk Collar");
|
||||
/*
|
||||
{R}{G}{W} Legendary Creature - Elemental Beast
|
||||
Marath, Will of the Wild enters the battlefield with a number of +1/+1 counters on
|
||||
it equal to the amount of mana spent to cast it.
|
||||
{X}, Remove X +1/+1 counters from Marath: Choose one -
|
||||
* Put X +1/+1 counters on target creature
|
||||
* Marath deals X damage to target creature or player
|
||||
* Put an X/X green Elemental creature token onto the battlefield. X can't be 0
|
||||
*/
|
||||
addCard(Zone.HAND, playerA, "Marath, Will of the Wild", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Elesh Norn, Grand Cenobite");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Marath, Will of the Wild");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Elesh Norn, Grand Cenobite");
|
||||
setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player
|
||||
setChoice(playerA, "X=1");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Marath, Will of the Wild", 0); // died because he's 0/0
|
||||
assertPermanentCount(playerB, "Elesh Norn, Grand Cenobite", 0); // died from deathtouch
|
||||
|
||||
assertLife(playerA, 21); // +1 from lifelink doing 1 damage with Marath to Elesh Norn
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -41,23 +40,20 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
public class StormTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* 702.39. Storm
|
||||
* 702.39a Storm is a triggered ability that functions on the stack. “Storm” means “When you cast this
|
||||
* spell, put a copy of it onto the stack for each other spell that was cast before it this turn. If the
|
||||
* 702.39. Storm 702.39a Storm is a triggered ability that functions on the
|
||||
* stack. “Storm” means “When you cast this spell, put a copy of it onto the
|
||||
* stack for each other spell that was cast before it this turn. If the
|
||||
* spell has any targets, you may choose new targets for any of the copies.”
|
||||
* 702.39b If a spell has multiple instances of storm, each triggers separately.
|
||||
*
|
||||
* 702.39b If a spell has multiple instances of storm, each triggers
|
||||
* separately.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Grapeshot
|
||||
* Sorcery, 1R (2)
|
||||
* Grapeshot deals 1 damage to target creature or player.
|
||||
* Storm (When you cast this spell, copy it for each spell cast before it
|
||||
* this turn. You may choose new targets for the copies.)
|
||||
*
|
||||
* Grapeshot Sorcery, 1R (2) Grapeshot deals 1 damage to target creature or
|
||||
* player. Storm (When you cast this spell, copy it for each spell cast
|
||||
* before it this turn. You may choose new targets for the copies.)
|
||||
*
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testStorm1x() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
|
@ -105,7 +101,7 @@ public class StormTest extends CardTestPlayerBase {
|
|||
|
||||
assertLife(playerB, 7);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStorm4x() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
|
||||
|
@ -123,7 +119,7 @@ public class StormTest extends CardTestPlayerBase {
|
|||
|
||||
assertLife(playerB, 3);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoStorm() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
|
@ -136,13 +132,13 @@ public class StormTest extends CardTestPlayerBase {
|
|||
|
||||
assertLife(playerB, 19);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If a spell with storm gets countered, the strom trigger is also stifled, which isn't how its supposed to work.
|
||||
* For example a Chalic of the Void set to 1 counters Flusterstorm and also counters the storm trigger, which shouldn't happen
|
||||
* If a spell with storm gets countered, the strom trigger is also stifled,
|
||||
* which isn't how its supposed to work. For example a Chalic of the Void
|
||||
* set to 1 counters Flusterstorm and also counters the storm trigger, which
|
||||
* shouldn't happen
|
||||
*/
|
||||
|
||||
|
||||
@Test
|
||||
public void testStormSpellCountered() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
|
@ -155,20 +151,21 @@ public class StormTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Counterspell", "Grapeshot");
|
||||
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 16); // 3 (Lightning Bolt) + 1 from Storm copied Grapeshot
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* I provide a game log fo the issue with storm mentioned earlier. I guess Pyromancer Ascension is a culprit.
|
||||
*
|
||||
*
|
||||
* I provide a game log fo the issue with storm mentioned earlier. I guess
|
||||
* Pyromancer Ascension is a culprit.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testStormAndPyromancerAscension() {
|
||||
|
@ -178,7 +175,7 @@ public class StormTest extends CardTestPlayerBase {
|
|||
// Whenever you cast an instant or sorcery spell while Pyromancer Ascension has two or more quest counters on it, you may copy that spell. You may choose new targets for the copy.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Pyromancer Ascension", 1);
|
||||
// Grapeshot deals 1 damage to target creature or player. - Sorcery {1}{R}
|
||||
// Storm (When you cast this spell, copy it for each spell cast before it this turn. You may choose new targets for the copies.)
|
||||
// Storm (When you cast this spell, copy it for each spell cast before it this turn. You may choose new targets for the copies.)
|
||||
addCard(Zone.LIBRARY, playerA, "Grapeshot", 2);
|
||||
skipInitShuffling();
|
||||
// Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
|
@ -198,5 +195,40 @@ public class StormTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Grapeshot", 1);
|
||||
assertCounterCount("Pyromancer Ascension", CounterType.QUEST, 2);
|
||||
assertLife(playerB, 8); // 6 from the Shocks + 5 from Grapeshot + 1 from Pyromancer Ascencsion copy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* I provide a game log fo the issue with storm mentioned earlier. I guess
|
||||
* Pyromancer Ascension is a culprit.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testStormAndFlshback() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
// Geistflame deals 1 damage to target creature or player.
|
||||
// Flashback {3}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it.)
|
||||
addCard(Zone.HAND, playerA, "Geistflame", 2); // {R}
|
||||
addCard(Zone.LIBRARY, playerA, "Grapeshot", 2);
|
||||
skipInitShuffling();
|
||||
// Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
addCard(Zone.HAND, playerA, "Sleight of Hand");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sleight of Hand");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Geistflame", playerB);
|
||||
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Flashback {3}{R}");
|
||||
addTarget(playerA, playerB);
|
||||
castSpell(1, PhaseStep.END_COMBAT, playerA, "Geistflame", playerB);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertExileCount("Geistflame", 1);
|
||||
assertGraveyardCount(playerA, "Geistflame", 1);
|
||||
assertGraveyardCount(playerA, "Grapeshot", 1);
|
||||
assertLife(playerB, 12); // 3 from the Geistflame + 5 from Grapeshot
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -112,6 +112,26 @@ public abstract class ExpansionSet implements Serializable {
|
|||
return name;
|
||||
}
|
||||
|
||||
public List<Card> create15CardBooster() {
|
||||
// Forces 15 card booster packs.
|
||||
// if the packs are too small, it adds commons to fill it out.
|
||||
// if the packs are too big, it removes the first cards.
|
||||
// since it adds lands then commons before uncommons
|
||||
// and rares this should be the least disruptive.
|
||||
|
||||
List<Card> theBooster = this.createBooster();
|
||||
List<CardInfo> commons = getCardsByRarity(Rarity.COMMON);
|
||||
while (15 > theBooster.size()) {
|
||||
addToBooster(theBooster, commons);
|
||||
}
|
||||
|
||||
while (theBooster.size() > 15) {
|
||||
theBooster.remove(0);
|
||||
}
|
||||
|
||||
return theBooster;
|
||||
}
|
||||
|
||||
public List<Card> createBooster() {
|
||||
List<Card> booster = new ArrayList<>();
|
||||
if (!hasBoosters) {
|
||||
|
|
|
@ -60,7 +60,7 @@ public enum CardRepository {
|
|||
// raise this if db structure was changed
|
||||
private static final long CARD_DB_VERSION = 41;
|
||||
// raise this if new cards were added to the server
|
||||
private static final long CARD_CONTENT_VERSION = 26;
|
||||
private static final long CARD_CONTENT_VERSION = 29;
|
||||
|
||||
private final Random random = new Random();
|
||||
private Dao<CardInfo, Object> cardDao;
|
||||
|
|
|
@ -50,28 +50,11 @@ public class RandomBoosterDraft extends BoosterDraft {
|
|||
resetBoosters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
while (!isAbort() && boosterNum < numberBoosters) {
|
||||
openBooster();
|
||||
while (!isAbort() && pickCards()) {
|
||||
if (boosterNum % 2 == 1) {
|
||||
passLeft();
|
||||
} else {
|
||||
passRight();
|
||||
}
|
||||
fireUpdatePlayersEvent();
|
||||
}
|
||||
}
|
||||
resetBufferedCards();
|
||||
this.fireEndDraftEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openBooster() {
|
||||
if (boosterNum < numberBoosters) {
|
||||
for (DraftPlayer player: players.values()) {
|
||||
player.setBooster(getNextBooster().createBooster());
|
||||
player.setBooster(getNextBooster().create15CardBooster());
|
||||
}
|
||||
}
|
||||
boosterNum++;
|
||||
|
|
|
@ -149,9 +149,11 @@ git log cd0cba6ec7d8799bb85247b7b4f5d545e170b093..HEAD --diff-filter=A --name-st
|
|||
since 1.4.2.v1
|
||||
git log 0b26aaff6ec033a538179bf607b1c7a7736aedb2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
|
||||
|
||||
since 1.4.2.v1
|
||||
since 1.4.2.v2
|
||||
git log 8d5137e40ebe1c029e737ef475935ff7cc40bb64..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
|
||||
|
||||
since 1.4.2.v3
|
||||
git log 60c7a2b34b5dd9a64bd415b65424a559294cf52b..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
|
||||
|
||||
3. Copy added_cards.txt to trunk\Utils folder
|
||||
4. Run script:
|
||||
|
|
Loading…
Reference in a new issue