implement [BLB] Starseer Mentor

This commit is contained in:
Susucre 2024-07-12 18:18:02 +02:00
parent 233d714e00
commit 3fdeb8c2fc
8 changed files with 421 additions and 152 deletions

View file

@ -1,8 +1,8 @@
package mage.cards.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.YouLostLifeCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
@ -18,21 +18,22 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.common.PlayerLostLifeWatcher;
import java.util.UUID;
/**
*
* @author Styxo
*/
public final class RevengeStarWars extends CardImpl {
private static final Condition condition = new YouLostLifeCondition();
public RevengeStarWars(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// Target creature you control gets +4/+0 until end of turn before it fights if you lost life this turn.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new RevengeEffect(),
LostLifeCondition.instance,
new RevengeEffect(), condition,
"Target creature you control gets +4/+0 until end of turn before it fights if you lost life this turn"));
// Target creature you control fights target creature an opponent controls.
@ -52,22 +53,6 @@ public final class RevengeStarWars extends CardImpl {
}
}
enum LostLifeCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
PlayerLostLifeWatcher watcher = game.getState().getWatcher(PlayerLostLifeWatcher.class);
UUID player = source.getControllerId();
if (watcher != null && player != null) {
return watcher.getLifeLost(player) > 0;
}
return false;
}
}
class RevengeEffect extends OneShotEffect {
RevengeEffect() {

View file

@ -0,0 +1,96 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.OrCondition;
import mage.abilities.condition.common.YouGainedLifeCondition;
import mage.abilities.condition.common.YouLostLifeCondition;
import mage.abilities.costs.OrCost;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.target.common.TargetOpponent;
import mage.watchers.common.PlayerGainedLifeWatcher;
import mage.watchers.common.PlayerLostLifeWatcher;
import java.util.UUID;
/**
* @author Susucr
*/
public final class StarseerMentor extends CardImpl {
private static final Condition condition =
new OrCondition(
"if you gained or lost life this turn",
new YouGainedLifeCondition(),
new YouLostLifeCondition()
);
private static final Hint hint = new ConditionHint(condition);
private static final FilterControlledPermanent filter = new FilterControlledPermanent("nonland permanent");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public StarseerMentor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}");
this.subtype.add(SubType.BAT);
this.subtype.add(SubType.WARLOCK);
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// At the beginning of your end step, if you gained or lost life this turn, target opponent loses 3 life unless they sacrifice a nonland permanent or discard a card.
Ability ability = new ConditionalInterveningIfTriggeredAbility(
new BeginningOfEndStepTriggeredAbility(
new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(
new LoseLifeTargetEffect(3),
new OrCost(
"sacrifice a nonland permanent or discard a card",
new SacrificeTargetCost(filter),
new DiscardCardCost()
),
"Sacrifice a nonland permanent or discard a card to prevent losing 3 life?"
), TargetController.YOU, false
), condition, "At the beginning of your end step, if you gained or lost life this turn, "
+ "target opponent loses 3 life unless they sacrifice a nonland permanent or discard a card."
);
ability.addTarget(new TargetOpponent());
ability.addWatcher(new PlayerGainedLifeWatcher());
ability.addWatcher(new PlayerLostLifeWatcher());
ability.addHint(hint);
this.addAbility(ability);
}
private StarseerMentor(final StarseerMentor card) {
super(card);
}
@Override
public StarseerMentor copy() {
return new StarseerMentor(this);
}
}

View file

@ -3,30 +3,30 @@ package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.OrCost;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.effects.common.UntapSourceEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.Card;
import mage.cards.CardSetInfo;
import mage.cards.ModalDoubleFacedCard;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.target.common.TargetSacrifice;
import mage.target.targetpointer.FixedTarget;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -34,6 +34,12 @@ import java.util.UUID;
*/
public final class TergridGodOfFright extends ModalDoubleFacedCard {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("nonland permanent");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public TergridGodOfFright(UUID ownerId, CardSetInfo setInfo) {
super(
ownerId, setInfo,
@ -58,7 +64,15 @@ public final class TergridGodOfFright extends ModalDoubleFacedCard {
// Legendary Artifact
// {T}: Target player loses 3 life unless they sacrifice a nonland permanent or discard a card.
Ability tergridsLaternActivatedAbility = new SimpleActivatedAbility(
new TergridsLaternEffect(), new TapSourceCost()
new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(
new LoseLifeTargetEffect(3),
new OrCost(
"sacrifice a nonland permanent or discard a card",
new SacrificeTargetCost(filter),
new DiscardCardCost()
),
"Sacrifice a nonland permanent or discard a card to prevent losing 3 life?"
), new TapSourceCost()
);
tergridsLaternActivatedAbility.addTarget(new TargetPlayer());
this.getRightHalfCard().addAbility(tergridsLaternActivatedAbility);
@ -166,69 +180,3 @@ class TergridGodOfFrightEffect extends OneShotEffect {
return false;
}
}
class TergridsLaternEffect extends OneShotEffect {
private static final String SACRIFICE_CHOICE = "Sacrifice a nonland permanent";
private static final String DISCARD_CHOICE = "Discard a card";
private static final String LIFE_LOSS_CHOICE = "Lose 3 life";
public TergridsLaternEffect() {
super(Outcome.Detriment);
staticText = "Target player loses 3 life unless they sacrifice a nonland permanent or discard a card";
}
private TergridsLaternEffect(final TergridsLaternEffect effect) {
super(effect);
}
@Override
public TergridsLaternEffect copy() {
return new TergridsLaternEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetedPlayer = game.getPlayer(source.getTargets().getFirstTarget());
if (targetedPlayer == null) {
return false;
}
// AI hint to discard/sacrifice before die
Outcome aiOutcome = (targetedPlayer.getLife() <= 3 * 2) ? Outcome.Benefit : Outcome.Detriment;
Set<String> choiceSet = new HashSet<>();
if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND, targetedPlayer.getId(), source, game) > 0) {
choiceSet.add(SACRIFICE_CHOICE);
}
if (targetedPlayer.getHand().size() > 0) {
choiceSet.add(DISCARD_CHOICE);
}
choiceSet.add(LIFE_LOSS_CHOICE);
String chosen;
if (choiceSet.size() > 1) {
Choice choice = new ChoiceImpl(true);
choice.setChoices(choiceSet);
targetedPlayer.choose(aiOutcome, choice, game);
chosen = choice.getChoice();
if (chosen == null) {
// on disconnect
chosen = LIFE_LOSS_CHOICE;
}
} else {
chosen = LIFE_LOSS_CHOICE;
}
switch (chosen) {
case SACRIFICE_CHOICE:
TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND);
targetedPlayer.choose(Outcome.Sacrifice, target, source, game);
Permanent chosenLand = game.getPermanent(target.getFirstTarget());
return chosenLand != null && chosenLand.sacrifice(source, game);
case DISCARD_CHOICE:
return targetedPlayer.discard(1, false, false, source, game).size() > 0;
case LIFE_LOSS_CHOICE:
return targetedPlayer.loseLife(3, game, source, false) > 0;
}
return false;
}
}

View file

@ -2,8 +2,12 @@ package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.costs.OrCost;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -11,21 +15,23 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
* @author LevelX2
* @author LevelX2, Susucr
*/
public final class TormentOfScarabs extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("nonland permanent");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public TormentOfScarabs(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}");
@ -40,7 +46,15 @@ public final class TormentOfScarabs extends CardImpl {
// At the beginning of enchanted player's upkeep, that player loses 3 life unless they sacrifice a nonland permanent or discards a card.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new TormentOfScarabsEffect(), TargetController.ENCHANTED, false
new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(
new LoseLifeTargetEffect(3),
new OrCost(
"sacrifice a nonland permanent or discard a card",
new SacrificeTargetCost(filter),
new DiscardCardCost()
),
"Sacrifice a nonland permanent or discard a card to prevent losing 3 life?"
), TargetController.ENCHANTED, false
));
}
@ -53,47 +67,3 @@ public final class TormentOfScarabs extends CardImpl {
return new TormentOfScarabs(this);
}
}
class TormentOfScarabsEffect extends OneShotEffect {
TormentOfScarabsEffect() {
super(Outcome.LoseLife);
this.staticText = "that player loses 3 life unless they sacrifice a nonland permanent or discard a card";
}
private TormentOfScarabsEffect(final TormentOfScarabsEffect effect) {
super(effect);
}
@Override
public TormentOfScarabsEffect copy() {
return new TormentOfScarabsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player enchantedPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (enchantedPlayer == null) {
return false;
}
int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, enchantedPlayer.getId(), game);
if (permanents > 0 && enchantedPlayer.chooseUse(outcome, "Sacrifice a nonland permanent?",
"Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) {
Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND);
if (enchantedPlayer.choose(outcome, target, source, game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.sacrifice(source, game);
return true;
}
}
}
if (!enchantedPlayer.getHand().isEmpty() && enchantedPlayer.chooseUse(outcome, "Discard a card?",
"Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) {
enchantedPlayer.discardOne(false, false, source, game);
return true;
}
enchantedPlayer.loseLife(3, game, source, false);
return true;
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
@ -22,8 +21,9 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class TormentOfVenom extends CardImpl {
@ -46,6 +46,7 @@ public final class TormentOfVenom extends CardImpl {
}
}
// TODO: simplify using DoUnlessTargetPlayerOrTargetsControllerPaysEffect and OrCost
class TormentOfVenomEffect extends OneShotEffect {
TormentOfVenomEffect() {

View file

@ -88,6 +88,7 @@ public final class Bloomburrow extends ExpansionSet {
cards.add(new SetCardInfo("Shrike Force", 31, Rarity.UNCOMMON, mage.cards.s.ShrikeForce.class));
cards.add(new SetCardInfo("Splash Lasher", 73, Rarity.UNCOMMON, mage.cards.s.SplashLasher.class));
cards.add(new SetCardInfo("Stargaze", 114, Rarity.UNCOMMON, mage.cards.s.Stargaze.class));
cards.add(new SetCardInfo("Starseer Mentor", 233, Rarity.UNCOMMON, mage.cards.s.StarseerMentor.class));
cards.add(new SetCardInfo("Steampath Charger", 153, Rarity.COMMON, mage.cards.s.SteampathCharger.class));
cards.add(new SetCardInfo("Stormcatch Mentor", 234, Rarity.UNCOMMON, mage.cards.s.StormcatchMentor.class));
cards.add(new SetCardInfo("Sunshower Druid", 195, Rarity.COMMON, mage.cards.s.SunshowerDruid.class));

View file

@ -0,0 +1,231 @@
package org.mage.test.cards.single.blb;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author Susucr
*/
public class StarseerMentorTest extends CardTestPlayerBase {
/**
* {@link mage.cards.s.StarseerMentor Starseer Mentor} {3}{W}{B}
* Creature Bat Warlock
* Flying, vigilance
* At the beginning of your end step, if you gained or lost life this turn, target opponent loses 3 life unless they sacrifice a nonland permanent or discard a card.
* 3/5
*/
private static final String mentor = "Starseer Mentor";
@Test
public void test_NoTrigger() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20);
}
@Test
public void test_LifeGain_Trigger() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
// playerB has no way to pay for the cost, so no choice.
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20 - 3);
}
@Test
public void test_LifeLost_Trigger() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Serpent Warrior"); // etb loses 3 life
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Serpent Warrior");
addTarget(playerA, playerB); // target for the trigger.
// playerB has no way to pay for the cost, so no choice.
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20 - 3);
}
@Test
public void test_Trigger_CanDiscard_AndDiscard() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerB, "Abandon Hope");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, true); // choose to pay the cost to not lose life
setChoice(playerB, "Abandon Hope"); // Choose to discard
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Abandon Hope", 1);
}
@Test
public void test_Trigger_CanDiscard_AndDontDiscard() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerB, "Abandon Hope");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, false); // choose to not pay the cost to not lose life
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20 - 3);
assertHandCount(playerB, "Abandon Hope", 1);
}
@Test
public void test_Trigger_CanSacrifice_AndSacrifice() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerB, "Elite Vanguard");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, true); // choose to pay the cost to not lose life
setChoice(playerB, "Elite Vanguard"); // Choose to sacrifice
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Elite Vanguard", 1);
}
@Test
public void test_Trigger_CanSacrifice_AndDontSacrifice() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerB, "Elite Vanguard");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, false); // choose to not pay the cost to not lose life
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20 - 3);
assertPermanentCount(playerB, "Elite Vanguard", 1);
}
@Test
public void test_Trigger_CanSacrificeOrDiscard_AndSacrifice() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerB, "Elite Vanguard");
addCard(Zone.HAND, playerB, "Abandon Hope");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, true); // choose to pay the cost to not lose life
setChoice(playerB, true); // choose to pay the sacrifice cost
setChoice(playerB, "Elite Vanguard"); // Choose to sacrifice
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Elite Vanguard", 1);
assertHandCount(playerB, "Abandon Hope", 1);
}
@Test
public void test_Trigger_CanSacrificeOrDiscard_AndDiscard() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerB, "Elite Vanguard");
addCard(Zone.HAND, playerB, "Abandon Hope");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, true); // choose to pay the cost to not lose life
setChoice(playerB, false); // choose to not pay the sacrifice cost (so will discard)
setChoice(playerB, "Abandon Hope"); // Choose to discard
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20);
assertPermanentCount(playerB, "Elite Vanguard", 1);
assertGraveyardCount(playerB, "Abandon Hope", 1);
}
@Test
public void test_Trigger_CanSacrificeOrDiscard_AndDontPay() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, mentor);
addCard(Zone.HAND, playerA, "Angel of Mercy"); // etb gains 5 life
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerB, "Elite Vanguard");
addCard(Zone.HAND, playerB, "Abandon Hope");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Mercy");
addTarget(playerA, playerB); // target for the trigger.
setChoice(playerB, false); // choose to not pay the cost to not lose life
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 20 - 3);
assertPermanentCount(playerB, "Elite Vanguard", 1);
assertHandCount(playerB, "Abandon Hope", 1);
}
}

View file

@ -0,0 +1,37 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.IntCompareCondition;
import mage.constants.ComparisonType;
import mage.game.Game;
import mage.watchers.common.PlayerLostLifeWatcher;
/**
* Needs PlayerLostLifeWatcher to work
*
* @author Susucr
*/
public class YouLostLifeCondition extends IntCompareCondition {
/**
* "if you lost life this turn"
*/
public YouLostLifeCondition() {
super(ComparisonType.MORE_THAN, 0);
}
public YouLostLifeCondition(ComparisonType type, int value) {
super(type, value);
}
@Override
protected int getInputValue(Game game, Ability source) {
PlayerLostLifeWatcher watcher = game.getState().getWatcher(PlayerLostLifeWatcher.class);
return watcher == null ? 0 : watcher.getLifeLost(source.getControllerId());
}
@Override
public String toString() {
return "if you lost " + (value == 0 ? "" : (value + 1) + " or more ") + "life this turn";
}
}