fixed implementation of Drain Life and Soul Burn to reflect current rules

This commit is contained in:
Evan Kranzler 2019-01-23 16:31:56 -05:00
parent d25bca748d
commit 3a85349b48
3 changed files with 105 additions and 123 deletions

View file

@ -1,49 +1,52 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.Ability;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.InfoEffect;
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.Outcome; import mage.constants.Zone;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/** /**
* @author nantuko * @author nantuko
*/ */
public final class ConsumeSpirit extends CardImpl { public final class ConsumeSpirit extends CardImpl {
static final FilterMana filterBlack = new FilterMana(); private static final FilterMana filterBlack = new FilterMana();
static { static {
filterBlack.setBlack(true); filterBlack.setBlack(true);
} }
public ConsumeSpirit(UUID ownerId, CardSetInfo setInfo) { public ConsumeSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{1}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
// Spend only black mana on X. // Spend only black mana on X.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new InfoEffect("Spend only black mana on X")).setRuleAtTheTop(true)
);
// Consume Spirit deals X damage to any target and you gain X life. // Consume Spirit deals X damage to any target and you gain X life.
this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new ConsumeSpiritEffect()); this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance).concatBy("and"));
VariableCost variableCost = this.getSpellAbility().getManaCostsToPay().getVariableCosts().get(0); VariableCost variableCost = this.getSpellAbility().getManaCostsToPay().getVariableCosts().get(0);
if (variableCost instanceof VariableManaCost) { if (variableCost instanceof VariableManaCost) {
((VariableManaCost) variableCost).setFilter(filterBlack); ((VariableManaCost) variableCost).setFilter(filterBlack);
} }
} }
public ConsumeSpirit(final ConsumeSpirit card) { private ConsumeSpirit(final ConsumeSpirit card) {
super(card); super(card);
} }
@ -52,46 +55,3 @@ public final class ConsumeSpirit extends CardImpl {
return new ConsumeSpirit(this); return new ConsumeSpirit(this);
} }
} }
class ConsumeSpiritEffect extends OneShotEffect {
public ConsumeSpiritEffect() {
super(Outcome.Damage);
staticText = "Consume Spirit deals X damage to any target and you gain X life. Spend only black mana on X";
}
public ConsumeSpiritEffect(final ConsumeSpiritEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int amount = source.getManaCostsToPay().getX();
if (amount > 0) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
permanent.damage(amount, source.getSourceId(), game, false, true);
} else {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) {
player.damage(amount, source.getSourceId(), game, false, true);
} else {
return false;
}
}
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(amount, game, source);
} else {
return false;
}
}
return true;
}
@Override
public ConsumeSpiritEffect copy() {
return new ConsumeSpiritEffect(this);
}
}

View file

@ -1,29 +1,32 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
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.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/** /**
*
* @author KholdFuzion * @author KholdFuzion
*
*/ */
public final class DrainLife extends CardImpl { public final class DrainLife extends CardImpl {
static final FilterMana filterBlack = new FilterMana(); private static final FilterMana filterBlack = new FilterMana();
static { static {
filterBlack.setBlack(true); filterBlack.setBlack(true);
@ -33,6 +36,10 @@ public final class DrainLife extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
// Spend only black mana on X. // Spend only black mana on X.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new InfoEffect("Spend only black mana on X")).setRuleAtTheTop(true)
);
// Drain Life deals X damage to any target. You gain life equal to the damage dealt, but not more life than the player's life total before Drain Life dealt damage or the creature's toughness. // Drain Life deals X damage to any target. You gain life equal to the damage dealt, but not more life than the player's life total before Drain Life dealt damage or the creature's toughness.
this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new DrainLifeEffect()); this.getSpellAbility().addEffect(new DrainLifeEffect());
@ -42,7 +49,7 @@ public final class DrainLife extends CardImpl {
} }
} }
public DrainLife(final DrainLife card) { private DrainLife(final DrainLife card) {
super(card); super(card);
} }
@ -54,12 +61,14 @@ public final class DrainLife extends CardImpl {
class DrainLifeEffect extends OneShotEffect { class DrainLifeEffect extends OneShotEffect {
public DrainLifeEffect() { DrainLifeEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "Spend only black mana on X.<br>{this} deals X damage to any target. You gain life equal to the damage dealt, but not more life than the player's life total before Drain Life dealt damage or the creature's toughness"; staticText = "{this} deals X damage to any target. You gain life equal to the damage dealt, " +
"but not more life than the players life total before the damage was dealt, " +
"the planeswalkers loyalty before the damage was dealt, or the creatures toughness.";
} }
public DrainLifeEffect(final DrainLifeEffect effect) { private DrainLifeEffect(final DrainLifeEffect effect) {
super(effect); super(effect);
} }
@ -67,31 +76,32 @@ class DrainLifeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
int amount = source.getManaCostsToPay().getX(); int amount = source.getManaCostsToPay().getX();
int lifetogain = amount; int lifetogain = amount;
if (amount > 0) { if (amount == 0) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); return true;
if (permanent != null) { }
if (permanent.getToughness().getValue() < amount) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
lifetogain = permanent.getToughness().getValue(); if (permanent != null) {
} if (permanent.isCreature()) {
permanent.damage(amount, source.getSourceId(), game, false, true); lifetogain = Math.min(permanent.getToughness().getValue(), lifetogain);
} else { } else if (permanent.isPlaneswalker()) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); lifetogain = Math.min(permanent.getCounters(game).getCount(CounterType.LOYALTY), lifetogain);
if (player != null) {
if (player.getLife() < amount) {
lifetogain = player.getLife();
}
player.damage(amount, source.getSourceId(), game, false, true);
} else {
return false;
}
}
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(lifetogain, game, source);
} else { } else {
return false; return false;
} }
permanent.damage(amount, source.getSourceId(), game);
} else {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player == null) {
return false;
}
lifetogain = Math.min(player.getLife(), lifetogain);
player.damage(amount, source.getSourceId(), game);
} }
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
controller.gainLife(lifetogain, game, source);
return true; return true;
} }

View file

@ -1,27 +1,32 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
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.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/** /**
* @author Johnny E. Hastings * @author Johnny E. Hastings
*/ */
public final class SoulBurn extends CardImpl { public final class SoulBurn extends CardImpl {
static final FilterMana filterBlackOrRed = new FilterMana(); private static final FilterMana filterBlackOrRed = new FilterMana();
static { static {
filterBlackOrRed.setBlack(true); filterBlackOrRed.setBlack(true);
@ -29,9 +34,13 @@ public final class SoulBurn extends CardImpl {
} }
public SoulBurn(UUID ownerId, CardSetInfo setInfo) { public SoulBurn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{2}{B}");
// Spend only black or red mana on X. // Spend only black or red mana on X.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new InfoEffect("Spend only black or red mana on X")).setRuleAtTheTop(true)
);
// Soul Burn deals X damage to any target. You gain life equal to the damage dealt for each black mana spent on X; not more life than the player's life total before Soul Burn dealt damage, or the creature's toughness. // Soul Burn deals X damage to any target. You gain life equal to the damage dealt for each black mana spent on X; not more life than the player's life total before Soul Burn dealt damage, or the creature's toughness.
this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new SoulBurnEffect()); this.getSpellAbility().addEffect(new SoulBurnEffect());
@ -41,7 +50,7 @@ public final class SoulBurn extends CardImpl {
} }
} }
public SoulBurn(final SoulBurn card) { private SoulBurn(final SoulBurn card) {
super(card); super(card);
} }
@ -53,33 +62,35 @@ public final class SoulBurn extends CardImpl {
class SoulBurnEffect extends OneShotEffect { class SoulBurnEffect extends OneShotEffect {
public SoulBurnEffect() { SoulBurnEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "{this} deals X damage to any target for each black or red mana spent on X. You gain life equal to the damage dealt for each black mana spent; not more life than the player's life total before Soul Burn dealt damage, or the creature's toughness."; staticText = "{this} deals X damage to any target. You gain life equal to the damage dealt, " +
"but not more than the amount of {B} spent on X, the players life total before the damage was dealt, " +
"the planeswalkers loyalty before the damage was dealt, or the creatures toughness.";
} }
public SoulBurnEffect(final SoulBurnEffect effect) { private SoulBurnEffect(final SoulBurnEffect effect) {
super(effect); super(effect);
} }
/*** /***
* @param game * @param game
* @param source * @param source
* @return * @return
*/ */
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
// Get the colors we care about. (This isn't racist, honestly.) // Get the colors we care about. (This isn't racist, honestly.)
int amountBlack = source.getManaCostsToPay().getPayment().getBlack(); int amountBlack = source.getManaCostsToPay().getPayment().getBlack();
int amountRed = source.getManaCostsToPay().getPayment().getRed(); int amountRed = source.getManaCostsToPay().getPayment().getRed();
// Get the colors we don't really care about. (See note above.) // Get the colors we don't really care about. (See note above.)
int amountWhite = source.getManaCostsToPay().getPayment().getWhite(); int amountWhite = source.getManaCostsToPay().getPayment().getWhite();
int amountGreen = source.getManaCostsToPay().getPayment().getGreen(); int amountGreen = source.getManaCostsToPay().getPayment().getGreen();
int amountBlue = source.getManaCostsToPay().getPayment().getBlue(); int amountBlue = source.getManaCostsToPay().getPayment().getBlue();
int amountColorless = source.getManaCostsToPay().getPayment().getColorless(); int amountColorless = source.getManaCostsToPay().getPayment().getColorless();
// Figure out what was spent on the spell in total, determine proper values for // Figure out what was spent on the spell in total, determine proper values for
// black and red, minus initial casting cost. // black and red, minus initial casting cost.
int totalColorlessForCastingCost = amountWhite + amountGreen + amountBlue + amountColorless; int totalColorlessForCastingCost = amountWhite + amountGreen + amountBlue + amountColorless;
@ -90,17 +101,17 @@ class SoulBurnEffect extends OneShotEffect {
// The game should never let this happen, but I'll check anyway since I don't know // The game should never let this happen, but I'll check anyway since I don't know
// the guts of the game [yet]. // the guts of the game [yet].
amountOffsetByColorless = 2; amountOffsetByColorless = 2;
} }
} }
// Remove 1 black to account for casting cost. // Remove 1 black to account for casting cost.
amountBlack--; amountBlack--;
// Determine if we need to offset the red or black values any further due to the // Determine if we need to offset the red or black values any further due to the
// amount of non-red and non-black paid. // amount of non-red and non-black paid.
if (amountOffsetByColorless < 2) { if (amountOffsetByColorless < 2) {
int amountToOffsetBy = 2 - amountOffsetByColorless; int amountToOffsetBy = 2 - amountOffsetByColorless;
if (amountRed > 0) { if (amountRed > 0) {
if (amountRed >= amountToOffsetBy) { if (amountRed >= amountToOffsetBy) {
// Pay all additional unpaid casting cost with red. // Pay all additional unpaid casting cost with red.
@ -118,35 +129,36 @@ class SoulBurnEffect extends OneShotEffect {
amountBlack = amountBlack - amountToOffsetBy; amountBlack = amountBlack - amountToOffsetBy;
} }
} }
int totalXAmount = amountBlack + amountRed; int totalXAmount = amountBlack + amountRed;
int lifetogain = amountBlack; int lifetogain = amountBlack;
if (totalXAmount > 0) { if (totalXAmount == 0) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); return false;
if (permanent != null ) { }
if (permanent.getToughness().getValue() < lifetogain) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
lifetogain = permanent.getToughness().getValue(); if (permanent != null) {
} if (permanent.isCreature()) {
permanent.damage(totalXAmount, source.getSourceId(), game, false, true); lifetogain = Math.min(permanent.getToughness().getValue(), lifetogain);
} else { } else if (permanent.isPlaneswalker()) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); lifetogain = Math.min(permanent.getCounters(game).getCount(CounterType.LOYALTY), lifetogain);
if (player != null) {
if (player.getLife() < lifetogain) {
lifetogain = player.getLife();
}
player.damage(totalXAmount, source.getSourceId(), game, false, true);
} else {
return false;
}
}
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(lifetogain, game, source);
} else { } else {
return false; return false;
} }
permanent.damage(totalXAmount, source.getSourceId(), game);
} else {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player == null) {
return false;
}
lifetogain = Math.min(player.getLife(), lifetogain);
player.damage(totalXAmount, source.getSourceId(), game);
} }
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
controller.gainLife(lifetogain, game, source);
return true; return true;
} }