Some fixes/changes to some prevention effects (e.g. select choice or source during resolution).

This commit is contained in:
LevelX2 2014-09-15 00:01:56 +02:00
parent d498df6a54
commit 95de1b1e30
3 changed files with 124 additions and 100 deletions

View file

@ -27,22 +27,20 @@
*/ */
package mage.sets.avacynrestored; package mage.sets.avacynrestored;
import mage.constants.CardType; import java.util.UUID;
import mage.constants.Rarity;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectData;
import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Rarity;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreatureOrPlayer;
import java.util.UUID;
/** /**
* @author noxx * @author noxx
*/ */
@ -56,7 +54,6 @@ public class DivineDeflection extends CardImpl {
// Prevent the next X damage that would be dealt to you and/or permanents you control this turn. If damage is prevented this way, Divine Deflection deals that much damage to target creature or player. // Prevent the next X damage that would be dealt to you and/or permanents you control this turn. If damage is prevented this way, Divine Deflection deals that much damage to target creature or player.
this.getSpellAbility().addEffect(new DivineDeflectionPreventDamageTargetEffect(Duration.EndOfTurn)); this.getSpellAbility().addEffect(new DivineDeflectionPreventDamageTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetSource());
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
} }
@ -72,16 +69,13 @@ public class DivineDeflection extends CardImpl {
class DivineDeflectionPreventDamageTargetEffect extends PreventionEffectImpl { class DivineDeflectionPreventDamageTargetEffect extends PreventionEffectImpl {
private int amount = -1;
public DivineDeflectionPreventDamageTargetEffect(Duration duration) { public DivineDeflectionPreventDamageTargetEffect(Duration duration) {
super(duration); super(duration, Integer.MIN_VALUE, false, true);
staticText = "Prevent the next X damage that would be dealt to you and/or permanents you control this turn. If damage is prevented this way, {this} deals that much damage to target creature or player"; staticText = "Prevent the next X damage that would be dealt to you and/or permanents you control this turn. If damage is prevented this way, {this} deals that much damage to target creature or player";
} }
public DivineDeflectionPreventDamageTargetEffect(final DivineDeflectionPreventDamageTargetEffect effect) { public DivineDeflectionPreventDamageTargetEffect(final DivineDeflectionPreventDamageTargetEffect effect) {
super(effect); super(effect);
this.amount = effect.amount;
} }
@Override @Override
@ -96,42 +90,48 @@ class DivineDeflectionPreventDamageTargetEffect extends PreventionEffectImpl {
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, event.getTargetId(), source.getSourceId(), source.getControllerId(), event.getAmount(), false); /*
if (!game.replaceEvent(preventEvent)) { If damage is dealt to multiple permanents you control, or is dealt to you and at least
if (amount == -1) { one permanent you control, you choose which of that damage to prevent if the chosen value
// define once for X won't prevent all the damage. For example, if 3 damage would be dealt to you and to
amount = source.getManaCostsToPay().getX(); each of two creatures you control, and Divine Deflection will prevent the next 3 damage,
} you might choose to prevent the next 2 damage it would deal to you and the next 1 damage
int prevented; it would deal to one of the creatures, among other choices. You don't decide until the
if (event.getAmount() >= this.amount) { point at which the damage would be dealt.
int damage = amount; TODO: Support to select which damage to prevent
event.setAmount(event.getAmount() - amount); */
this.used = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, event.getTargetId(), source.getSourceId(), source.getControllerId(), damage));
prevented = damage;
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, event.getTargetId(), source.getSourceId(), source.getControllerId(), damage));
prevented = damage;
}
// deal damage now PreventionEffectData preventionData = preventDamageAction(event, source, game);
if (prevented > 0) { /*
UUID redirectTo = source.getTargets().get(1).getFirstTarget(); Divine Deflection's effect is not a redirection effect. If it prevents damage,
Permanent permanent = game.getPermanent(redirectTo); Divine Deflection (not the original source) deals damage to the targeted creature
if (permanent != null) { or player as part of that prevention effect. Divine Deflection is the source of
game.informPlayers("Dealing " + prevented + " to " + permanent.getName() + " instead"); the new damage, so the characteristics of the original source (such as its color,
// keep the original source id as it is redirecting or whether it had lifelink or deathtouch) don't affect this damage. The new damage
permanent.damage(prevented, event.getSourceId(), game, false, true); is not combat damage, even if the prevented damage was. Since you control the source
} of the new damage, if you targeted an opponent with Divine Deflection, you may
Player player = game.getPlayer(redirectTo); have Divine Deflection deal its damage to a planeswalker that opponent controls.
if (player != null) { */
game.informPlayers("Dealing " + prevented + " to " + player.getName() + " instead"); // deal damage now
// keep the original source id as it is redirecting int prevented = preventionData.getPreventedDamage();
player.damage(prevented, event.getSourceId(), game, false, true); if (prevented > 0) {
} UUID dealDamageTo = source.getFirstTarget();
/*
Whether the targeted creature or player is still a legal target is not checked after
Divine Deflection resolves. For example, if a creature targeted by Divine Deflection
gains shroud after Divine Deflection resolves, Divine Deflection can still deal damage
to that creature.
*/
Permanent permanent = game.getPermanent(dealDamageTo);
if (permanent != null) {
game.informPlayers("Dealing " + prevented + " to " + permanent.getName() + " instead");
permanent.damage(prevented, source.getSourceId(), game, false, true);
}
Player player = game.getPlayer(dealDamageTo);
if (player != null) {
game.informPlayers("Dealing " + prevented + " to " + player.getName() + " instead");
player.damage(prevented, source.getSourceId(), game, false, true);
} }
} }
return false; return false;
@ -140,30 +140,18 @@ class DivineDeflectionPreventDamageTargetEffect extends PreventionEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) { if (!this.used && super.applies(event, source, game)) {
if (amountToPrevent == Integer.MIN_VALUE) {
// check source amountToPrevent = source.getManaCostsToPay().getX();
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
} }
if (!object.getId().equals(source.getFirstTarget())) {
return false;
}
// check target
// check permanent first // check permanent first
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) { if (permanent != null) {
if (permanent.getControllerId().equals(source.getControllerId())) { if (permanent.getControllerId().equals(source.getControllerId())) {
// it's your permanent
return true; return true;
} }
} }
// check player // check player
if (source.getControllerId().equals(event.getTargetId())) { if (source.getControllerId().equals(event.getTargetId())) {
// it is you
return true; return true;
} }
} }

