forked from External/mage
* Sylvan Library - Fixed that a player that controlled a Sylvan Library from another player was not forced to play life for cards he kept from Sylvan Library's triggered ability (fixes #1307).
This commit is contained in:
parent
3f771feb52
commit
d145885d2d
2 changed files with 73 additions and 26 deletions
|
|
@ -27,7 +27,9 @@
|
|||
*/
|
||||
package mage.sets.fifthedition;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
|
|
@ -64,7 +66,8 @@ public class SylvanLibrary extends CardImpl {
|
|||
this.expansionSetCode = "5ED";
|
||||
|
||||
// At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library.
|
||||
this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true), new CardsDrawnThisTurnWatcher());
|
||||
this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true),
|
||||
new CardsDrawnThisTurnWatcher());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -99,11 +102,11 @@ class SylvanLibraryEffect extends OneShotEffect {
|
|||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
controller.drawCards(2, game);
|
||||
CardsDrawnThisTurnWatcher watcher = (CardsDrawnThisTurnWatcher) game.getState().getWatchers().get("CardsDrawnThisTurnWatcher", source.getControllerId());
|
||||
CardsDrawnThisTurnWatcher watcher = (CardsDrawnThisTurnWatcher) game.getState().getWatchers().get("CardsDrawnThisTurnWatcher");
|
||||
if (watcher != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
for (UUID cardId : controller.getHand()) {
|
||||
if (watcher.getCardsDrawnThisTurn().contains(cardId)) {
|
||||
if (watcher.getCardsDrawnThisTurn(controller.getId()).contains(cardId)) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
|
|
@ -161,26 +164,31 @@ class SylvanLibraryEffect extends OneShotEffect {
|
|||
|
||||
class CardsDrawnThisTurnWatcher extends Watcher {
|
||||
|
||||
private final Set<UUID> cardsDrawnThisTurn = new HashSet<UUID>();
|
||||
private final Map<UUID, Set<UUID>> cardsDrawnThisTurn = new HashMap<>();
|
||||
|
||||
public CardsDrawnThisTurnWatcher() {
|
||||
super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER);
|
||||
super("CardsDrawnThisTurnWatcher", WatcherScope.GAME);
|
||||
}
|
||||
|
||||
public CardsDrawnThisTurnWatcher(final CardsDrawnThisTurnWatcher watcher) {
|
||||
super(watcher);
|
||||
this.cardsDrawnThisTurn.addAll(watcher.cardsDrawnThisTurn);
|
||||
this.cardsDrawnThisTurn.putAll(watcher.cardsDrawnThisTurn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.DREW_CARD && event.getPlayerId().equals(this.getControllerId())) {
|
||||
cardsDrawnThisTurn.add(event.getTargetId());
|
||||
if (event.getType() == GameEvent.EventType.DREW_CARD) {
|
||||
if (!cardsDrawnThisTurn.containsKey(event.getPlayerId())) {
|
||||
Set<UUID> cardsDrawn = new LinkedHashSet<>();
|
||||
cardsDrawnThisTurn.put(event.getPlayerId(), cardsDrawn);
|
||||
}
|
||||
Set<UUID> cardsDrawn = cardsDrawnThisTurn.get(event.getPlayerId());
|
||||
cardsDrawn.add(event.getTargetId());
|
||||
}
|
||||
}
|
||||
|
||||
public Set<UUID> getCardsDrawnThisTurn() {
|
||||
return cardsDrawnThisTurn;
|
||||
public Set<UUID> getCardsDrawnThisTurn(UUID playerId) {
|
||||
return cardsDrawnThisTurn.get(playerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -195,7 +203,6 @@ class CardsDrawnThisTurnWatcher extends Watcher {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class CardIdPredicate implements Predicate<MageObject> {
|
||||
|
||||
private final Cards cardsId;
|
||||
|
|
@ -206,10 +213,8 @@ class CardIdPredicate implements Predicate<MageObject> {
|
|||
|
||||
@Override
|
||||
public boolean apply(MageObject input, Game game) {
|
||||
for(UUID uuid : cardsId)
|
||||
{
|
||||
if(uuid.equals(input.getId()))
|
||||
{
|
||||
for (UUID uuid : cardsId) {
|
||||
if (uuid.equals(input.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Tests the effect:
|
||||
* - Exile target creature you control, then return that card to the battlefield under your control
|
||||
* Tests the effect: - Exile target creature you control, then return that card
|
||||
* to the battlefield under your control
|
||||
*
|
||||
* This effect grants you permanent control over the returned creature.
|
||||
* So you mail steal opponent's creature with "Act of Treason" and then use this effect for permanent control effect.
|
||||
* This effect grants you permanent control over the returned creature. So you
|
||||
* mail steal opponent's creature with "Act of Treason" and then use this effect
|
||||
* for permanent control effect.
|
||||
*
|
||||
* @author noxx
|
||||
*/
|
||||
|
|
@ -67,7 +68,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
|
|||
Assert.assertTrue("player A should play with top card revealed", playerA.isTopCardRevealed());
|
||||
Assert.assertFalse("player B should play NOT with top card revealed", playerB.isTopCardRevealed());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testVillainousWealthExilesBoost() {
|
||||
// Villainous Wealth {X}{B}{G}{U}
|
||||
|
|
@ -76,14 +77,14 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
|
|||
// their mana costs.
|
||||
addCard(Zone.HAND, playerA, "Villainous Wealth");
|
||||
addCard(Zone.HAND, playerA, "Master of Pearls");
|
||||
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// Secret Plans {G}{U}
|
||||
// Face-down creatures you control get +0/+1.
|
||||
// Whenever a permanent you control is turned face up, draw a card.
|
||||
// Whenever a permanent you control is turned face up, draw a card.
|
||||
addCard(Zone.LIBRARY, playerB, "Secret Plans");
|
||||
skipInitShuffling(); // to keep this card on top of library
|
||||
|
||||
|
|
@ -101,9 +102,50 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
|
|||
assertExileCount(playerB, 2);
|
||||
assertExileCount("Secret Plans", 0);
|
||||
assertPermanentCount(playerA, "Secret Plans", 1);
|
||||
|
||||
|
||||
assertPermanentCount(playerA, "", 1);
|
||||
assertPowerToughness(playerA, "", 2, 3);
|
||||
}
|
||||
assertPowerToughness(playerA, "", 2, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* My opponent cast Villainous Wealth and took control of my Sylvan Library.
|
||||
* On his next turn, when Sylvan Library's trigger resolved, he kept the two
|
||||
* extra cards without paying life.
|
||||
*/
|
||||
@Test
|
||||
public void testVillainousWealthExilesSylvanLibrary() {
|
||||
// Villainous Wealth {X}{B}{G}{U}
|
||||
// Target opponent exiles the top X cards of his or her library. You may cast any number
|
||||
// of nonland cards with converted mana cost X or less from among them without paying
|
||||
// their mana costs.
|
||||
addCard(Zone.HAND, playerA, "Villainous Wealth");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
|
||||
// At the beginning of your draw step, you may draw two additional cards.
|
||||
// If you do, choose two cards in your hand drawn this turn.
|
||||
// For each of those cards, pay 4 life or put the card on top of your library.
|
||||
addCard(Zone.LIBRARY, playerB, "Sylvan Library");
|
||||
skipInitShuffling(); // to keep this card on top of library
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
|
||||
setChoice(playerA, "X=3");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sylvan Library");
|
||||
|
||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Villainous Wealth", 1);
|
||||
assertExileCount(playerB, 2);
|
||||
assertExileCount("Sylvan Library", 0);
|
||||
assertPermanentCount(playerA, "Sylvan Library", 1);
|
||||
|
||||
assertHandCount(playerB, 1);
|
||||
assertHandCount(playerA, 3);
|
||||
assertLife(playerA, 12);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue