mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 19:41:59 -08:00
implement [DSK] Screaming Nemesis
This commit is contained in:
parent
b01b5aa24d
commit
3acab4a76d
6 changed files with 231 additions and 43 deletions
101
Mage.Sets/src/mage/cards/s/ScreamingNemesis.java
Normal file
101
Mage.Sets/src/mage/cards/s/ScreamingNemesis.java
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.SavedDamageValue;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.CantGainLifeRestOfGameTargetEffect;
|
||||||
|
import mage.abilities.keyword.HasteAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.common.FilterAnyTarget;
|
||||||
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public final class ScreamingNemesis extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterAnyTarget filter = new FilterAnyTarget("any other target");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.getPermanentFilter().add(AnotherPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScreamingNemesis(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.SPIRIT);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Haste
|
||||||
|
this.addAbility(HasteAbility.getInstance());
|
||||||
|
|
||||||
|
// Whenever Screaming Nemesis is dealt damage, it deals that much damage to any other target. If a player is dealt damage this way, they can't gain life for the rest of the game.
|
||||||
|
Ability ability = new DealtDamageToSourceTriggeredAbility(new ScreamingNemesisEffect(), false);
|
||||||
|
ability.addTarget(new TargetAnyTarget(filter));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScreamingNemesis(final ScreamingNemesis card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreamingNemesis copy() {
|
||||||
|
return new ScreamingNemesis(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScreamingNemesisEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
ScreamingNemesisEffect() {
|
||||||
|
super(Outcome.Damage);
|
||||||
|
staticText = "it deals that much damage to any other target. "
|
||||||
|
+ "If a player is dealt damage this way, they can't gain life for the rest of the game";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScreamingNemesisEffect(final ScreamingNemesisEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreamingNemesisEffect copy() {
|
||||||
|
return new ScreamingNemesisEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
int amount = SavedDamageValue.MUCH.calculate(game, source, this);
|
||||||
|
UUID targetId = getTargetPointer().getFirst(game, source);
|
||||||
|
if (amount <= 0 || targetId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Permanent permanent = game.getPermanent(targetId);
|
||||||
|
Player player = game.getPlayer(targetId);
|
||||||
|
if (permanent != null) {
|
||||||
|
permanent.damage(amount, source.getSourceId(), source, game, false, true);
|
||||||
|
return true;
|
||||||
|
} else if (player != null) {
|
||||||
|
int damageDone = player.damage(amount, source.getSourceId(), source, game, false, true);
|
||||||
|
if (damageDone > 0) {
|
||||||
|
// If a player is dealt damage this way, they can't gain life for the rest of the game.
|
||||||
|
game.addEffect(new CantGainLifeRestOfGameTargetEffect().setTargetPointer(new FixedTarget(player.getId())), source);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,34 +1,27 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility;
|
import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility;
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
import mage.abilities.effects.common.continuous.CantGainLifeRestOfGameTargetEffect;
|
||||||
import mage.abilities.keyword.WitherAbility;
|
import mage.abilities.keyword.WitherAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Duration;
|
|
||||||
import mage.constants.Layer;
|
import java.util.UUID;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.SubLayer;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.players.Player;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class StigmaLasher extends CardImpl {
|
public final class StigmaLasher extends CardImpl {
|
||||||
|
|
||||||
public StigmaLasher(UUID ownerId, CardSetInfo setInfo) {
|
public StigmaLasher(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{R}");
|
||||||
this.subtype.add(SubType.ELEMENTAL);
|
this.subtype.add(SubType.ELEMENTAL);
|
||||||
this.subtype.add(SubType.SHAMAN);
|
this.subtype.add(SubType.SHAMAN);
|
||||||
|
|
||||||
|
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
@ -37,42 +30,19 @@ public final class StigmaLasher extends CardImpl {
|
||||||
this.addAbility(WitherAbility.getInstance());
|
this.addAbility(WitherAbility.getInstance());
|
||||||
|
|
||||||
// Whenever Stigma Lasher deals damage to a player, that player can't gain life for the rest of the game.
|
// Whenever Stigma Lasher deals damage to a player, that player can't gain life for the rest of the game.
|
||||||
this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new StigmaLasherEffect(), false, true));
|
this.addAbility(new DealsDamageToAPlayerTriggeredAbility(
|
||||||
|
new CantGainLifeRestOfGameTargetEffect(),
|
||||||
|
false, true
|
||||||
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private StigmaLasher(final StigmaLasher card) {
|
private StigmaLasher(final StigmaLasher card) {
|
||||||
super(card);
|
super(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StigmaLasher copy() {
|
public StigmaLasher copy() {
|
||||||
return new StigmaLasher(this);
|
return new StigmaLasher(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class StigmaLasherEffect extends ContinuousEffectImpl {
|
|
||||||
|
|
||||||
public StigmaLasherEffect() {
|
|
||||||
super(Duration.EndOfGame, Layer.PlayerEffects, SubLayer.NA, Outcome.Neutral);
|
|
||||||
staticText = "that player can't gain life for the rest of the game";
|
|
||||||
}
|
|
||||||
|
|
||||||
private StigmaLasherEffect(final StigmaLasherEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StigmaLasherEffect copy() {
|
|
||||||
return new StigmaLasherEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
|
||||||
if (player != null) {
|
|
||||||
player.setCanGainLife(false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -30,6 +30,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Leyline of Hope", 18, Rarity.RARE, mage.cards.l.LeylineOfHope.class));
|
cards.add(new SetCardInfo("Leyline of Hope", 18, Rarity.RARE, mage.cards.l.LeylineOfHope.class));
|
||||||
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Plains", 272, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Plains", 272, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Screaming Nemesis", 157, Rarity.MYTHIC, mage.cards.s.ScreamingNemesis.class));
|
||||||
cards.add(new SetCardInfo("Swamp", 274, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Swamp", 274, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("The Wandering Rescuer", 41, Rarity.MYTHIC, mage.cards.t.TheWanderingRescuer.class));
|
cards.add(new SetCardInfo("The Wandering Rescuer", 41, Rarity.MYTHIC, mage.cards.t.TheWanderingRescuer.class));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
package org.mage.test.cards.single.acr;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public class ScreamingNemesisTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.s.ScreamingNemesis Screaming Nemesis} {2}{R}
|
||||||
|
* Creature — Spirit
|
||||||
|
* Haste
|
||||||
|
* Whenever Screaming Nemesis is dealt damage, it deals that much damage to any other target. If a player is dealt damage this way, they can’t gain life for the rest of the game.
|
||||||
|
* 3/3
|
||||||
|
*/
|
||||||
|
private static final String nemesis = "Screaming Nemesis";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Trigger_PreventGainLife() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, nemesis);
|
||||||
|
addCard(Zone.HAND, playerA, "Shock");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Plains", 4);
|
||||||
|
addCard(Zone.HAND, playerB, "Angel's Mercy"); // You gain 7 life.
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", nemesis);
|
||||||
|
addTarget(playerA, playerB); // target for trigger
|
||||||
|
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Angel's Mercy");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 - 2);
|
||||||
|
assertGraveyardCount(playerB, "Angel's Mercy", 1);
|
||||||
|
assertDamageReceived(playerA, nemesis, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Trigger_Permanent_NoPreventGainLife() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, nemesis);
|
||||||
|
addCard(Zone.HAND, playerA, "Shock");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Centaur Courser");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Plains", 4);
|
||||||
|
addCard(Zone.HAND, playerB, "Angel's Mercy"); // You gain 7 life.
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", nemesis);
|
||||||
|
addTarget(playerA, "Centaur Courser"); // target for trigger
|
||||||
|
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Angel's Mercy");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 + 7);
|
||||||
|
assertGraveyardCount(playerB, "Angel's Mercy", 1);
|
||||||
|
assertDamageReceived(playerA, nemesis, 2);
|
||||||
|
assertDamageReceived(playerB, "Centaur Courser", 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package mage.abilities.effects.common.continuous;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Layer;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubLayer;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public class CantGainLifeRestOfGameTargetEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
|
public CantGainLifeRestOfGameTargetEffect() {
|
||||||
|
super(Duration.EndOfGame, Layer.PlayerEffects, SubLayer.NA, Outcome.Neutral);
|
||||||
|
staticText = "that player can't gain life for the rest of the game";
|
||||||
|
}
|
||||||
|
|
||||||
|
private CantGainLifeRestOfGameTargetEffect(final CantGainLifeRestOfGameTargetEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CantGainLifeRestOfGameTargetEffect copy() {
|
||||||
|
return new CantGainLifeRestOfGameTargetEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
||||||
|
if (player != null) {
|
||||||
|
player.setCanGainLife(false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,10 @@ public class TargetAnyTarget extends TargetPermanentOrPlayer {
|
||||||
this(1);
|
this(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TargetAnyTarget(FilterAnyTarget filter) {
|
||||||
|
this(1, 1, filter);
|
||||||
|
}
|
||||||
|
|
||||||
public TargetAnyTarget(int numTargets) {
|
public TargetAnyTarget(int numTargets) {
|
||||||
this(numTargets, numTargets);
|
this(numTargets, numTargets);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue