new common class for life drain effects

"Each opponent loses X life. You gain life equal to the life lost this way."
This commit is contained in:
xenohedron 2024-01-26 21:41:30 -05:00
parent c4aa812862
commit 1a7edda03d
17 changed files with 179 additions and 591 deletions

View file

@ -1,16 +1,13 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.game.Game;
import java.util.UUID;
@ -27,7 +24,7 @@ public final class AgentOfMasks extends CardImpl {
// At the beginning of your upkeep, each opponent loses 1 life. You gain life equal to the life lost this way.
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AgentOfMasksEffect(), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsYouGainLifeLostEffect(1), TargetController.YOU, false));
}
private AgentOfMasks(final AgentOfMasks card) {
@ -39,31 +36,3 @@ public final class AgentOfMasks extends CardImpl {
return new AgentOfMasks(this);
}
}
class AgentOfMasksEffect extends OneShotEffect {
public AgentOfMasksEffect() {
super(Outcome.Damage);
staticText = "each opponent loses 1 life. You gain life equal to the life lost this way";
}
private AgentOfMasksEffect(final AgentOfMasksEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int loseLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
loseLife += game.getPlayer(opponentId).loseLife(1, game, source, false);
}
if (loseLife > 0)
game.getPlayer(source.getControllerId()).gainLife(loseLife, game, source);
return true;
}
@Override
public AgentOfMasksEffect copy() {
return new AgentOfMasksEffect(this);
}
}

View file

@ -1,15 +1,11 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import java.util.UUID;
/**
*
@ -20,7 +16,8 @@ public final class BloodTithe extends CardImpl {
public BloodTithe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
this.getSpellAbility().addEffect(new BloodTitheEffect());
// Each opponent loses 3 life. You gain life equal to the life lost this way.
this.getSpellAbility().addEffect(new LoseLifeOpponentsYouGainLifeLostEffect(3));
}
private BloodTithe(final BloodTithe card) {
@ -33,31 +30,3 @@ public final class BloodTithe extends CardImpl {
}
}
class BloodTitheEffect extends OneShotEffect {
BloodTitheEffect() {
super(Outcome.GainLife);
staticText = "Each opponent loses 3 life. You gain life equal to the life lost this way";
}
private BloodTitheEffect(final BloodTitheEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int lifeLost = 0;
for (UUID opponentId: game.getOpponents(source.getControllerId())) {
lifeLost += game.getPlayer(opponentId).loseLife(3, game, source, false);
}
game.getPlayer(source.getControllerId()).gainLife(lifeLost, game, source);
return true;
}
@Override
public BloodTitheEffect copy() {
return new BloodTitheEffect(this);
}
}

View file

@ -1,24 +1,21 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
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.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
@ -41,7 +38,7 @@ public final class BubblingCauldron extends CardImpl {
ability1.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT));
this.addAbility(ability1);
// {1}, {T}, Sacrifice a creature named Festering Newt: Each opponent loses 4 life. You gain life equal to the life lost this way.
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BubblingCauldronEffect(), new ManaCostsImpl<>("{1}"));
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeOpponentsYouGainLifeLostEffect(4), new ManaCostsImpl<>("{1}"));
ability2.addCost(new TapSourceCost());
ability2.addCost(new SacrificeTargetCost(filter));
this.addAbility(ability2);
@ -56,37 +53,3 @@ public final class BubblingCauldron extends CardImpl {
return new BubblingCauldron(this);
}
}
class BubblingCauldronEffect extends OneShotEffect {
BubblingCauldronEffect() {
super(Outcome.GainLife);
staticText = "Each opponent loses 4 life. You gain life equal to the life lost this way";
}
private BubblingCauldronEffect(final BubblingCauldronEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int lostLife = 0;
Player controller = game.getPlayer(source.getControllerId());
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
lostLife += opponent.loseLife(4, game, source, false);
}
}
if (controller != null) {
controller.gainLife(lostLife, game, source);
}
return true;
}
@Override
public BubblingCauldronEffect copy() {
return new BubblingCauldronEffect(this);
}
}

View file

@ -1,22 +1,19 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.ChancellorAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import java.util.UUID;
/**
*
@ -24,7 +21,7 @@ import mage.game.events.GameEvent.EventType;
*/
public final class ChancellorOfTheDross extends CardImpl {
private static String abilityText = "at the beginning of the first upkeep, each opponent loses 3 life, then you gain life equal to the life lost this way";
private static final String abilityText = "at the beginning of the first upkeep, each opponent loses 3 life, then you gain life equal to the life lost this way";
public ChancellorOfTheDross(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}{B}");
@ -54,7 +51,7 @@ public final class ChancellorOfTheDross extends CardImpl {
class ChancellorOfTheDrossDelayedTriggeredAbility extends DelayedTriggeredAbility {
ChancellorOfTheDrossDelayedTriggeredAbility () {
super(new ChancellorOfTheDrossEffect());
super(new LoseLifeOpponentsYouGainLifeLostEffect(3));
}
private ChancellorOfTheDrossDelayedTriggeredAbility(final ChancellorOfTheDrossDelayedTriggeredAbility ability) {
@ -75,33 +72,3 @@ class ChancellorOfTheDrossDelayedTriggeredAbility extends DelayedTriggeredAbilit
return new ChancellorOfTheDrossDelayedTriggeredAbility(this);
}
}
class ChancellorOfTheDrossEffect extends OneShotEffect {
ChancellorOfTheDrossEffect () {
super(Outcome.Benefit);
staticText = "each opponent loses 3 life, then you gain life equal to the life lost this way";
}
private ChancellorOfTheDrossEffect(final ChancellorOfTheDrossEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int loseLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
loseLife += game.getPlayer(opponentId).loseLife(3, game, source, false);
}
if (loseLife > 0) {
game.getPlayer(source.getControllerId()).gainLife(loseLife, game, source);
}
return true;
}
@Override
public ChancellorOfTheDrossEffect copy() {
return new ChancellorOfTheDrossEffect(this);
}
}

View file

@ -1,15 +1,14 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.MultipliedValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -17,11 +16,13 @@ import mage.players.Player;
*/
public final class DebtToTheDeathless extends CardImpl {
private static final DynamicValue xValue = new MultipliedValue(ManacostVariableValue.REGULAR, 2);
public DebtToTheDeathless(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{W}{W}{B}{B}");
// Each opponent loses two times X life. You gain life equal to the life lost this way.
this.getSpellAbility().addEffect(new DebtToTheDeathlessEffect());
this.getSpellAbility().addEffect(new LoseLifeOpponentsYouGainLifeLostEffect(xValue, "two times X life"));
}
private DebtToTheDeathless(final DebtToTheDeathless card) {
@ -33,38 +34,3 @@ public final class DebtToTheDeathless extends CardImpl {
return new DebtToTheDeathless(this);
}
}
class DebtToTheDeathlessEffect extends OneShotEffect {
DebtToTheDeathlessEffect() {
super(Outcome.Benefit);
this.staticText = "Each opponent loses two times X life. You gain life equal to the life lost this way";
}
private DebtToTheDeathlessEffect(final DebtToTheDeathlessEffect effect) {
super(effect);
}
@Override
public DebtToTheDeathlessEffect copy() {
return new DebtToTheDeathlessEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
int lifeLost = 0;
int xValue = source.getManaCostsToPay().getX();
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
lifeLost += opponent.loseLife(xValue * 2, game, source, false);
}
}
controller.gainLife(lifeLost, game, source);
return true;
}
return false;
}
}

View file

@ -1,13 +1,12 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import java.util.UUID;
/**
*
@ -18,7 +17,8 @@ public final class Exsanguinate extends CardImpl {
public Exsanguinate(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}");
this.getSpellAbility().addEffect(new ExsanguinateEffect());
// Each opponent loses X life. You gain life equal to the life lost this way.
this.getSpellAbility().addEffect(new LoseLifeOpponentsYouGainLifeLostEffect(ManacostVariableValue.REGULAR, "X life"));
}
private Exsanguinate(final Exsanguinate card) {
@ -31,34 +31,3 @@ public final class Exsanguinate extends CardImpl {
}
}
class ExsanguinateEffect extends OneShotEffect {
ExsanguinateEffect() {
super(Outcome.GainLife);
staticText = "Each opponent loses X life. You gain life equal to the life lost this way";
}
private ExsanguinateEffect(final ExsanguinateEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int totalLostLife = 0;
int loseLife = source.getManaCostsToPay().getX();
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
totalLostLife += game.getPlayer(opponentId).loseLife(loseLife, game, source, false);
}
if (totalLostLife > 0) {
game.getPlayer(source.getControllerId()).gainLife(totalLostLife, game, source);
}
return true;
}
@Override
public ExsanguinateEffect copy() {
return new ExsanguinateEffect(this);
}
}

View file

@ -1,26 +1,25 @@
package mage.cards.g;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author LevelX2
*/
@ -36,7 +35,7 @@ public final class GontisMachinations extends CardImpl {
// Pay {E}{E}, Sacrifice Gonti's Machinations: Each opponent loses 3 life. You gain life equal to the life lost this way.
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new GontisMachinationsEffect(),
new LoseLifeOpponentsYouGainLifeLostEffect(3),
new PayEnergyCost(2));
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@ -117,38 +116,3 @@ class GontisMachinationsFirstLostLifeThisTurnWatcher extends Watcher {
return playersLostLife.getOrDefault(playerId, 0);
}
}
class GontisMachinationsEffect extends OneShotEffect {
GontisMachinationsEffect() {
super(Outcome.GainLife);
staticText = "Each opponent loses 3 life. You gain life equal to the life lost this way";
}
private GontisMachinationsEffect(final GontisMachinationsEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int totalLostLife = 0;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
totalLostLife += game.getPlayer(opponentId).loseLife(3, game, source, false);
}
}
game.getPlayer(source.getControllerId()).gainLife(totalLostLife, game, source);
return true;
}
return false;
}
@Override
public GontisMachinationsEffect copy() {
return new GontisMachinationsEffect(this);
}
}

View file

@ -1,19 +1,14 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.Objects;
import java.util.UUID;
/**
@ -29,8 +24,8 @@ public final class GrayMerchantOfAsphodel extends CardImpl {
this.toughness = new MageInt(4);
// When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new GrayMerchantOfAsphodelEffect(), false
this.addAbility(new EntersBattlefieldTriggeredAbility(new LoseLifeOpponentsYouGainLifeLostEffect(
DevotionCount.B, "X life, where X is your devotion to black"), false
).addHint(DevotionCount.B.getHint()));
}
@ -43,42 +38,3 @@ public final class GrayMerchantOfAsphodel extends CardImpl {
return new GrayMerchantOfAsphodel(this);
}
}
class GrayMerchantOfAsphodelEffect extends OneShotEffect {
GrayMerchantOfAsphodelEffect() {
super(Outcome.GainLife);
this.staticText = "each opponent loses X life, where X is your devotion to black. "
+ "You gain life equal to the life lost this way. "
+ DevotionCount.B.getReminder();
}
private GrayMerchantOfAsphodelEffect(final GrayMerchantOfAsphodelEffect effect) {
super(effect);
}
@Override
public GrayMerchantOfAsphodelEffect copy() {
return new GrayMerchantOfAsphodelEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
int lifeLost = DevotionCount.B.calculate(game, source, this);
if (lifeLost == 0) {
return true;
}
int totalLifeLost = game
.getOpponents(source.getControllerId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.mapToInt(opponent -> opponent.loseLife(lifeLost, game, source, false))
.sum();
return controller.gainLife(totalLifeLost, game, source) > 0;
}
}

View file

@ -1,20 +1,16 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.game.Game;
import java.util.UUID;
/**
* @author Loki
@ -30,7 +26,7 @@ public final class KokushoTheEveningStar extends CardImpl {
this.power = new MageInt(5);
this.toughness = new MageInt(5);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new DiesSourceTriggeredAbility(new KokushoTheEveningStarEffect(), false));
this.addAbility(new DiesSourceTriggeredAbility(new LoseLifeOpponentsYouGainLifeLostEffect(5), false));
}
private KokushoTheEveningStar(final KokushoTheEveningStar card) {
@ -43,31 +39,3 @@ public final class KokushoTheEveningStar extends CardImpl {
}
}
class KokushoTheEveningStarEffect extends OneShotEffect {
public KokushoTheEveningStarEffect() {
super(Outcome.Damage);
staticText = "each opponent loses 5 life. You gain life equal to the life lost this way";
}
private KokushoTheEveningStarEffect(final KokushoTheEveningStarEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int loseLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
loseLife += game.getPlayer(opponentId).loseLife(5, game, source, false);
}
if (loseLife > 0)
game.getPlayer(source.getControllerId()).gainLife(loseLife, game, source);
return true;
}
@Override
public KokushoTheEveningStarEffect copy() {
return new KokushoTheEveningStarEffect(this);
}
}

View file

@ -1,24 +1,22 @@
package mage.cards.m;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -26,6 +24,9 @@ import mage.players.Player;
*/
public final class MalakirBloodwitch extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.VAMPIRE));
private static final Hint hint = new ValueHint("Vampires you control", xValue);
public MalakirBloodwitch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
this.subtype.add(SubType.VAMPIRE);
@ -41,8 +42,10 @@ public final class MalakirBloodwitch extends CardImpl {
this.addAbility(ProtectionAbility.from(ObjectColor.WHITE));
// When Malakir Bloodwitch enters the battlefield, each opponent loses life equal to the number of Vampires you control. You gain life equal to the life lost this way.
this.addAbility(new EntersBattlefieldTriggeredAbility(new MalakirBloodwitchEffect(), false)
.addHint(new ValueHint("Vampires you control", new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.VAMPIRE))))
this.addAbility(new EntersBattlefieldTriggeredAbility(
new LoseLifeOpponentsYouGainLifeLostEffect(xValue,
"life equal to the number of Vampires you control"), false
).addHint(hint)
);
}
@ -55,46 +58,3 @@ public final class MalakirBloodwitch extends CardImpl {
return new MalakirBloodwitch(this);
}
}
class MalakirBloodwitchEffect extends OneShotEffect {
MalakirBloodwitchEffect() {
super(Outcome.Benefit);
this.staticText = "each opponent loses life equal to the number of Vampires you control. You gain life equal to the life lost this way";
}
private MalakirBloodwitchEffect(final MalakirBloodwitchEffect effect) {
super(effect);
}
@Override
public MalakirBloodwitchEffect copy() {
return new MalakirBloodwitchEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
FilterControlledPermanent filter = new FilterControlledPermanent("Vampire");
filter.add(SubType.VAMPIRE.getPredicate());
int amount = game.getBattlefield().countAll(filter, source.getControllerId(), game);
Set<UUID> opponents = game.getOpponents(source.getControllerId());
int total = 0;
for (UUID opponentUuid : opponents) {
Player opponent = game.getPlayer(opponentUuid);
if (opponent != null) {
total += opponent.loseLife(amount, game, source, false);
}
}
if (total > 0) {
player.gainLife(total, game, source);
}
return true;
}
}

View file

@ -1,24 +1,20 @@
package mage.cards.o;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.game.Game;
import mage.game.command.emblems.ObNixilisOfTheBlackOathEmblem;
import mage.game.permanent.token.DemonToken;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -34,7 +30,7 @@ public final class ObNixilisOfTheBlackOath extends CardImpl {
this.setStartingLoyalty(3);
// +2: Each opponent loses 1 life. You gain life equal to the life lost this way.
this.addAbility(new LoyaltyAbility(new ObNixilisOfTheBlackOathEffect1(), 2));
this.addAbility(new LoyaltyAbility(new LoseLifeOpponentsYouGainLifeLostEffect(1), 2));
// -2: Create a 5/5 black Demon creature token with flying. You lose 2 life.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new CreateTokenEffect(new DemonToken()), -2);
@ -57,39 +53,3 @@ public final class ObNixilisOfTheBlackOath extends CardImpl {
return new ObNixilisOfTheBlackOath(this);
}
}
class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect {
public ObNixilisOfTheBlackOathEffect1() {
super(Outcome.Damage);
staticText = "Each opponent loses 1 life. You gain life equal to the life lost this way";
}
private ObNixilisOfTheBlackOathEffect1(final ObNixilisOfTheBlackOathEffect1 effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
int loseLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
loseLife += opponent.loseLife(1, game, source, false);
}
}
controller.gainLife(loseLife, game, source);
return true;
}
return false;
}
@Override
public ObNixilisOfTheBlackOathEffect1 copy() {
return new ObNixilisOfTheBlackOathEffect1(this);
}
}

View file

@ -1,19 +1,16 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -30,7 +27,7 @@ public final class ScholarOfAthreos extends CardImpl {
this.toughness = new MageInt(4);
// {2}{B}: Each opponent loses 1 life. You gain life equal to the life lost this way.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScholarOfAthreosEffect(), new ManaCostsImpl<>("{2}{B}")));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeOpponentsYouGainLifeLostEffect(1), new ManaCostsImpl<>("{2}{B}")));
}
private ScholarOfAthreos(final ScholarOfAthreos card) {
@ -42,34 +39,3 @@ public final class ScholarOfAthreos extends CardImpl {
return new ScholarOfAthreos(this);
}
}
class ScholarOfAthreosEffect extends OneShotEffect {
ScholarOfAthreosEffect() {
super(Outcome.Damage);
staticText = "Each opponent loses 1 life. You gain life equal to the life lost this way";
}
private ScholarOfAthreosEffect(final ScholarOfAthreosEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int lifeLost = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if(opponent != null) {
lifeLost += opponent.loseLife(1, game, source, false);
}
}
game.getPlayer(source.getControllerId()).gainLife(lifeLost, game, source);
return true;
}
@Override
public ScholarOfAthreosEffect copy() {
return new ScholarOfAthreosEffect(this);
}
}

View file

@ -1,21 +1,18 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.keyword.InspiredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import java.util.UUID;
/**
*
@ -31,7 +28,7 @@ public final class ServantOfTymaret extends CardImpl {
this.toughness = new MageInt(3);
// <i>Inspired</i> &mdash; Whenever Servant of Tymaret becomes untapped, each opponent loses 1 life. You gain life equal to the life lost this way.
this.addAbility(new InspiredAbility(new ServantOfTymaretEffect()));
this.addAbility(new InspiredAbility(new LoseLifeOpponentsYouGainLifeLostEffect(1)));
// {2}{B}: Regenerate Servant of Tymaret.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl<>("{2}{B}")));
@ -46,31 +43,3 @@ public final class ServantOfTymaret extends CardImpl {
return new ServantOfTymaret(this);
}
}
class ServantOfTymaretEffect extends OneShotEffect {
ServantOfTymaretEffect() {
super(Outcome.Damage);
staticText = "each opponent loses 1 life. You gain life equal to the life lost this way";
}
private ServantOfTymaretEffect(final ServantOfTymaretEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int lostAmount = 0;
for (UUID opponentId: game.getOpponents(source.getControllerId())) {
lostAmount += game.getPlayer(opponentId).loseLife(1, game, source, false);
}
game.getPlayer(source.getControllerId()).gainLife(lostAmount, game, source);
return true;
}
@Override
public ServantOfTymaretEffect copy() {
return new ServantOfTymaretEffect(this);
}
}

View file

@ -1,14 +1,11 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.game.Game;
import java.util.UUID;
@ -20,9 +17,8 @@ public final class Subversion extends CardImpl {
public Subversion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
// At the beginning of your upkeep, each opponent loses 1 life. You gain life equal to the life lost this way.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SubversionEffect(), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsYouGainLifeLostEffect(1), TargetController.YOU, false));
}
private Subversion(final Subversion card) {
@ -34,32 +30,4 @@ public final class Subversion extends CardImpl {
return new Subversion(this);
}
static class SubversionEffect extends OneShotEffect {
public SubversionEffect() {
super(Outcome.Damage);
staticText = "each opponent loses 1 life. You gain life equal to the life lost this way";
}
private SubversionEffect(final SubversionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int damage = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
damage += game.getPlayer(opponentId).damage(1, source.getSourceId(), source, game);
}
game.getPlayer(source.getControllerId()).gainLife(damage, game, source);
return true;
}
@Override
public SubversionEffect copy() {
return new SubversionEffect(this);
}
}
}

View file

@ -1,18 +1,15 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsYouGainLifeLostEffect;
import mage.abilities.keyword.HeroicAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.game.Game;
import java.util.UUID;
/**
*
@ -31,7 +28,7 @@ public final class TormentedHero extends CardImpl {
// Tormented Hero enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// Heroic - Whenever you cast a spell that targets Tormented Hero, each opponent loses 1 life. You gain life equal to the life lost this way.
this.addAbility(new HeroicAbility(new EachOpponentLosesYouGainSumLifeEffect()));
this.addAbility(new HeroicAbility(new LoseLifeOpponentsYouGainLifeLostEffect(1)));
}
private TormentedHero(final TormentedHero card) {
@ -43,31 +40,3 @@ public final class TormentedHero extends CardImpl {
return new TormentedHero(this);
}
}
class EachOpponentLosesYouGainSumLifeEffect extends OneShotEffect {
EachOpponentLosesYouGainSumLifeEffect() {
super(Outcome.Damage);
staticText = "Each opponent loses 1 life. You gain life equal to the life lost this way";
}
private EachOpponentLosesYouGainSumLifeEffect(final EachOpponentLosesYouGainSumLifeEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int lostLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
lostLife += game.getPlayer(opponentId).loseLife(1, game, source, false);
}
game.getPlayer(source.getControllerId()).gainLife(lostLife, game, source);
return true;
}
@Override
public EachOpponentLosesYouGainSumLifeEffect copy() {
return new EachOpponentLosesYouGainSumLifeEffect(this);
}
}

View file

@ -0,0 +1,42 @@
package org.mage.test.cards.single.ths;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase;
/**
* @author xenohedron
*/
public class GrayMerchantOfAsphodelTest extends CardTestMultiPlayerBase {
@Test
public void testDevotionLifeDrain() {
String gary = "Gray Merchant of Asphodel";
// When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life,
// where X is your devotion to black. You gain life equal to the life lost this way.
addCard(Zone.HAND, playerA, gary, 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, gary); // 2 life lost, total 8 gained
checkLife("", 1, PhaseStep.BEGIN_COMBAT, playerB, 18);
checkLife("", 1, PhaseStep.BEGIN_COMBAT, playerC, 20); // not in range
checkLife("", 1, PhaseStep.BEGIN_COMBAT, playerD, 18);
checkLife("", 1, PhaseStep.BEGIN_COMBAT, playerA, 24);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, gary); // 4 life lost, total 8 gained
setStrictChooseMode(true);
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertLife(playerB, 14);
assertLife(playerC, 20);
assertLife(playerD, 14);
assertLife(playerA, 32);
assertPermanentCount(playerA, gary, 2);
}
}

View file

@ -0,0 +1,63 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
import java.util.Objects;
/**
* @author xenohedron
*/
public class LoseLifeOpponentsYouGainLifeLostEffect extends OneShotEffect {
private final DynamicValue amount;
public LoseLifeOpponentsYouGainLifeLostEffect(int amount) {
this(StaticValue.get(amount), amount + " life");
}
public LoseLifeOpponentsYouGainLifeLostEffect(DynamicValue amount, String amountLifeText) {
super(Outcome.GainLife);
this.amount = amount;
staticText = "each opponent loses " + amountLifeText + ". You gain life equal to the life lost this way";
}
protected LoseLifeOpponentsYouGainLifeLostEffect(final LoseLifeOpponentsYouGainLifeLostEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
int lifeToLose = amount.calculate(game, source, this);
if (lifeToLose < 1) {
return true;
}
int totalLifeLost = game
.getOpponents(source.getControllerId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.mapToInt(opponent -> opponent.loseLife(lifeToLose, game, source, false))
.sum();
if (totalLifeLost > 1) {
controller.gainLife(totalLifeLost, game, source);
}
return true;
}
@Override
public LoseLifeOpponentsYouGainLifeLostEffect copy() {
return new LoseLifeOpponentsYouGainLifeLostEffect(this);
}
}