mirror of
https://github.com/correl/mage.git
synced 2024-11-29 03:00:12 +00:00
[MH2] Implemented Sanctifier en-Vec (#7893)
* [MH2] Implemented Sanctifier en-Vec * [MH2] Sanctifier en-Vec - Remove unused filter
This commit is contained in:
parent
568bfad743
commit
df5bf2fa25
4 changed files with 250 additions and 1 deletions
106
Mage.Sets/src/mage/cards/s/SanctifierEnVec.java
Normal file
106
Mage.Sets/src/mage/cards/s/SanctifierEnVec.java
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
|
import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect;
|
||||||
|
import mage.abilities.keyword.ProtectionAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.ZoneChangeEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author weirddan455
|
||||||
|
*/
|
||||||
|
public final class SanctifierEnVec extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCard filter = new FilterCard("cards that are black or red");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLACK), new ColorPredicate(ObjectColor.RED)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SanctifierEnVec(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.subtype.add(SubType.CLERIC);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// Protection from black and from red
|
||||||
|
this.addAbility(ProtectionAbility.from(ObjectColor.BLACK, ObjectColor.RED));
|
||||||
|
|
||||||
|
// When Sanctifier en-Vec enters the battlefield, exile all cards that are black or red from all graveyards.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new ExileGraveyardAllPlayersEffect(filter)));
|
||||||
|
|
||||||
|
// If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new SanctifierEnVecEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SanctifierEnVec(final SanctifierEnVec card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SanctifierEnVec copy() {
|
||||||
|
return new SanctifierEnVec(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SanctifierEnVecEffect extends ReplacementEffectImpl {
|
||||||
|
|
||||||
|
public SanctifierEnVecEffect() {
|
||||||
|
super(Duration.WhileOnBattlefield, Outcome.Exile);
|
||||||
|
this.staticText = "If a black or red permanent, spell, or card not on the battlefield would be put into a graveyard, exile it instead";
|
||||||
|
}
|
||||||
|
|
||||||
|
private SanctifierEnVecEffect(final SanctifierEnVecEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SanctifierEnVecEffect copy() {
|
||||||
|
return new SanctifierEnVecEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||||
|
if (zEvent.getToZone() == Zone.GRAVEYARD) {
|
||||||
|
Permanent permanent = zEvent.getTarget();
|
||||||
|
if (permanent != null) {
|
||||||
|
return permanent.getColor(game).contains(ObjectColor.BLACK) || permanent.getColor(game).contains(ObjectColor.RED);
|
||||||
|
}
|
||||||
|
Card card = game.getCard(zEvent.getTargetId());
|
||||||
|
if (card != null) {
|
||||||
|
return card.getColor(game).contains(ObjectColor.BLACK) || card.getColor(game).contains(ObjectColor.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -228,6 +228,7 @@ public final class ModernHorizons2 extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class));
|
cards.add(new SetCardInfo("Road // Ruin", 212, Rarity.UNCOMMON, mage.cards.r.RoadRuin.class));
|
||||||
cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class));
|
cards.add(new SetCardInfo("Rustvale Bridge", 253, Rarity.COMMON, mage.cards.r.RustvaleBridge.class));
|
||||||
cards.add(new SetCardInfo("Said // Done", 60, Rarity.UNCOMMON, mage.cards.s.SaidDone.class));
|
cards.add(new SetCardInfo("Said // Done", 60, Rarity.UNCOMMON, mage.cards.s.SaidDone.class));
|
||||||
|
cards.add(new SetCardInfo("Sanctifier en-Vec", 27, Rarity.RARE, mage.cards.s.SanctifierEnVec.class));
|
||||||
cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class));
|
cards.add(new SetCardInfo("Sanctuary Raptor", 233, Rarity.UNCOMMON, mage.cards.s.SanctuaryRaptor.class));
|
||||||
cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class));
|
cards.add(new SetCardInfo("Sanctum Prelate", 491, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class));
|
||||||
cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class));
|
cards.add(new SetCardInfo("Sanctum Weaver", 171, Rarity.RARE, mage.cards.s.SanctumWeaver.class));
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package org.mage.test.cards.replacement;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
public class SanctifierEnVecTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
private static final String sanctifier = "Sanctifier en-Vec";
|
||||||
|
private static final String painter = "Painter's Servant";
|
||||||
|
private static final String jace = "Jace, the Mind Sculptor";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntersBattlefieldAbility() {
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Divination");
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt");
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, "Fatal Push");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||||
|
addCard(Zone.HAND, playerA, sanctifier);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sanctifier);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
assertPermanentCount(playerA, sanctifier, 1);
|
||||||
|
assertGraveyardCount(playerA, "Divination", 1);
|
||||||
|
assertExileCount(playerA, "Lightning Bolt", 1);
|
||||||
|
assertExileCount(playerB, "Fatal Push", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReplacementEffect() {
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||||
|
addCard(Zone.HAND, playerA, "Divination");
|
||||||
|
addCard(Zone.HAND, playerB, jace);
|
||||||
|
addCard(Zone.HAND, playerB, "Fatal Push");
|
||||||
|
addCard(Zone.HAND, playerB, "One with Nothing");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sanctifier);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Midnight Reaper");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Midnight Reaper");
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Divination");
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "One with Nothing");
|
||||||
|
setStopAt(2, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
// Test that Midnight Reaper did not trigger
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, sanctifier, 1);
|
||||||
|
assertGraveyardCount(playerA, "Divination", 1);
|
||||||
|
assertGraveyardCount(playerB, "Grizzly Bears", 1);
|
||||||
|
assertExileCount(playerA, "Lightning Bolt", 2);
|
||||||
|
assertExileCount(playerB, "Midnight Reaper", 1);
|
||||||
|
|
||||||
|
assertExileCount(playerB, "One with Nothing", 1);
|
||||||
|
assertGraveyardCount(playerB, jace, 1);
|
||||||
|
assertExileCount(playerB, "Fatal Push", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEtbWithPaintersServant() {
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Divination");
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt");
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, "Fatal Push");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
addCard(Zone.HAND, playerA, sanctifier);
|
||||||
|
addCard(Zone.HAND, playerA, painter);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, painter);
|
||||||
|
setChoice(playerA, "Black");
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sanctifier);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
assertPermanentCount(playerA, painter, 1);
|
||||||
|
assertPermanentCount(playerA, sanctifier, 1);
|
||||||
|
assertExileCount(playerA, "Divination", 1);
|
||||||
|
assertExileCount(playerA, "Lightning Bolt", 1);
|
||||||
|
assertExileCount(playerB, "Fatal Push", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReplacementWithPaintersServant() {
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||||
|
addCard(Zone.HAND, playerA, "Divination");
|
||||||
|
addCard(Zone.HAND, playerA, painter);
|
||||||
|
addCard(Zone.HAND, playerB, jace);
|
||||||
|
addCard(Zone.HAND, playerB, "Fatal Push");
|
||||||
|
addCard(Zone.HAND, playerB, "One with Nothing");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sanctifier);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Midnight Reaper");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
// Tap correctly for painter
|
||||||
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}",2);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, painter);
|
||||||
|
setChoice(playerA, "Red");
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Midnight Reaper");
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Divination");
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "One with Nothing");
|
||||||
|
setStopAt(2, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
// Test that Midnight Reaper did not trigger
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, painter, 1);
|
||||||
|
assertPermanentCount(playerA, sanctifier, 1);
|
||||||
|
assertExileCount(playerB, jace, 1);
|
||||||
|
assertExileCount(playerA, "Divination", 1);
|
||||||
|
assertExileCount(playerB, "Grizzly Bears", 1);
|
||||||
|
assertExileCount(playerA, "Lightning Bolt", 2);
|
||||||
|
assertExileCount(playerB, "Midnight Reaper", 1);
|
||||||
|
|
||||||
|
assertExileCount(playerB, "One with Nothing", 1);
|
||||||
|
assertExileCount(playerB, jace, 1);
|
||||||
|
assertExileCount(playerB, "Fatal Push", 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ public class ExileGraveyardAllPlayersEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
toExile.addAll(player.getGraveyard());
|
toExile.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.moveCards(toExile, Zone.EXILED, source, game);
|
controller.moveCards(toExile, Zone.EXILED, source, game);
|
||||||
|
|
Loading…
Reference in a new issue