* Fixed that permanents under non owner control sine they are on the battlefield were no exiled if the controller left the game (e.g. Captive Audience) (fixes #5593).

This commit is contained in:
LevelX2 2020-06-27 23:47:04 +02:00
parent 2c745109e4
commit d2d892a7cb
7 changed files with 308 additions and 235 deletions

View file

@ -1,5 +1,6 @@
package org.mage.test.multiplayer;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
@ -14,8 +15,6 @@ import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase;
import java.io.FileNotFoundException;
/**
* @author LevelX2
*/
@ -344,4 +343,54 @@ public class PlayerLeftGameRange1Test extends CardTestMultiPlayerBase {
Assert.assertTrue("Staff of player B could be used", staffPlayerB.isTapped());
}
/**
* Captive Audience doesn't work correctly in multiplayer #5593
*
* Currently, if the controller of Captive Audience leaves the game, Captive
* Audience returns to its owner instead of being exiled.
*/
@Test
public void TestCaptiveAudienceGoesToExile() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// Captive Audience enters the battlefield under the control of an opponent of your choice.
// At the beginning of your upkeep, choose one that hasn't been chosen
// Your life total becomes 4.
// Discard your hand.
// Each opponent creates five 2/2 black Zombie creature tokens.
addCard(Zone.HAND, playerA, "Captive Audience"); // Enchantment {5}{B}{R}
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);
setChoice(playerA, "PlayerA"); // Starting Player
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Captive Audience");
setChoice(playerA, "PlayerD");
setModeChoice(playerD, "1");
attack(5, playerA, "Silvercoat Lion", playerD);
attack(5, playerA, "Pillarfield Ox", playerD);
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
setStrictChooseMode(true);
execute();
assertAllCommandsUsed();
assertLife(playerA, 2);
Assert.assertFalse("Player D is no longer in the game", playerD.isInGame());
assertPermanentCount(playerD, 0);
assertPermanentCount(playerA, "Captive Audience", 0);
assertGraveyardCount(playerA, "Captive Audience", 0);
assertExileCount(playerA, "Captive Audience", 1);
}
}

View file

@ -1,5 +1,13 @@
package org.mage.test.serverside.base.impl;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.MageObject;
import mage.Mana;
import mage.ObjectColor;
@ -35,15 +43,6 @@ import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestAPI;
import org.mage.test.serverside.base.MageTestPlayerBase;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* API for test initialization and asserting the test results.
*
@ -275,7 +274,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
}
Assert.assertFalse("Wrong stop command on " + this.stopOnTurn + " / " + this.stopAtStep + " (" + this.stopAtStep.getIndex() + ")"
+ " (found actions after stop on " + maxTurn + " / " + maxPhase + ")",
+ " (found actions after stop on " + maxTurn + " / " + maxPhase + ")",
(maxTurn > this.stopOnTurn) || (maxTurn == this.stopOnTurn && maxPhase > this.stopAtStep.getIndex()));
for (Player player : currentGame.getPlayers().values()) {
@ -508,8 +507,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add a card to specified zone of specified player.
*
* @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param cardName Card name in string format.
*/
@Override
@ -521,10 +520,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add any amount of cards to specified zone of specified player.
*
* @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param cardName Card name in string format.
* @param count Amount of cards to be added.
* @param count Amount of cards to be added.
*/
@Override
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) {
@ -535,13 +534,13 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add any amount of cards to specified zone of specified player.
*
* @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param cardName Card name in string format.
* @param count Amount of cards to be added.
* @param tapped In case gameZone is Battlefield, determines whether
* permanent should be tapped. In case gameZone is other than Battlefield,
* {@link IllegalArgumentException} is thrown
* @param count Amount of cards to be added.
* @param tapped In case gameZone is Battlefield, determines whether
* permanent should be tapped. In case gameZone is other than Battlefield,
* {@link IllegalArgumentException} is thrown
*/
@Override
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) {
@ -622,7 +621,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Set player's initial life count.
*
* @param player {@link Player} to set life count for.
* @param life Life count to set.
* @param life Life count to set.
*/
@Override
public void setLife(TestPlayer player, int life) {
@ -699,7 +698,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert player's life count after test execution.
*
* @param player {@link Player} to get life for comparison.
* @param life Expected player's life to compare with.
* @param life Expected player's life to compare with.
*/
@Override
public void assertLife(Player player, int life) throws AssertionError {
@ -716,14 +715,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* params 3b. all: there is at least one creature with the cardName with the
* different p\t params
*
* @param player {@link Player} to get creatures for comparison.
* @param cardName Card name to compare with.
* @param power Expected power to compare with.
* @param player {@link Player} to get creatures for comparison.
* @param cardName Card name to compare with.
* @param power Expected power to compare with.
* @param toughness Expected toughness to compare with.
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you
* want "at least one creature with given name should have specified p\t"
* Use ALL, if you want "all creature with gived name should have specified
* p\t"
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you
* want "at least one creature with given name should have specified p\t"
* Use ALL, if you want "all creature with gived name should have specified
* p\t"
*/
@Override
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
@ -813,8 +812,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param cardName
* @param ability
* @param mustHave true if creature should contain ability, false if it
* should NOT contain it instead
* @param count number of permanents with that ability
* should NOT contain it instead
* @param count number of permanents with that ability
* @throws AssertionError
*/
public void assertAbility(Player player, String cardName, Ability ability, boolean mustHave, int count) throws AssertionError {
@ -847,7 +846,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert permanent count under player's control.
*
* @param player {@link Player} which permanents should be counted.
* @param count Expected count.
* @param count Expected count.
*/
@Override
public void assertPermanentCount(Player player, int count) throws AssertionError {
@ -863,9 +862,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert permanent count under player's control.
*
* @param player {@link Player} which permanents should be counted.
* @param player {@link Player} which permanents should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
@Override
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
@ -915,8 +914,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a permanent
*
* @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterCount(String cardName, CounterType type, int count) throws AssertionError {
this.assertCounterCount(null, cardName, type, count);
@ -939,8 +938,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a card in exile
*
* @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -963,8 +962,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a player
*
* @param player The player whos counters should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError {
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ':' + type + ')', count, player.getCounters().getCount(type));
@ -974,7 +973,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type or not
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param type A type to test for
* @param mustHave true if creature should have type, false if it should not
*/
public void assertType(String cardName, CardType type, boolean mustHave) throws AssertionError {
@ -999,8 +998,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param subType a subtype to test for
* @param type A type to test for
* @param subType a subtype to test for
*/
public void assertType(String cardName, CardType type, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1015,7 +1014,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified type
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param type A type to test for
*/
public void assertNotType(String cardName, CardType type) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1027,7 +1026,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified subtype
*
* @param cardName Name of the permanent that should be checked.
* @param subType a subtype to test for
* @param subType a subtype to test for
*/
public void assertNotSubtype(String cardName, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1040,10 +1039,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert permanent color
*
* @param player player to check
* @param cardName card name on battlefield from player
* @param player player to check
* @param cardName card name on battlefield from player
* @param searchColors colors list with searchable values
* @param mustHave must or not must have that colors
* @param mustHave must or not must have that colors
*/
public void assertColor(Player player, String cardName, ObjectColor searchColors, boolean mustHave) {
//Assert.assertNotEquals("", cardName);
@ -1078,7 +1077,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is tapped or not
*
* @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not
* @param tapped Whether the permanent is tapped or not
*/
public void assertTapped(String cardName, boolean tapped) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1105,8 +1104,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether X permanents of the same name are tapped or not.
*
* @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not
* @param count The amount of this permanents that should be tapped
* @param tapped Whether the permanent is tapped or not
* @param count The amount of this permanents that should be tapped
*/
public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1128,7 +1127,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert whether a permanent is attacking or not
*
* @param cardName Name of the permanent that should be checked.
* @param cardName Name of the permanent that should be checked.
* @param attacking Whether the permanent is attacking or not
*/
public void assertAttacking(String cardName, boolean attacking) throws AssertionError {
@ -1150,7 +1149,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's hand.
*
* @param player {@link Player} who's hand should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertHandCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getHand().size();
@ -1160,9 +1159,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's hand.
*
* @param player {@link Player} who's hand should be counted.
* @param player {@link Player} who's hand should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertHandCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1210,7 +1209,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's graveyard.
*
* @param player {@link Player} who's graveyard should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertGraveyardCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getGraveyard().size();
@ -1221,7 +1220,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in exile.
*
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertExileCount(String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1259,9 +1258,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's exile.
*
* @param owner {@link Player} who's exile should be counted.
* @param owner {@link Player} who's exile should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertExileCount(Player owner, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1280,9 +1279,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's graveyard.
*
* @param player {@link Player} who's graveyard should be counted.
* @param player {@link Player} who's graveyard should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertGraveyardCount(Player player, String cardName, int count) throws AssertionError {
assertAliaseSupportInActivateCommand(cardName, true);
@ -1301,7 +1300,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert library card count.
*
* @param player {@link Player} who's library should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertLibraryCount(Player player, int count) throws AssertionError {
List<Card> libraryList = player.getLibrary().getCards(currentGame);
@ -1312,9 +1311,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert specific card count in player's library.
*
* @param player {@link Player} who's library should be counted.
* @param player {@link Player} who's library should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertLibraryCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1353,8 +1352,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
/**
* Raise error on any unused commands, choices or targets
* If you want to test that ability can't be activated then use call checkPlayableAbility()
* Raise error on any unused commands, choices or targets If you want to
* test that ability can't be activated then use call checkPlayableAbility()
*
* @throws AssertionError
*/
@ -1501,8 +1500,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param player
* @param cardName
* @param targetName for modes you can add "mode=3" before target name,
* multiple targets can be seperated by ^, not target marks as
* TestPlayer.NO_TARGET
* multiple targets can be seperated by ^, not target marks as
* TestPlayer.NO_TARGET
*/
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
//Assert.assertNotEquals("", cardName);
@ -1525,8 +1524,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param cardName
* @param targetName for modal spells add the mode to the name e.g.
* "mode=2SilvercoatLion^mode3=PillarfieldOx"
* @param targetName for modal spells add the mode to the name e.g.
* "mode=2SilvercoatLion^mode3=PillarfieldOx"
* @param spellOnStack
*/
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack) {
@ -1613,7 +1612,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param ability
* @param targetName use NO_TARGET if there is no target to set
* @param targetName use NO_TARGET if there is no target to set
* @param spellOnStack
*/
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) {
@ -1626,8 +1625,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param ability
* @param targetName if not target has to be defined use the constant
* NO_TARGET
* @param targetName if not target has to be defined use the constant
* NO_TARGET
* @param spellOnStack
* @param clause
*/
@ -1691,9 +1690,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
/**
* For use choices set "Yes" or "No" the the choice string. For X values set
* "X=[xValue]" example: for X=3 set choice string to "X=3".
* <br>For ColorChoice use "Red", "Green", "Blue", "Black" or "White"
* For use choices set "Yes" or "No" the the choice string.<br>
* For X values set "X=[xValue]" example: for X=3 set choice string to
* "X=3".<br>
* For ColorChoice use "Red", "Green", "Blue", "Black" or "White"<br>
* use command setModeChoice if you have to set a mode from modal
* ability<br>
*
* @param player
* @param choice
@ -1713,10 +1715,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
*
* @param player
* @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to
* set multiple modes call the command multiple times). If a spell mode can
* be used only once like Demonic Pact, the value has to be set to the
* number of the remaining modes (e.g. if only 2 are left the number need to
* be 1 or 2).
* set multiple modes call the command multiple times). If a spell mode can
* be used only once like Demonic Pact, the value has to be set to the
* number of the remaining modes (e.g. if only 2 are left the number need to
* be 1 or 2).
*/
public void setModeChoice(TestPlayer player, String choice) {
player.addModeChoice(choice);
@ -1727,12 +1729,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
*
* @param player
* @param target you can add multiple targets by separating them by the "^"
* character e.g. "creatureName1^creatureName2" you can qualify the target
* additional by setcode e.g. "creatureName-M15" you can add [no copy] to
* the end of the target name to prohibit targets that are copied you can
* add [only copy] to the end of the target name to allow only targets that
* are copies. For modal spells use a prefix with the mode number:
* mode=1Lightning Bolt^mode=2Silvercoat Lion
* character e.g. "creatureName1^creatureName2" you can qualify the target
* additional by setcode e.g. "creatureName-M15" you can add [no copy] to
* the end of the target name to prohibit targets that are copied you can
* add [only copy] to the end of the target name to allow only targets that
* are copies. For modal spells use a prefix with the mode number:
* mode=1Lightning Bolt^mode=2Silvercoat Lion
*/
// TODO: mode options doesn't work here (see BrutalExpulsionTest)
public void addTarget(TestPlayer player, String target) {
@ -1764,7 +1766,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* @param player
* @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop
* "up two xxx" selection
* "up two xxx" selection
* @param amount
*/
public void addTargetAmount(TestPlayer player, String target, int amount) {