mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
tests: added additional tests for Dryad Militant card and Madness abilities, added docs;
This commit is contained in:
parent
8c0ed8a749
commit
d28b9e6d05
6 changed files with 283 additions and 43 deletions
|
|
@ -45,12 +45,14 @@ public final class ChandraAblaze extends CardImpl {
|
||||||
ability.addEffect(new ChandraAblazeEffect2());
|
ability.addEffect(new ChandraAblazeEffect2());
|
||||||
ability.addTarget(new TargetAnyTarget());
|
ability.addTarget(new TargetAnyTarget());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// -2: Each player discards their hand, then draws three cards.
|
// -2: Each player discards their hand, then draws three cards.
|
||||||
ability = new LoyaltyAbility(new DiscardHandAllEffect(), -2);
|
ability = new LoyaltyAbility(new DiscardHandAllEffect(), -2);
|
||||||
Effect effect = new DrawCardAllEffect(3);
|
Effect effect = new DrawCardAllEffect(3);
|
||||||
effect.setText(", then draws three cards");
|
effect.setText(", then draws three cards");
|
||||||
ability.addEffect(effect);
|
ability.addEffect(effect);
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// -7: Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs.
|
// -7: Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs.
|
||||||
ability = new LoyaltyAbility(new ChandraAblazeEffect5(), -7);
|
ability = new LoyaltyAbility(new ChandraAblazeEffect5(), -7);
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
@ -84,6 +86,11 @@ class ChandraAblazeEffect1 extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
|
// If you activate Chandra Ablaze’s first ability, you don’t discard a card until the ability resolves.
|
||||||
|
// You may activate the ability even if your hand is empty. You choose a target as you activate the ability
|
||||||
|
// even if you have no red cards in hand at that time.
|
||||||
|
// (2009-10-01)
|
||||||
|
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
TargetDiscard target = new TargetDiscard(player.getId());
|
TargetDiscard target = new TargetDiscard(player.getId());
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class UnboundFlourishingTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_OnCastInstantOrSourcery_MustCopy() {
|
public void test_OnCastInstantOrSorcery_MustCopy() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Unbound Flourishing", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Unbound Flourishing", 1);
|
||||||
//
|
//
|
||||||
// Banefire deals X damage to any target.
|
// Banefire deals X damage to any target.
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,35 @@
|
||||||
|
|
||||||
package org.mage.test.cards.replacement;
|
package org.mage.test.cards.replacement;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
|
import mage.watchers.common.CardsExiledThisTurnWatcher;
|
||||||
|
import mage.watchers.common.CardsPutIntoGraveyardWatcher;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dryad Militant
|
* Dryad Militant oracle rules:
|
||||||
* Creature - Dryad Soldier 1/1 {G/W}
|
* <p>
|
||||||
* If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
* If an instant or sorcery spell destroys Dryad Militant directly (like Murder does), that instant or sorcery
|
||||||
|
* card will be put into its owner’s graveyard. However, if an instant or sorcery card deals lethal damage to
|
||||||
|
* Dryad Militant, Dryad Militant will remain on the battlefield until the next time state-based actions are
|
||||||
|
* checked, which is after the instant or sorcery finishes resolving.
|
||||||
|
* The instant or sorcery will be exiled.
|
||||||
|
* (2012-10-01) - supported, has tests
|
||||||
|
* <p>
|
||||||
|
* If an instant or sorcery card is discarded while Dryad Militant is on the battlefield, abilities that
|
||||||
|
* function when a card is discarded (such as madness) still work, even though that card never reaches a
|
||||||
|
* graveyard. In addition, spells or abilities that check the characteristics of a discarded card (such as
|
||||||
|
* Chandra Ablaze’s first ability) can find that card in exile.
|
||||||
|
* (2012-10-01) - supported, has tests
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2, JayDi85
|
||||||
*/
|
*/
|
||||||
public class DryadMilitantTest extends CardTestPlayerBase {
|
public class DryadMilitantTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
|
@ -19,60 +37,251 @@ public class DryadMilitantTest extends CardTestPlayerBase {
|
||||||
* Tests that an instant or sorcery card is moved to exile
|
* Tests that an instant or sorcery card is moved to exile
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNormalCase() {
|
public void test_OnResolve_MustWork() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
// If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
||||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
||||||
|
//
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerB, 17);
|
assertLife(playerB, 17);
|
||||||
assertExileCount("Lightning Bolt", 1);
|
assertExileCount("Lightning Bolt", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if Dryad Militant dies by damage spell, the
|
* Tests if Dryad Militant dies by damage spell, the
|
||||||
* spell gets exiled
|
* spell gets exiled (see oracle rules)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDiesByDamage() {
|
public void test_DiesByDamage_MustWork() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
// If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
||||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
||||||
|
//
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Dryad Militant");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Dryad Militant");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerB, 20);
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
assertExileCount("Lightning Bolt", 1);
|
assertExileCount("Lightning Bolt", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if Dryad Militant dies by destroy spell, the
|
* Tests if Dryad Militant dies by destroy spell, the
|
||||||
* spell don't get exiled
|
* spell don't get exiled (see oracle rules)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDiesByDestroy() {
|
public void test_DiesByDestroy_MustNotWork() {
|
||||||
|
// If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
||||||
|
//
|
||||||
|
// Destroy target creature. It can't be regenerated.
|
||||||
|
addCard(Zone.HAND, playerA, "Terminate"); // {B}{R}
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
addCard(Zone.HAND, playerA, "Terminate");
|
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
|
||||||
|
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Terminate", "Dryad Militant");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Terminate", "Dryad Militant");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerB, 20);
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
assertHandCount(playerA, "Terminate", 0);
|
assertHandCount(playerA, "Terminate", 0);
|
||||||
assertGraveyardCount(playerA, "Terminate", 1);
|
assertGraveyardCount(playerA, "Terminate", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareGraveyardAndExileWatchers() {
|
||||||
|
currentGame.getState().addWatcher(new CardsPutIntoGraveyardWatcher());
|
||||||
|
currentGame.getState().addWatcher(new CardsExiledThisTurnWatcher());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertCardsList(String info, Collection<Card> currentList, Collection<String> needList) {
|
||||||
|
String current = currentList.stream().map(Card::getName).sorted().collect(Collectors.joining("; "));
|
||||||
|
String need = needList.stream().sorted().collect(Collectors.joining("; "));
|
||||||
|
Assert.assertEquals(info, need, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertReachesGraveyard(Collection<String> needList) {
|
||||||
|
CardsPutIntoGraveyardWatcher graveyardWatcher = currentGame.getState().getWatcher(CardsPutIntoGraveyardWatcher.class);
|
||||||
|
assertCardsList(
|
||||||
|
"graveyard must reaches " + needList.size() + " cards this turn",
|
||||||
|
graveyardWatcher.getCardsPutIntoGraveyardFromAnywhere(currentGame),
|
||||||
|
needList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertReachesExile(Collection<String> needList) {
|
||||||
|
CardsExiledThisTurnWatcher exileWatcher = currentGame.getState().getWatcher(CardsExiledThisTurnWatcher.class);
|
||||||
|
assertCardsList(
|
||||||
|
"exile must reaches " + needList.size() + " cards this turn",
|
||||||
|
exileWatcher.getCardsExiledThisTurn(currentGame),
|
||||||
|
needList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_MadnessCreature_OnDiscard() {
|
||||||
|
prepareGraveyardAndExileWatchers();
|
||||||
|
|
||||||
|
// Madness {B}{B} (If you discard this card, discard it into exile. When you do, cast it for its madness cost
|
||||||
|
// or put it into your graveyard.)
|
||||||
|
addCard(Zone.HAND, playerA, "Gorgon Recluse"); // {3}{B}{B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||||
|
//
|
||||||
|
// Target player discards a card.
|
||||||
|
addCard(Zone.HAND, playerA, "Raven's Crime"); // {B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
|
|
||||||
|
// discard
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerA);
|
||||||
|
setChoice(playerA, true); // use madness
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
// raven on cast go to grave
|
||||||
|
// gorgon on madness go to exile and cast instead grave
|
||||||
|
assertReachesGraveyard(Arrays.asList("Raven's Crime"));
|
||||||
|
assertReachesExile(Arrays.asList("Gorgon Recluse")); // was cast from exile
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_MadnessSorcery_OnDiscard() {
|
||||||
|
prepareGraveyardAndExileWatchers();
|
||||||
|
|
||||||
|
// Alchemist’s Greeting deals 4 damage to target creature.
|
||||||
|
// Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness
|
||||||
|
// cost or put it into your graveyard.)
|
||||||
|
addCard(Zone.HAND, playerA, "Alchemist's Greeting"); // {4}{R}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
//
|
||||||
|
// Target player discards a card.
|
||||||
|
addCard(Zone.HAND, playerA, "Raven's Crime"); // {B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
|
|
||||||
|
// discard
|
||||||
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 1);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerA);
|
||||||
|
setChoice(playerA, true); // use madness
|
||||||
|
addTarget(playerA, "Grizzly Bears"); // target of madness card
|
||||||
|
|
||||||
|
showGraveyard("after grave", 1, PhaseStep.END_TURN, playerA);
|
||||||
|
showExile("after exile", 1, PhaseStep.END_TURN, playerA);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertGraveyardCount(playerA, "Alchemist's Greeting", 1); // go to grave after madness cast resolve
|
||||||
|
|
||||||
|
// raven on cast go to grave
|
||||||
|
// alchemist on discard with madness go to exile and grave
|
||||||
|
// bears on damage go to grave
|
||||||
|
assertReachesGraveyard(Arrays.asList("Raven's Crime", "Alchemist's Greeting", "Grizzly Bears"));
|
||||||
|
assertReachesExile(Arrays.asList("Alchemist's Greeting"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure no exile zone reaches due replacement effects (see oracle rules)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test_MadnessSorcery_OnDiscardWithDryadMilitant_BySpell() {
|
||||||
|
prepareGraveyardAndExileWatchers();
|
||||||
|
|
||||||
|
// checking rule:
|
||||||
|
// If an instant or sorcery card is discarded while Dryad Militant is on the battlefield, abilities that
|
||||||
|
// function when a card is discarded (such as madness) still work, even though that card never reaches a
|
||||||
|
// graveyard.
|
||||||
|
|
||||||
|
// If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
||||||
|
//
|
||||||
|
// Alchemist’s Greeting deals 4 damage to target creature.
|
||||||
|
// Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness
|
||||||
|
// cost or put it into your graveyard.)
|
||||||
|
addCard(Zone.HAND, playerA, "Alchemist's Greeting"); // {4}{R}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
//
|
||||||
|
// Target player discards a card.
|
||||||
|
addCard(Zone.HAND, playerA, "Raven's Crime"); // {B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
|
|
||||||
|
// discard
|
||||||
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 1);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerA);
|
||||||
|
setChoice(playerA, "Alchemist's Greeting"); // choose replacement effects (madness first)
|
||||||
|
setChoice(playerA, true); // use madness
|
||||||
|
addTarget(playerA, "Grizzly Bears"); // target of madness card
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertExileCount(playerA, "Alchemist's Greeting", 1); // discard -> exile and cast madness -> exile instead grave
|
||||||
|
|
||||||
|
// raven on cast go to exile instead grave due dryad effect
|
||||||
|
// alchemist on discard with madness go to exile, after cast go to exile again instead grave due dryad effect
|
||||||
|
// bears on damage go to grave (ignored by dryad effect due it's not a instant/sorcery)
|
||||||
|
assertReachesGraveyard(Arrays.asList("Grizzly Bears"));
|
||||||
|
assertReachesExile(Arrays.asList("Raven's Crime", "Alchemist's Greeting", "Alchemist's Greeting"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_MadnessSorcery_OnDiscardWithDryadMilitant_ByChandraAblaze() {
|
||||||
|
prepareGraveyardAndExileWatchers();
|
||||||
|
|
||||||
|
// checking rule:
|
||||||
|
// In addition, spells or abilities that check the characteristics of a discarded card (such as
|
||||||
|
// Chandra Ablaze’s first ability) can find that card in exile.
|
||||||
|
|
||||||
|
// If an instant or sorcery card would be put into a graveyard from anywhere, exile it instead.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Dryad Militant");
|
||||||
|
//
|
||||||
|
// Alchemist’s Greeting deals 4 damage to target creature.
|
||||||
|
// Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness
|
||||||
|
// cost or put it into your graveyard.)
|
||||||
|
addCard(Zone.HAND, playerA, "Alchemist's Greeting"); // {4}{R}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
//
|
||||||
|
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze");
|
||||||
|
|
||||||
|
// discard
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1");
|
||||||
|
addTarget(playerA, playerB); // x4 damage by chandra
|
||||||
|
setChoice(playerA, "Alchemist's Greeting"); // discard by chandra
|
||||||
|
setChoice(playerA, "Alchemist's Greeting"); // choose replacement effects (madness first)
|
||||||
|
setChoice(playerA, true); // use madness
|
||||||
|
addTarget(playerA, "Grizzly Bears"); // target of madness card
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertExileCount(playerA, "Alchemist's Greeting", 1); // discard -> exile and cast madness -> exile instead grave
|
||||||
|
assertLife(playerB, 20 - 4); // by chandra
|
||||||
|
|
||||||
|
// alchemist on discard with madness go to exile, after cast go to exile again instead grave due dryad effect
|
||||||
|
// bears on damage go to grave (ignored by dryad effect due it's not a instant/sorcery)
|
||||||
|
assertReachesGraveyard(Arrays.asList("Grizzly Bears"));
|
||||||
|
assertReachesExile(Arrays.asList("Alchemist's Greeting", "Alchemist's Greeting"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -131,12 +131,15 @@ class MadnessReplacementEffect extends ReplacementEffectImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO, deal with deprecated call
|
if (!controller.moveCards(card, Zone.EXILED, source, game)) {
|
||||||
if (controller.moveCards(card, Zone.EXILED, source, game)) {
|
return false;
|
||||||
game.applyEffects(); // needed to add Madness ability to cards (e.g. by Falkenrath Gorger)
|
}
|
||||||
|
|
||||||
|
// needed to add Madness ability to cards (e.g. by Falkenrath Gorger)
|
||||||
|
game.getState().processAction(game);
|
||||||
|
|
||||||
GameEvent gameEvent = new MadnessCardExiledEvent(card.getId(), source, controller.getId());
|
GameEvent gameEvent = new MadnessCardExiledEvent(card.getId(), source, controller.getId());
|
||||||
game.fireEvent(gameEvent);
|
game.fireEvent(gameEvent);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.watchers.common;
|
package mage.watchers.common;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.constants.WatcherScope;
|
import mage.constants.WatcherScope;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -7,12 +8,22 @@ import mage.game.events.GameEvent;
|
||||||
import mage.game.events.ZoneChangeEvent;
|
import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Susucr
|
* Counts cards that was moved to exile zone by any way
|
||||||
|
* <p>
|
||||||
|
* Can contain multiple instances of the same card (if it was moved multiple times per turn)
|
||||||
|
*
|
||||||
|
* @author Susucr, JayDi85
|
||||||
*/
|
*/
|
||||||
public class CardsExiledThisTurnWatcher extends Watcher {
|
public class CardsExiledThisTurnWatcher extends Watcher {
|
||||||
|
|
||||||
private int countExiled = 0;
|
private final List<UUID> exiledCards = new ArrayList<>();
|
||||||
|
|
||||||
public CardsExiledThisTurnWatcher() {
|
public CardsExiledThisTurnWatcher() {
|
||||||
super(WatcherScope.GAME);
|
super(WatcherScope.GAME);
|
||||||
|
|
@ -22,17 +33,24 @@ public class CardsExiledThisTurnWatcher extends Watcher {
|
||||||
public void watch(GameEvent event, Game game) {
|
public void watch(GameEvent event, Game game) {
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
|
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
|
||||||
&& ((ZoneChangeEvent) event).getToZone() == Zone.EXILED) {
|
&& ((ZoneChangeEvent) event).getToZone() == Zone.EXILED) {
|
||||||
countExiled++;
|
this.exiledCards.add(event.getTargetId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCountCardsExiledThisTurn() {
|
public int getCountCardsExiledThisTurn() {
|
||||||
return countExiled;
|
return this.exiledCards.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Card> getCardsExiledThisTurn(Game game) {
|
||||||
|
return this.exiledCards.stream()
|
||||||
|
.map(game::getCard)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
super.reset();
|
super.reset();
|
||||||
countExiled = 0;
|
this.exiledCards.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ import java.util.stream.Collectors;
|
||||||
* Counts how many cards are put into each player's graveyard this turn.
|
* Counts how many cards are put into each player's graveyard this turn.
|
||||||
* Keeps track of the UUIDs of the cards that went to graveyard this turn.
|
* Keeps track of the UUIDs of the cards that went to graveyard this turn.
|
||||||
* from the battlefield, from anywhere other both from anywhere and from only the battlefield.
|
* from the battlefield, from anywhere other both from anywhere and from only the battlefield.
|
||||||
|
* <p>
|
||||||
|
* Can contain multiple instances of the same card (if it was moved multiple times per turn)
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
|
|
@ -40,7 +42,8 @@ public class CardsPutIntoGraveyardWatcher extends Watcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID playerId = event.getPlayerId();
|
UUID playerId = event.getPlayerId();
|
||||||
if (playerId == null || game.getCard(event.getTargetId()) == null) {
|
Card card = game.getCard(event.getTargetId());
|
||||||
|
if (playerId == null || card == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue