mirror of
https://github.com/magefree/mage.git
synced 2025-12-30 07:22:03 -08:00
[CMR] implemented Opposition Agent and other changes:
* You may play cards and you may spend mana of any color - refactored cards to use same code; * Library search event allows to change searching controller (gives full game control for another player); * Library searched event allows to remove founded cards from result; * Improved library searching effects with Panglacial Wurm's effects; * Little changes to test framework;
This commit is contained in:
parent
13fa98ec44
commit
c2a636e2b2
22 changed files with 806 additions and 721 deletions
|
|
@ -120,6 +120,10 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
|
|||
// You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.
|
||||
addCard(Zone.HAND, playerA, "Hostage Taker"); // {2}{U}{B}
|
||||
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}.");
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {U}.");
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}.");
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}.");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,254 @@
|
|||
package org.mage.test.cards.control;
|
||||
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.replacement.YouControlYourOpponentsWhileSearchingReplacementEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class TakeControlWhileSearchingLibraryTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_SimpleSearchingLibrary_Normal() {
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
|
||||
addCard(Zone.LIBRARY, playerB, "Kitesail Corsair", 1);
|
||||
//
|
||||
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
|
||||
addCard(Zone.HAND, playerA, "Buried Alive", 1); // {2}{B}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
|
||||
// before
|
||||
checkGraveyardCount("before a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("before b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
// search as normal
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 3);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
addTarget(playerA, "Balduvian Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// after
|
||||
checkGraveyardCount("after a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
checkGraveyardCount("after b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_SimpleSearchingLibrary_TakeControl() {
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
|
||||
addCard(Zone.LIBRARY, playerB, "Kitesail Corsair", 1);
|
||||
//
|
||||
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
|
||||
addCard(Zone.HAND, playerA, "Buried Alive", 1); // {2}{B}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
//
|
||||
// You control your opponents while they’re searching their libraries.
|
||||
addCustomCardWithAbility("control", playerB, new SimpleStaticAbility(
|
||||
new YouControlYourOpponentsWhileSearchingReplacementEffect())
|
||||
);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
|
||||
// before
|
||||
checkGraveyardCount("before a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("before b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
// search under control of B
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 3);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
setChoice(playerB, "Yes"); // continue
|
||||
addTarget(playerB, "Balduvian Bears"); // player B must take control for searching
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// after
|
||||
checkGraveyardCount("after a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
checkGraveyardCount("after b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
// check that control returned
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
|
||||
addTarget(playerA, playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CastCardWhileSearchingLibrary_Normal() {
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
|
||||
addCard(Zone.LIBRARY, playerB, "Kitesail Corsair", 1);
|
||||
//
|
||||
// While you're searching your library, you may cast Panglacial Wurm from your library.
|
||||
addCard(Zone.LIBRARY, playerA, "Panglacial Wurm", 1); // {5}{G}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Panglacial Wurm", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
|
||||
//
|
||||
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
|
||||
addCard(Zone.HAND, playerA, "Buried Alive", 1); // {2}{B}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
//
|
||||
|
||||
// before
|
||||
checkGraveyardCount("before a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("before b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
// search as normal and cast
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 3);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
setChoice(playerA, "Yes"); // yes, try to cast a creature card from lib
|
||||
setChoice(playerA, "Panglacial Wurm"); // try to cast
|
||||
addTarget(playerA, "Balduvian Bears"); // choice for searching
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// after
|
||||
checkGraveyardCount("after a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
checkGraveyardCount("after b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
checkPermanentCount("must cast Panglacial Wurm", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Panglacial Wurm", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // unsupported by unit tests, see test_UnderControlMustUseTestCommandsCorrectrly
|
||||
public void test_CastCardWhileSearchingLibrary_TakeControl() {
|
||||
/*
|
||||
[test control manually]
|
||||
// use case: login by p1 and p2 clients, cast Buried Alive -> control under p2 -> try cast Panglacial Wurm and search for Balduvian Bears
|
||||
library:p1:Balduvian Bears:1
|
||||
library:p2:Kitesail Corsair:1
|
||||
library:p1:Panglacial Wurm:1
|
||||
battlefield:p1:Panglacial Wurm:1
|
||||
battlefield:p1:Forest:7
|
||||
hand:p1:Buried Alive:1
|
||||
battlefield:p1:Swamp:3
|
||||
battlefield:p2:Opposition Agent:1
|
||||
*/
|
||||
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
|
||||
addCard(Zone.LIBRARY, playerB, "Kitesail Corsair", 1);
|
||||
//
|
||||
// While you're searching your library, you may cast Panglacial Wurm from your library.
|
||||
addCard(Zone.LIBRARY, playerA, "Panglacial Wurm", 1); // {5}{G}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Panglacial Wurm", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
|
||||
//
|
||||
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
|
||||
addCard(Zone.HAND, playerA, "Buried Alive", 1); // {2}{B}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
|
||||
// before
|
||||
checkGraveyardCount("before a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("before b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
|
||||
// search under control of B and cast under B too
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 3);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
setChoice(playerB, "Yes"); // continue
|
||||
setChoice(playerB, "Yes"); // yes, try to cast a creature card from lib
|
||||
setChoice(playerB, "Panglacial Wurm"); // try to cast
|
||||
addTarget(playerB, "Balduvian Bears"); // choice for searching
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// after
|
||||
checkGraveyardCount("after a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
checkGraveyardCount("after b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Kitesail Corsair", 0);
|
||||
checkPermanentCount("must cast Panglacial Wurm", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Panglacial Wurm", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// TODO: current "take player under control" implemented in GameController and HumanPlayer,
|
||||
// not "game part" - so tests and AI ignore it and must be tested manually
|
||||
// see another problems with control in HumanPlayer.priority(Game game) and https://github.com/magefree/mage/issues/2088
|
||||
public void test_UnderControlMustUseTestCommandsCorrectrly() {
|
||||
// {4}, {T}, Sacrifice Mindslaver: You control target player during that player's next turn.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mindslaver", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
//
|
||||
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||
|
||||
// activate and take control
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}, {T}");
|
||||
addTarget(playerA, playerB);
|
||||
|
||||
// check control
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
|
||||
addTarget(playerA, playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_OppositionAgent() {
|
||||
// You control your opponents while they’re searching their libraries.
|
||||
// While an opponent is searching their library, they exile each card they find. You may play those cards
|
||||
// for as long as they remain exiled, and you may spend mana as though it were mana of any color to cast them.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Opposition Agent", 1);
|
||||
//
|
||||
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
|
||||
addCard(Zone.HAND, playerA, "Buried Alive", 1); // {2}{B}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
//
|
||||
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1); // {1}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); // B can cast green bear for red mana
|
||||
|
||||
// before
|
||||
checkPermanentCount("before a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkPermanentCount("before b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Balduvian Bears", 0);
|
||||
|
||||
// start searching under B (bears must go to exile instead graveyard)
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
setChoice(playerB, "Yes"); // continue after new control
|
||||
addTarget(playerB, "Balduvian Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkGraveyardCount("after grave a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("after grave b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Balduvian Bears", 0);
|
||||
checkExileCount("after exile a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
checkExileCount("after exile b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Balduvian Bears", 0);
|
||||
|
||||
// B can cast green bear for red mana
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Balduvian Bears");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerB, "Balduvian Bears", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1302,7 +1302,7 @@ public class TestPlayer implements Player {
|
|||
printStart("Permanents of " + player.getName());
|
||||
printPermanents(game, game.getBattlefield().getAllActivePermanents(player.getId()));
|
||||
printEnd();
|
||||
Assert.fail(action.getActionName() + " - permanent " + permanentName + " must exists in " + count + " instances");
|
||||
Assert.fail(action.getActionName() + " - permanent " + permanentName + " must exists in " + count + " instances, but founded " + foundedCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2526,7 +2526,8 @@ public class TestPlayer implements Player {
|
|||
|
||||
this.chooseStrictModeFailed("choice", game, getInfo(source, game)
|
||||
+ "\nMessage: " + message
|
||||
+ "\nChoices: " + (trueText != null ? trueText : "Yes") + " - " + (falseText != null ? falseText : "No"));
|
||||
+ "\nChoices: " + (trueText != null ? trueText : "Yes") + " - " + (falseText != null ? falseText : "No")
|
||||
+ ((trueText != null || falseText != null) ? "\nUse Yes/No in unit tests for text choices." : ""));
|
||||
return computerPlayer.chooseUse(outcome, message, secondMessage, trueText, falseText, source, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue