diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
index afaf19627ed..b15bbcdd6aa 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
@@ -82,8 +82,8 @@
-
-
+
+
@@ -159,7 +159,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
@@ -231,7 +231,7 @@
-
+
@@ -381,8 +381,8 @@
-
-
+
+
@@ -528,8 +528,8 @@
-
-
+
+
@@ -537,7 +537,7 @@
-
+
@@ -628,7 +628,7 @@
-
+
@@ -675,6 +675,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
index c7cbbb722c8..d655432110c 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
@@ -135,6 +135,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_STOP_BLOCK = "stopDeclareBlockersStep";
public static final String KEY_STOP_ALL_MAIN_PHASES = "stopOnAllMainPhases";
public static final String KEY_STOP_ALL_END_PHASES = "stopOnAllEndPhases";
+ public static final String KEY_PASS_PRIORITY_CAST = "passPriorityCast";
+ public static final String KEY_PASS_PRIORITY_ACTIVATION = "passPriorityActivation";
+ public static final String KEY_AUTO_ORDER_TRIGGER = "autoOrderTrigger";
// mana auto payment
public static final String KEY_GAME_MANA_AUTOPAYMENT = "gameManaAutopayment";
@@ -394,6 +397,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbStopBlock = new javax.swing.JCheckBox();
cbStopOnAllMain = new javax.swing.JCheckBox();
cbStopOnAllEnd = new javax.swing.JCheckBox();
+ cbPassPriorityCast = new javax.swing.JCheckBox();
+ cbPassPriorityActivation = new javax.swing.JCheckBox();
+ cbAutoOrderTrigger = new javax.swing.JCheckBox();
tabImages = new javax.swing.JPanel();
panelCardImages = new javax.swing.JPanel();
cbUseDefaultImageFolder = new javax.swing.JCheckBox();
@@ -629,7 +635,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(cbConfirmEmptyManaPool)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbAskMoveToGraveOrder)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
);
nonLandPermanentsInOnePile.getAccessibleContext().setAccessibleName("nonLandPermanentsInOnePile");
@@ -691,8 +697,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addContainerGap()
.addComponent(main_card, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(main_game, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(main_game, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(main_gamelog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
@@ -701,7 +707,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Main", tabMain);
- jLabelHeadLine.setText("Choose phases your game will stop on:");
+ jLabelHeadLine.setText("Choose phases your game will stop on if not skipped by a skip action (e.g. F6):");
jLabelYourTurn.setText("Your turn");
@@ -722,7 +728,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
jLabelEndOfTurn.setText("End of turn:");
phases_stopSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Stop settings"));
- phases_stopSettings.setLayout(new java.awt.GridLayout(4, 1));
+ phases_stopSettings.setLayout(new java.awt.GridLayout(7, 1));
cbStopAttack.setSelected(true);
cbStopAttack.setText("Stop on declare attackers step if you skip steps (F4/F5/F7) and attackers are available");
@@ -766,6 +772,39 @@ public class PreferencesDialog extends javax.swing.JDialog {
});
phases_stopSettings.add(cbStopOnAllEnd);
+ cbPassPriorityCast.setText("Pass priority automatically after you have put a spell on the stack");
+ cbPassPriorityCast.setToolTipText("If activated the system passes priority automatically for you if you have put a spell on the stack.");
+ cbPassPriorityCast.setActionCommand("");
+ cbPassPriorityCast.setPreferredSize(new java.awt.Dimension(300, 25));
+ cbPassPriorityCast.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cbPassPriorityCastActionPerformed(evt);
+ }
+ });
+ phases_stopSettings.add(cbPassPriorityCast);
+
+ cbPassPriorityActivation.setText("Pass priority automatically after you have put an activated ability on the stack");
+ cbPassPriorityActivation.setToolTipText("If activated the system passes priority for you automatically after you have put an activated ability on the stack.");
+ cbPassPriorityActivation.setActionCommand("");
+ cbPassPriorityActivation.setPreferredSize(new java.awt.Dimension(300, 25));
+ cbPassPriorityActivation.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cbPassPriorityActivationActionPerformed(evt);
+ }
+ });
+ phases_stopSettings.add(cbPassPriorityActivation);
+
+ cbAutoOrderTrigger.setText("Set order for your triggers automatically if all have the same text");
+ cbAutoOrderTrigger.setToolTipText("If activated the order to put on the stack your triggers that trigger at the same time
\nis set automatically if all have the same text.");
+ cbAutoOrderTrigger.setActionCommand("");
+ cbAutoOrderTrigger.setPreferredSize(new java.awt.Dimension(300, 25));
+ cbAutoOrderTrigger.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cbAutoOrderTriggerActionPerformed(evt);
+ }
+ });
+ phases_stopSettings.add(cbAutoOrderTrigger);
+
javax.swing.GroupLayout tabPhasesLayout = new javax.swing.GroupLayout(tabPhases);
tabPhases.setLayout(tabPhasesLayout);
tabPhasesLayout.setHorizontalGroup(
@@ -876,11 +915,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(jLabelEndOfTurn)
.addComponent(checkBoxEndTurnOthers))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(phases_stopSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(45, Short.MAX_VALUE))
+ .addComponent(phases_stopSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap())
);
- tabsPanel.addTab("Phases", tabPhases);
+ tabsPanel.addTab("Phases & Priority", tabPhases);
panelCardImages.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card images:"));
@@ -1699,7 +1738,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbDraftLogAutoSave, KEY_DRAFT_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
- // Phases
+ // Phases & Priority
save(prefs, dialog.checkBoxUpkeepYou, UPKEEP_YOU);
save(prefs, dialog.checkBoxDrawYou, DRAW_YOU);
save(prefs, dialog.checkBoxMainYou, MAIN_YOU);
@@ -1720,6 +1759,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.cbStopBlock, KEY_STOP_BLOCK, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbStopOnAllMain, KEY_STOP_ALL_MAIN_PHASES, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbStopOnAllEnd, KEY_STOP_ALL_END_PHASES, "true", "false", UPDATE_CACHE_POLICY);
+ save(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false", UPDATE_CACHE_POLICY);
+ save(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false", UPDATE_CACHE_POLICY);
+ save(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "false", UPDATE_CACHE_POLICY);
// images
save(prefs, dialog.cbUseDefaultImageFolder, KEY_CARD_IMAGES_USE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY);
@@ -2022,6 +2064,18 @@ public class PreferencesDialog extends javax.swing.JDialog {
// TODO add your handling code here:
}//GEN-LAST:event_cbDraftLogAutoSaveActionPerformed
+ private void cbPassPriorityCastActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbPassPriorityCastActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_cbPassPriorityCastActionPerformed
+
+ private void cbPassPriorityActivationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbPassPriorityActivationActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_cbPassPriorityActivationActionPerformed
+
+ private void cbAutoOrderTriggerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbAutoOrderTriggerActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_cbAutoOrderTriggerActionPerformed
+
private void showProxySettings() {
if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) {
this.pnlProxy.setVisible(true);
@@ -2122,6 +2176,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.cbStopBlock, KEY_STOP_BLOCK, "true", "true");
load(prefs, dialog.cbStopOnAllMain, KEY_STOP_ALL_MAIN_PHASES, "true", "false");
load(prefs, dialog.cbStopOnAllEnd, KEY_STOP_ALL_END_PHASES, "true", "false");
+ load(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false");
+ load(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false");
+ load(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "true");
}
@@ -2456,7 +2513,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
MageFrame.getPreferences().get(KEY_CONNECT_FLAG, "world"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
- PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true")
+ PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
+ PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_CAST, "true").equals("true"),
+ PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_ACTIVATION, "true").equals("true"),
+ PreferencesDialog.getCachedValue(PreferencesDialog.KEY_AUTO_ORDER_TRIGGER, "true").equals("true")
);
}
@@ -2469,6 +2529,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JButton btnBrowseImageLocation;
private javax.swing.JCheckBox cbAllowRequestToShowHandCards;
private javax.swing.JCheckBox cbAskMoveToGraveOrder;
+ private javax.swing.JCheckBox cbAutoOrderTrigger;
private javax.swing.JCheckBox cbCheckForNewImages;
private javax.swing.JCheckBox cbConfirmEmptyManaPool;
private javax.swing.JCheckBox cbDraftLogAutoSave;
@@ -2478,6 +2539,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox cbEnableOtherSounds;
private javax.swing.JCheckBox cbEnableSkipButtonsSounds;
private javax.swing.JCheckBox cbGameLogAutoSave;
+ private javax.swing.JCheckBox cbPassPriorityActivation;
+ private javax.swing.JCheckBox cbPassPriorityCast;
private javax.swing.JComboBox cbPreferedImageLanguage;
private javax.swing.JComboBox cbProxyType;
private javax.swing.JCheckBox cbSaveToZipFiles;
diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
index b628991865e..73fba0f4eae 100644
--- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
@@ -562,6 +562,18 @@ public class HumanPlayer extends PlayerImpl {
public boolean priority(Game game) {
passed = false;
if (!abort) {
+ if (getJustActivatedType() != null) {
+ if (userData.isPassPriorityCast() && getJustActivatedType().equals(AbilityType.SPELL)) {
+ setJustActivatedType(null);
+ pass(game);
+ return false;
+ }
+ if (userData.isPassPriorityActivation() && getJustActivatedType().equals(AbilityType.ACTIVATED)) {
+ setJustActivatedType(null);
+ pass(game);
+ return false;
+ }
+ }
if (passedAllTurns) {
if (passWithManaPoolCheck(game)) {
return false;
@@ -693,6 +705,8 @@ public class HumanPlayer extends PlayerImpl {
@Override
public TriggeredAbility chooseTriggeredAbility(List abilities, Game game) {
+ String autoOrderRuleText = null;
+ boolean autoOrderUse = getUserData().isAutoOrderTrigger();
while (!abort) {
// try to set trigger auto order
List abilitiesWithNoOrderSet = new ArrayList<>();
@@ -712,12 +726,19 @@ public class HumanPlayer extends PlayerImpl {
abilityOrderLast = ability;
continue;
}
+ if (autoOrderUse) {
+ if (autoOrderRuleText == null) {
+ autoOrderRuleText = ability.getRule();
+ } else if (!ability.getRule().equals(autoOrderRuleText)) {
+ autoOrderUse = false;
+ }
+ }
abilitiesWithNoOrderSet.add(ability);
}
if (abilitiesWithNoOrderSet.isEmpty()) {
return abilityOrderLast;
}
- if (abilitiesWithNoOrderSet.size() == 1) {
+ if (abilitiesWithNoOrderSet.size() == 1 || autoOrderUse) {
return abilitiesWithNoOrderSet.iterator().next();
}
updateGameStatePriority("chooseTriggeredAbility", game);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
index f980b8be196..7c63a8447f1 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
@@ -27,7 +27,6 @@
*/
package org.mage.test.cards.abilities.keywords;
-
import mage.cards.Card;
import mage.constants.PhaseStep;
import mage.constants.Zone;
@@ -39,7 +38,6 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
-
public class ManifestTest extends CardTestPlayerBase {
/**
@@ -73,7 +71,8 @@ public class ManifestTest extends CardTestPlayerBase {
}
/**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not trigger
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
*/
@Test
public void testETBTriggeredAbilities2() {
@@ -103,8 +102,10 @@ public class ManifestTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
}
+
/**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not trigger
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
*/
@Test
public void testETBTriggeredAbilities3() {
@@ -115,10 +116,10 @@ public class ManifestTest extends CardTestPlayerBase {
// Constellation - When Doomwake Giant or another enchantment enters the battlefield
// under your control, creatures your opponents control get -1/-1 until end of turn.
addCard(Zone.LIBRARY, playerA, "Doomwake Giant");
-
- addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
-
+
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
@@ -130,7 +131,7 @@ public class ManifestTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion" , 1);
+ assertExileCount("Silvercoat Lion", 1);
// a facedown creature is on the battlefield
assertPermanentCount(playerA, "", 1);
assertPowerToughness(playerA, "", 2, 2);
@@ -138,8 +139,10 @@ public class ManifestTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Pillarfield Ox", 1);
assertPowerToughness(playerB, "Pillarfield Ox", 2, 4);
}
+
/**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not trigger
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
*/
@Test
public void testNylea() {
@@ -150,7 +153,7 @@ public class ManifestTest extends CardTestPlayerBase {
// As long as your devotion to white is less than five, Nylea isn't a creature.
// (Each {G} in the mana costs of permanents you control counts towards your devotion to green.)
addCard(Zone.LIBRARY, playerA, "Nylea, God of the Hunt");
-
+
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
skipInitShuffling();
@@ -164,17 +167,17 @@ public class ManifestTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion" , 1);
+ assertExileCount("Silvercoat Lion", 1);
// a facedown creature is on the battlefield
assertPermanentCount(playerA, "", 1);
assertPowerToughness(playerA, "", 2, 2);
}
-
+
/*
- Had a Foundry Street Denizen and another creature out.
- Opponent Reality Shift'ed the other creature, manifested card was a red creature. This pumped the foundry street denizen even though it shouldn't.
- */
+ Had a Foundry Street Denizen and another creature out.
+ Opponent Reality Shift'ed the other creature, manifested card was a red creature. This pumped the foundry street denizen even though it shouldn't.
+ */
@Test
public void testColorOfManifestedCardDoesNotCount() {
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
@@ -184,7 +187,7 @@ public class ManifestTest extends CardTestPlayerBase {
// Gore Swine {2}{R}
// 4/1
addCard(Zone.LIBRARY, playerA, "Gore Swine");
-
+
// Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
addCard(Zone.BATTLEFIELD, playerA, "Foundry Street Denizen");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
@@ -200,16 +203,17 @@ public class ManifestTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion" , 1);
+ assertExileCount("Silvercoat Lion", 1);
// a facedown creature is on the battlefield
assertPermanentCount(playerA, "", 1);
assertPowerToughness(playerA, "", 2, 2);
assertPowerToughness(playerA, "Foundry Street Denizen", 1, 1);
- }
+ }
/*
- I casted a Silence the Believers on a manifested card. It moved to the exile zone face-down.
- */
+ I casted a Silence the Believers on a manifested card. It moved to the exile zone face-down.
+ */
+
@Test
public void testCardGetsExiledFaceUp() {
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
@@ -224,7 +228,7 @@ public class ManifestTest extends CardTestPlayerBase {
// Gore Swine {2}{R}
// 4/1
addCard(Zone.LIBRARY, playerA, "Gore Swine");
-
+
// Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
@@ -240,12 +244,12 @@ public class ManifestTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion" , 1);
- assertExileCount("Gore Swine" , 1);
+ assertExileCount("Silvercoat Lion", 1);
+ assertExileCount("Gore Swine", 1);
// no facedown creature is on the battlefield
assertPermanentCount(playerA, "", 0);
-
- for (Card card :currentGame.getExile().getAllCards(currentGame)){
+
+ for (Card card : currentGame.getExile().getAllCards(currentGame)) {
if (card.getName().equals("Gore Swine")) {
Assert.assertTrue("Gore Swine may not be face down in exile", !card.isFaceDown(currentGame));
}
@@ -255,7 +259,6 @@ public class ManifestTest extends CardTestPlayerBase {
// Qarsi High Priest went to manifest Illusory Gains,
// but it made me choose a target for gains, then enchanted the card to that creature.
-
@Test
public void testManifestAura() {
@@ -282,15 +285,13 @@ public class ManifestTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Illusory Gains", 0);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
-
// a facedown creature is on the battlefield
assertPermanentCount(playerB, "", 1);
}
- // Check if a Megamorph card is manifested and truned by their megamorph ability
+ // Check if a Megamorph card is manifested and turned face up by their megamorph ability
// it gets the +1/+1 counter.
-
@Test
public void testManifestMegamorph() {
@@ -300,6 +301,8 @@ public class ManifestTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+ // Reach (This creature can block creatures with flying.)
+ // Megamorph {5}{G}
addCard(Zone.LIBRARY, playerB, "Aerie Bowmasters", 1);
addCard(Zone.LIBRARY, playerB, "Mountain", 1);
@@ -324,10 +327,11 @@ public class ManifestTest extends CardTestPlayerBase {
assertPowerToughness(playerB, "Aerie Bowmasters", 4, 5); // 3/4 and the +1/+1 counter from Megamorph
}
-
+
/**
- * When a Forest came manifested into play my Courser of Kruphix gained me a life.
- *
+ * When a Forest came manifested into play my Courser of Kruphix gained me a
+ * life.
+ *
*/
@Test
public void testManifestForest() {
@@ -349,7 +353,6 @@ public class ManifestTest extends CardTestPlayerBase {
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature");
addTarget(playerB, "Silvercoat Lion");
-
setStopAt(2, PhaseStep.END_TURN);
execute();
@@ -361,41 +364,40 @@ public class ManifestTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "", 1);
- }
-
- /**
+ }
+
+ /**
* Whisperwood Elemental - Its sacrifice ability doesn't work..
- *
+ *
*/
@Test
public void testWhisperwoodElemental() {
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// Seismic Rupture deals 2 damage to each creature without flying.
addCard(Zone.HAND, playerA, "Seismic Rupture", 1);
-
+
// At the beginning of your end step, manifest the top card of your library.
// Sacrifice Whisperwood Elemental: Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library."
addCard(Zone.BATTLEFIELD, playerB, "Whisperwood Elemental", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
-
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Seismic Rupture");
-
+
setStopAt(1, PhaseStep.END_TURN);
execute();
// no life gain
assertLife(playerA, 20);
assertLife(playerB, 20);
-
+
assertGraveyardCount(playerA, "Seismic Rupture", 1);
assertGraveyardCount(playerB, "Whisperwood Elemental", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 2);
assertPermanentCount(playerB, "", 2);
- }
+ }
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
index 4a7dc293243..037de63e93d 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
@@ -88,7 +88,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests Soulbond effect disabling whenever Soulbond creature changes its controller
+ * Tests Soulbond effect disabling whenever Soulbond creature changes its
+ * controller
*/
@Test
public void testChangeControllerForSoulbondCreature() {
@@ -115,7 +116,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests Soulbond effect disabling when paired creture changes its controller
+ * Tests Soulbond effect disabling when paired creture changes its
+ * controller
*/
@Test
public void testChangeControllerForAnotherCreature() {
@@ -141,8 +143,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests Soulbond effect disabling when Soulbond creature changes its controller and then returns back.
- * Effect should not be restored.
+ * Tests Soulbond effect disabling when Soulbond creature changes its
+ * controller and then returns back. Effect should not be restored.
*/
@Test
public void testChangeControllerAndGettingBack() {
@@ -166,7 +168,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests that stealing creature will allow to use Soulbond ability on controller's creature
+ * Tests that stealing creature will allow to use Soulbond ability on
+ * controller's creature
*/
@Test
public void testSoulbondWorksOnControllerSide() {
@@ -243,7 +246,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests that it is possible to animate land and pair it on next coming Soulbond creature
+ * Tests that it is possible to animate land and pair it on next coming
+ * Soulbond creature
*/
@Test
public void testPairOnAnimatedLand() {
@@ -263,7 +267,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests no effect whether land was animated after Soulbond creature has entered the battlefield
+ * Tests no effect whether land was animated after Soulbond creature has
+ * entered the battlefield
*/
@Test
public void testPairOnPostAnimatedLand() {
@@ -302,7 +307,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
}
/**
- * Tests that after loosing first pair it is possible to pair creature with another one
+ * Tests that after loosing first pair it is possible to pair creature with
+ * another one
*/
@Test
public void testRebondOnNextCreature() {
@@ -357,6 +363,8 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
public void testExileAndReturnBack() {
addCard(Zone.HAND, playerA, "Elite Vanguard");
addCard(Zone.HAND, playerA, "Cloudshift");
+ // Soulbond (You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them.)
+ // As long as Trusted Forcemage is paired with another creature, each of those creatures gets +1/+1.
addCard(Zone.BATTLEFIELD, playerA, "Trusted Forcemage");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
@@ -375,6 +383,6 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
Permanent trustedForcemange = getPermanent("Trusted Forcemage", playerA.getId());
Permanent eliteVanguard = getPermanent("Elite Vanguard", playerA.getId());
Assert.assertEquals(trustedForcemange.getPairedCard(), null);
- Assert.assertEquals(eliteVanguard.getPairedCard(),null);
+ Assert.assertEquals(eliteVanguard.getPairedCard(), null);
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index c815c8f94c4..9526cb9bef0 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -53,6 +53,7 @@ import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
+import mage.constants.AbilityType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
@@ -803,6 +804,9 @@ public class TestPlayer implements Player {
@Override
public boolean chooseUse(Outcome outcome, MessageToClient message, Ability source, Game game) {
+ if (message.getMessage().equals("Scry 1?")) {
+ return false;
+ }
if (!choices.isEmpty()) {
if (choices.get(0).equals("No")) {
choices.remove(0);
@@ -813,7 +817,7 @@ public class TestPlayer implements Player {
return true;
}
}
- return true;
+ return computerPlayer.chooseUse(outcome, message, source, game);
}
@Override
@@ -1822,6 +1826,16 @@ public class TestPlayer implements Player {
return computerPlayer.getMatchPlayer();
}
+ @Override
+ public AbilityType getJustActivatedType() {
+ return computerPlayer.getJustActivatedType();
+ }
+
+ @Override
+ public void setJustActivatedType(AbilityType justActivatedType) {
+ computerPlayer.setJustActivatedType(justActivatedType);
+ }
+
@Override
public void cleanUpOnMatchEnd() {
computerPlayer.cleanUpOnMatchEnd();
diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java
index 094550b16f6..eb3d7d70b2c 100644
--- a/Mage/src/mage/players/Player.java
+++ b/Mage/src/mage/players/Player.java
@@ -52,6 +52,7 @@ import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
+import mage.constants.AbilityType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PlayerAction;
@@ -192,6 +193,10 @@ public interface Player extends MageItem, Copyable {
boolean getPassedAllTurns();
+ AbilityType getJustActivatedType();
+
+ void setJustActivatedType(AbilityType abilityType);
+
boolean hasLost();
boolean hasWon();
diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java
index be796054a89..b121e9f269f 100644
--- a/Mage/src/mage/players/PlayerImpl.java
+++ b/Mage/src/mage/players/PlayerImpl.java
@@ -176,6 +176,7 @@ public abstract class PlayerImpl implements Player, Serializable {
* and abilities in the stack and will pass them as well.
*/
protected boolean passedAllTurns; // F9
+ protected AbilityType justActivatedType; // used to check if priority can be passed automatically
protected int turns;
protected int storedBookmark = -1;
@@ -317,6 +318,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.passedUntilStackResolved = player.passedUntilStackResolved;
this.dateLastAddedToStack = player.dateLastAddedToStack;
this.passedAllTurns = player.passedAllTurns;
+ this.justActivatedType = player.justActivatedType;
this.priorityTimeLeft = player.getPriorityTimeLeft();
this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving;
@@ -440,6 +442,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.skippedAtLeastOnce = false;
this.passedUntilStackResolved = false;
this.passedAllTurns = false;
+ this.justActivatedType = null;
this.canGainLife = true;
this.canLoseLife = true;
this.topCardRevealed = false;
@@ -1130,7 +1133,11 @@ public abstract class PlayerImpl implements Player, Serializable {
}
//if player has taken an action then reset all player passed flags
+ justActivatedType = null;
if (result) {
+ if (isHuman() && (ability.getAbilityType().equals(AbilityType.SPELL) || ability.getAbilityType().equals(AbilityType.ACTIVATED))) {
+ setJustActivatedType(ability.getAbilityType());
+ }
game.getPlayers().resetPassed();
}
return result;
@@ -3246,6 +3253,16 @@ public abstract class PlayerImpl implements Player, Serializable {
return passedUntilStackResolved;
}
+ @Override
+ public AbilityType getJustActivatedType() {
+ return justActivatedType;
+ }
+
+ @Override
+ public void setJustActivatedType(AbilityType justActivatedType) {
+ this.justActivatedType = justActivatedType;
+ }
+
@Override
public void revokePermissionToSeeHandCards() {
usersAllowedToSeeHandCards.clear();
diff --git a/Mage/src/mage/players/net/UserData.java b/Mage/src/mage/players/net/UserData.java
index cb405e34dff..0e6e4017334 100644
--- a/Mage/src/mage/players/net/UserData.java
+++ b/Mage/src/mage/players/net/UserData.java
@@ -19,10 +19,14 @@ public class UserData implements Serializable {
protected boolean askMoveToGraveOrder;
protected boolean manaPoolAutomatic;
protected boolean manaPoolAutomaticRestricted;
+ protected boolean passPriorityCast;
+ protected boolean passPriorityActivation;
+ protected boolean autoOrderTrigger;
public UserData(UserGroup userGroup, int avatarId, boolean showAbilityPickerForced,
boolean allowRequestShowHandCards, boolean confirmEmptyManaPool, UserSkipPrioritySteps userSkipPrioritySteps,
- String flagName, boolean askMoveToGraveOrder, boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted) {
+ String flagName, boolean askMoveToGraveOrder, boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted,
+ boolean passPriorityCast, boolean passPriorityActivation, boolean autoOrderTrigger) {
this.groupId = userGroup.getGroupId();
this.avatarId = avatarId;
this.showAbilityPickerForced = showAbilityPickerForced;
@@ -33,6 +37,9 @@ public class UserData implements Serializable {
this.askMoveToGraveOrder = askMoveToGraveOrder;
this.manaPoolAutomatic = manaPoolAutomatic;
this.manaPoolAutomaticRestricted = manaPoolAutomaticRestricted;
+ this.passPriorityCast = passPriorityCast;
+ this.passPriorityActivation = passPriorityActivation;
+ this.autoOrderTrigger = autoOrderTrigger;
}
public void update(UserData userData) {
@@ -46,10 +53,13 @@ public class UserData implements Serializable {
this.askMoveToGraveOrder = userData.askMoveToGraveOrder;
this.manaPoolAutomatic = userData.manaPoolAutomatic;
this.manaPoolAutomaticRestricted = userData.manaPoolAutomaticRestricted;
+ this.passPriorityCast = userData.passPriorityCast;
+ this.passPriorityActivation = userData.passPriorityActivation;
+ this.autoOrderTrigger = userData.autoOrderTrigger;
}
public static UserData getDefaultUserDataView() {
- return new UserData(UserGroup.DEFAULT, 0, false, false, true, null, "world.png", false, true, true);
+ return new UserData(UserGroup.DEFAULT, 0, false, false, true, null, "world.png", false, true, true, false, false, false);
}
public void setGroupId(int groupId) {
@@ -132,4 +142,28 @@ public class UserData implements Serializable {
this.manaPoolAutomaticRestricted = manaPoolAutomaticRestricted;
}
+ public boolean isPassPriorityCast() {
+ return passPriorityCast;
+ }
+
+ public void setPassPriorityCast(boolean passPriorityCast) {
+ this.passPriorityCast = passPriorityCast;
+ }
+
+ public boolean isPassPriorityActivation() {
+ return passPriorityActivation;
+ }
+
+ public void setPassPriorityActivation(boolean passPriorityActivation) {
+ this.passPriorityActivation = passPriorityActivation;
+ }
+
+ public boolean isAutoOrderTrigger() {
+ return autoOrderTrigger;
+ }
+
+ public void setAutoOrderTrigger(boolean autoOrderTrigger) {
+ this.autoOrderTrigger = autoOrderTrigger;
+ }
+
}
diff --git a/Mage/src/mage/watchers/common/SoulbondWatcher.java b/Mage/src/mage/watchers/common/SoulbondWatcher.java
index 4806133c740..ffe63d93f6b 100644
--- a/Mage/src/mage/watchers/common/SoulbondWatcher.java
+++ b/Mage/src/mage/watchers/common/SoulbondWatcher.java
@@ -109,7 +109,7 @@ public class SoulbondWatcher extends Watcher {
Cards cards = new CardsImpl();
cards.add(chosen);
controller.lookAtCards("Soulbond", cards, game);
- if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", null, game)) {
+ if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", SoulbondAbility.getInstance(), game)) {
chosen.setPairedCard(permanent.getId());
permanent.setPairedCard(chosen.getId());
if (!game.isSimulation()) {