View file

@ -27,25 +27,26 @@
*/ */
package mage.sets.darkascension; package mage.sets.darkascension;
import mage.constants.CardType; import java.util.UUID;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.common.FatefulHourCondition; import mage.abilities.condition.common.FatefulHourCondition;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continious.GainAbilityControlledEffect; import mage.abilities.effects.common.continious.GainAbilityControlledEffect;
import mage.abilities.effects.common.continious.GainAbilityControllerEffect;
import mage.abilities.effects.common.continious.GainProtectionFromColorTargetEffect; import mage.abilities.effects.common.continious.GainProtectionFromColorTargetEffect;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.choices.ChoiceColor; import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/** /**
* *
* @author BetaSteward * @author BetaSteward
@ -79,7 +80,8 @@ class FaithsShieldEffect extends OneShotEffect {
public FaithsShieldEffect() { public FaithsShieldEffect() {
super(Outcome.Protect); super(Outcome.Protect);
staticText = "Target permanent you control gains protection from the color of your choice until end of turn\nFateful hour - If you have 5 or less life, instead you and each permanent you control gain protection from the color of your choice until end of turn"; staticText = "Target permanent you control gains protection from the color of your choice until end of turn."
+ "<br/><br/><i>Fateful hour</i> - If you have 5 or less life, instead you and each permanent you control gain protection from the color of your choice until end of turn";
} }
public FaithsShieldEffect(final FaithsShieldEffect effect) { public FaithsShieldEffect(final FaithsShieldEffect effect) {
@ -88,19 +90,31 @@ class FaithsShieldEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
if (FatefulHourCondition.getInstance().apply(game, source)) { Player controller = game.getPlayer(source.getControllerId());
ChoiceColor choice = (ChoiceColor) source.getChoices().get(0); if (controller != null) {
FilterCard filter = new FilterCard(); if (FatefulHourCondition.getInstance().apply(game, source)) {
filter.add(new ColorPredicate(choice.getColor())); ChoiceColor choice = new ChoiceColor();
filter.setMessage(choice.getChoice()); while (!choice.isChosen()) {
controller.choose(Outcome.Protect, choice, game);
if (!controller.isInGame()) {
return false;
}
}
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(choice.getColor()));
filter.setMessage(choice.getChoice());
Ability ability = new ProtectionAbility(filter) ;
game.addEffect(new GainAbilityControlledEffect(ability, Duration.EndOfTurn), source);
game.addEffect(new GainAbilityControllerEffect(ability, Duration.EndOfTurn), source);
}
else {
game.addEffect(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), source);
}
return true;
Ability ability = new ProtectionAbility(filter) ;
game.addEffect(new GainAbilityControlledEffect(ability, Duration.EndOfTurn), source);
} }
else { return false;
game.addEffect(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), source);
}
return true;
} }
@Override @Override

View file

@ -32,17 +32,22 @@ import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.delayed.PactDelayedTriggeredAbility; import mage.abilities.common.delayed.PactDelayedTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.PreventionEffectData; import mage.abilities.effects.PreventionEffectData;
import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.players.Player; import mage.players.Player;
import mage.target.Target;
import mage.target.TargetSource; import mage.target.TargetSource;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -57,8 +62,7 @@ public class InterventionPact extends CardImpl {
this.color.setWhite(true); this.color.setWhite(true);
// The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way. // The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
this.getSpellAbility().addEffect(new InterventionPactPreventDamageEffect()); this.getSpellAbility().addEffect(new InterventionPactEffect());
this.getSpellAbility().addTarget(new TargetSource());
// At the beginning of your next upkeep, pay {1}{W}{W}. If you don't, you lose the game. // At the beginning of your next upkeep, pay {1}{W}{W}. If you don't, you lose the game.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new PactDelayedTriggeredAbility(new ManaCostsImpl("{1}{W}{W}")), false)); this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new PactDelayedTriggeredAbility(new ManaCostsImpl("{1}{W}{W}")), false));
} }
@ -73,12 +77,44 @@ public class InterventionPact extends CardImpl {
} }
} }
class InterventionPactEffect extends OneShotEffect {
public InterventionPactEffect() {
super(Outcome.PreventDamage);
this.staticText = "The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way";
}
public InterventionPactEffect(final InterventionPactEffect effect) {
super(effect);
}
@Override
public InterventionPactEffect copy() {
return new InterventionPactEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetSource();
target.setRequired(true);
target.setNotTarget(true);
if (controller.chooseTarget(outcome, target, source, game)) {
ContinuousEffect continuousEffect = new InterventionPactPreventDamageEffect();
continuousEffect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
game.addEffect(continuousEffect, source);
}
return true;
}
return false;
}
}
class InterventionPactPreventDamageEffect extends PreventionEffectImpl { class InterventionPactPreventDamageEffect extends PreventionEffectImpl {
public InterventionPactPreventDamageEffect() { public InterventionPactPreventDamageEffect() {
super(Duration.EndOfTurn); super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false);
staticText = "The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way"; staticText = "The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way";
} }
@ -100,6 +136,7 @@ class InterventionPactPreventDamageEffect extends PreventionEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
PreventionEffectData preventEffectData = preventDamageAction(event, source, game); PreventionEffectData preventEffectData = preventDamageAction(event, source, game);
if (preventEffectData.getPreventedDamage() > 0) { if (preventEffectData.getPreventedDamage() > 0) {
used = true;
Player player = game .getPlayer(source.getControllerId()); Player player = game .getPlayer(source.getControllerId());
if(player != null){ if(player != null){
player.gainLife(preventEffectData.getPreventedDamage(), game); player.gainLife(preventEffectData.getPreventedDamage(), game);
@ -110,24 +147,9 @@ class InterventionPactPreventDamageEffect extends PreventionEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) { if (!this.used && super.applies(event, source, game) && event.getTargetId().equals(source.getControllerId())) {
if (event.getSourceId().equals(getTargetPointer().getFirst(game, source))) {
return true;
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
}
if (!object.getId().equals(source.getFirstTarget())) {
return false;
}
Player player = game.getPlayer(event.getTargetId());
if (player != null) {
if (player.getId().equals(source.getControllerId())) {
return true;
}
} }
} }
return false; return false;