diff --git a/Mage.Sets/src/mage/cards/a/AjanisAid.java b/Mage.Sets/src/mage/cards/a/AjanisAid.java index 51c07ba7b8e..d3869aadd9a 100644 --- a/Mage.Sets/src/mage/cards/a/AjanisAid.java +++ b/Mage.Sets/src/mage/cards/a/AjanisAid.java @@ -1,24 +1,22 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventDamageByChosenSourceEffect; import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.NamePredicate; +import java.util.UUID; + /** - * * @author fireshoes */ public final class AjanisAid extends CardImpl { @@ -37,8 +35,7 @@ public final class AjanisAid extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutInHandEffect(filter), true)); // Sacrifice Ajani's Aid: Prevent all combat damage a creature of your choice would deal this turn. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, new FilterCreaturePermanent("creature of your choice"), true); - effect.setText("Prevent all combat damage a creature of your choice would deal this turn"); + Effect effect = new PreventDamageByChosenSourceEffect(new FilterCreaturePermanent("creature of your choice"), true); this.addAbility(new SimpleActivatedAbility(effect, new SacrificeSourceCost())); } diff --git a/Mage.Sets/src/mage/cards/b/BoneMask.java b/Mage.Sets/src/mage/cards/b/BoneMask.java index 574a6c78eaf..5a18b1de750 100644 --- a/Mage.Sets/src/mage/cards/b/BoneMask.java +++ b/Mage.Sets/src/mage/cards/b/BoneMask.java @@ -1,27 +1,26 @@ package mage.cards.b; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.PreventionEffectData; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; import mage.target.TargetSource; +import java.util.Set; +import java.util.UUID; + /** - * * @author awjackson */ public final class BoneMask extends CardImpl { @@ -29,8 +28,14 @@ public final class BoneMask extends CardImpl { public BoneMask(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); - // {2}, {tap}: The next time a source of your choice would deal damage to you this turn, prevent that damage. Exile cards from the top of your library equal to the damage prevented this way. - Ability ability = new SimpleActivatedAbility(new BoneMaskEffect(), new GenericManaCost(2)); + // {2}, {T}: The next time a source of your choice would deal damage to you this turn, prevent that damage. Exile cards from the top of your library equal to the damage prevented this way. + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + BoneMaskEffectPreventionApplier.instance + ), + new GenericManaCost(2) + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -45,54 +50,24 @@ public final class BoneMask extends CardImpl { } } -class BoneMaskEffect extends PreventionEffectImpl { +enum BoneMaskEffectPreventionApplier implements PreventNextDamageFromChosenSourceEffect.ApplierOnPrevention { + instance; - private final TargetSource target; - - public BoneMaskEffect() { - super(Duration.EndOfTurn); - this.staticText = "The next time a source of your choice would deal damage to you this turn, prevent that damage. " - + "Exile cards from the top of your library equal to the damage prevented this way."; - this.target = new TargetSource(); - } - - private BoneMaskEffect(final BoneMaskEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public BoneMaskEffect copy() { - return new BoneMaskEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventionData = preventDamageAction(event, source, game); - this.used = true; - this.discard(); - if (preventionData.getPreventedDamage() > 0) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Set cards = controller.getLibrary().getTopCards(game, preventionData.getPreventedDamage()); - controller.moveCards(cards, Zone.EXILED, source, game); - } + public boolean apply(PreventionEffectData data, TargetSource targetSource, GameEvent event, Ability source, Game game) { + if (data == null || data.getPreventedDamage() <= 0) { + return false; } - return false; + int prevented = data.getPreventedDamage(); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Set cards = controller.getLibrary().getTopCards(game, prevented); + controller.moveCards(cards, Zone.EXILED, source, game); + return true; } - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return (!this.used - && super.applies(event, source, game) - && event.getTargetId().equals(source.getControllerId()) - && event.getSourceId().equals(target.getFirstTarget()) - ); + public String getText() { + return "Exile cards from the top of your library equal to the damage prevented this way"; } } diff --git a/Mage.Sets/src/mage/cards/b/BurrentonForgeTender.java b/Mage.Sets/src/mage/cards/b/BurrentonForgeTender.java index 3723515c746..330537dd312 100644 --- a/Mage.Sets/src/mage/cards/b/BurrentonForgeTender.java +++ b/Mage.Sets/src/mage/cards/b/BurrentonForgeTender.java @@ -1,23 +1,22 @@ package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.effects.common.PreventDamageBySourceEffect; +import mage.abilities.effects.common.PreventDamageByChosenSourceEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class BurrentonForgeTender extends CardImpl { @@ -29,7 +28,7 @@ public final class BurrentonForgeTender extends CardImpl { } public BurrentonForgeTender(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.KITHKIN, SubType.WIZARD); this.power = new MageInt(1); @@ -37,9 +36,9 @@ public final class BurrentonForgeTender extends CardImpl { // Protection from red this.addAbility(ProtectionAbility.from(ObjectColor.RED)); - + // Sacrifice Burrenton Forge-Tender: Prevent all damage a red source of your choice would deal this turn. - this.addAbility(new SimpleActivatedAbility( new PreventDamageBySourceEffect(filterObject), new SacrificeSourceCost())); + this.addAbility(new SimpleActivatedAbility(new PreventDamageByChosenSourceEffect(filterObject), new SacrificeSourceCost())); } diff --git a/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java b/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java index 664608f5dba..fed16f93fde 100644 --- a/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java +++ b/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java @@ -1,42 +1,41 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.PreventionEffectData; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.TargetSource; +import mage.constants.SubType; + +import java.util.UUID; /** - * * @author anonymous */ public final class ChoArrimAlchemist extends CardImpl { public ChoArrimAlchemist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SPELLSHAPER); this.power = new MageInt(1); this.toughness = new MageInt(1); - // {1}{W}{W}, {tap}, Discard a card: 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. - Ability ability = new SimpleActivatedAbility(new ChoArrimAlchemistEffect(), new ManaCostsImpl<>("{1}{W}{W}")); + // {1}{W}{W}, {T}, Discard a card: 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. + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + PreventNextDamageFromChosenSourceEffect.ON_PREVENT_YOU_GAIN_THAT_MUCH_LIFE + ), + new ManaCostsImpl<>("{1}{W}{W}") + ); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); this.addAbility(ability); @@ -50,55 +49,4 @@ public final class ChoArrimAlchemist extends CardImpl { public ChoArrimAlchemist copy() { return new ChoArrimAlchemist(this); } -} - -class ChoArrimAlchemistEffect extends PreventionEffectImpl { - - private final TargetSource target; - - public ChoArrimAlchemistEffect() { - super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); - 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."; - this.target = new TargetSource(); - } - - private ChoArrimAlchemistEffect(final ChoArrimAlchemistEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public ChoArrimAlchemistEffect copy() { - return new ChoArrimAlchemistEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventionData = preventDamageAction(event, source, game); - this.used = true; - this.discard(); // only one use - if (preventionData.getPreventedDamage() > 0) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.gainLife(preventionData.getPreventedDamage(), game, source); - } - } - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget())) { - return true; - } - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java index 9a73859f84f..8e81511bd6a 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java @@ -1,20 +1,19 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionArtifacts extends CardImpl { @@ -24,12 +23,12 @@ public final class CircleOfProtectionArtifacts extends CardImpl { static { filter.add(CardType.ARTIFACT.getPredicate()); } - + public CircleOfProtectionArtifacts(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {2}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{2}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java index a42b75122cf..5fd760f7cd6 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionBlack extends CardImpl { @@ -26,13 +25,13 @@ public final class CircleOfProtectionBlack extends CardImpl { static { filter.add(new ColorPredicate(ObjectColor.BLACK)); } - + public CircleOfProtectionBlack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a black source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java index 7a52cc659bd..cccfb199a99 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionBlue extends CardImpl { @@ -28,11 +27,11 @@ public final class CircleOfProtectionBlue extends CardImpl { } public CircleOfProtectionBlue(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a blue source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java index ab565226201..50c9b2e1228 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionGreen extends CardImpl { @@ -28,11 +27,11 @@ public final class CircleOfProtectionGreen extends CardImpl { } public CircleOfProtectionGreen(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a green source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java index 7ed4b49518e..c8b52163eed 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionRed extends CardImpl { @@ -28,11 +27,11 @@ public final class CircleOfProtectionRed extends CardImpl { } public CircleOfProtectionRed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a red source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java index 7eaa168dc64..aaa4e0e067b 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.ShadowAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; +import java.util.UUID; + /** - * * @author LoneFox */ public final class CircleOfProtectionShadow extends CardImpl { @@ -28,10 +27,10 @@ public final class CircleOfProtectionShadow extends CardImpl { } public CircleOfProtectionShadow(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); effect.setText("The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage"); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java index 39c6d8ae8bb..36420aa2994 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java @@ -1,22 +1,21 @@ package mage.cards.c; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Plopman */ public final class CircleOfProtectionWhite extends CardImpl { @@ -28,11 +27,11 @@ public final class CircleOfProtectionWhite extends CardImpl { } public CircleOfProtectionWhite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}: The next time a white source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/d/DeflectingPalm.java b/Mage.Sets/src/mage/cards/d/DeflectingPalm.java index a9f8bdccb89..0f9c4328d70 100644 --- a/Mage.Sets/src/mage/cards/d/DeflectingPalm.java +++ b/Mage.Sets/src/mage/cards/d/DeflectingPalm.java @@ -2,12 +2,11 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectData; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -24,7 +23,12 @@ public final class DeflectingPalm extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{W}"); // The next time a source of your choice would deal damage to you this turn, prevent that damage. If damage is prevented this way, Deflecting Palm deals that much damage to that source's controller. - this.getSpellAbility().addEffect(new DeflectingPalmEffect()); + this.getSpellAbility().addEffect( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + DeflectingPalmPreventionApplier.instance + ) + ); } private DeflectingPalm(final DeflectingPalm card) { @@ -37,56 +41,24 @@ public final class DeflectingPalm extends CardImpl { } } -class DeflectingPalmEffect extends PreventionEffectImpl { +enum DeflectingPalmPreventionApplier implements PreventNextDamageFromChosenSourceEffect.ApplierOnPrevention { + instance; - private final TargetSource target; - - DeflectingPalmEffect() { - super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); - this.staticText = "the next time a source of your choice would deal damage to you this turn, " + - "prevent that damage. If damage is prevented this way, " + - "{this} deals that much damage to that source's controller"; - this.target = new TargetSource(); - } - - private DeflectingPalmEffect(final DeflectingPalmEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public DeflectingPalmEffect copy() { - return new DeflectingPalmEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventionData = preventDamageAction(event, source, game); - this.used = true; - this.discard(); // only one use - if (preventionData.getPreventedDamage() < 1) { - return true; + public boolean apply(PreventionEffectData data, TargetSource targetSource, GameEvent event, Ability source, Game game) { + if (data == null || data.getPreventedDamage() <= 0) { + return false; } - UUID objectControllerId = game.getControllerId(target.getFirstTarget()); + int prevented = data.getPreventedDamage(); + UUID objectControllerId = game.getControllerId(targetSource.getFirstTarget()); Player objectController = game.getPlayer(objectControllerId); if (objectController == null) { - return true; + return false; } - objectController.damage(preventionData.getPreventedDamage(), source.getSourceId(), source, game); + objectController.damage(prevented, source.getSourceId(), source, game); return true; } - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return !this.used - && super.applies(event, source, game) - && event.getTargetId().equals(source.getControllerId()) - && event.getSourceId().equals(target.getFirstTarget()); + public String getText() { + return "If damage is prevented this way, {this} deals that much damage to that source's controller"; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GreaterRealmOfPreservation.java b/Mage.Sets/src/mage/cards/g/GreaterRealmOfPreservation.java index 74a405ba4ad..8ebb09bec90 100644 --- a/Mage.Sets/src/mage/cards/g/GreaterRealmOfPreservation.java +++ b/Mage.Sets/src/mage/cards/g/GreaterRealmOfPreservation.java @@ -1,38 +1,38 @@ package mage.cards.g; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author L_J */ public final class GreaterRealmOfPreservation extends CardImpl { private static final FilterObject filter = new FilterObject("black or red source"); - static{ + + static { filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLACK), new ColorPredicate(ObjectColor.RED))); } public GreaterRealmOfPreservation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {1}{W}: The next time a black or red source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}{W}"))); } diff --git a/Mage.Sets/src/mage/cards/h/HaazdaShieldMate.java b/Mage.Sets/src/mage/cards/h/HaazdaShieldMate.java index 3fb2048ceac..fd27b07966d 100644 --- a/Mage.Sets/src/mage/cards/h/HaazdaShieldMate.java +++ b/Mage.Sets/src/mage/cards/h/HaazdaShieldMate.java @@ -1,28 +1,27 @@ package mage.cards.h; -import java.util.UUID; import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; + +import java.util.UUID; /** - * * @author anonymous */ public final class HaazdaShieldMate extends CardImpl { public HaazdaShieldMate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(1); @@ -30,9 +29,9 @@ public final class HaazdaShieldMate extends CardImpl { // At the beginning of your upkeep, sacrifice Haazda Shield Mate unless you pay {W}{W}. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl<>("{W}{W}")))); - + // {W}: The next time a source of your choice would deal damage to you this turn, prevent that damage. - this.addAbility(new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{W}"))); + this.addAbility(new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true), new ManaCostsImpl<>("{W}"))); } private HaazdaShieldMate(final HaazdaShieldMate card) { diff --git a/Mage.Sets/src/mage/cards/i/InterventionPact.java b/Mage.Sets/src/mage/cards/i/InterventionPact.java index e51c05f3e85..433aca7b3b3 100644 --- a/Mage.Sets/src/mage/cards/i/InterventionPact.java +++ b/Mage.Sets/src/mage/cards/i/InterventionPact.java @@ -1,28 +1,17 @@ package mage.cards.i; -import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.common.delayed.PactDelayedTriggeredAbility; 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.PreventionEffectImpl; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetSource; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** - * * @author Plopman */ public final class InterventionPact extends CardImpl { @@ -33,7 +22,12 @@ public final class InterventionPact extends CardImpl { 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. - this.getSpellAbility().addEffect(new InterventionPactEffect()); + this.getSpellAbility().addEffect( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + PreventNextDamageFromChosenSourceEffect.ON_PREVENT_YOU_GAIN_THAT_MUCH_LIFE + ) + ); // 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)); } @@ -46,78 +40,4 @@ public final class InterventionPact extends CardImpl { public InterventionPact copy() { return new InterventionPact(this); } -} - -class InterventionPactEffect extends OneShotEffect { - - 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"; - } - - private 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.withNotTarget(true); - if (controller.chooseTarget(outcome, target, source, game)) { - ContinuousEffect continuousEffect = new InterventionPactPreventDamageEffect(); - continuousEffect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)); - game.addEffect(continuousEffect, source); - } - return true; - } - return false; - } -} - -class InterventionPactPreventDamageEffect extends PreventionEffectImpl { - - InterventionPactPreventDamageEffect() { - 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"; - } - - private InterventionPactPreventDamageEffect(final InterventionPactPreventDamageEffect effect) { - super(effect); - } - - @Override - public InterventionPactPreventDamageEffect copy() { - return new InterventionPactPreventDamageEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventEffectData = preventDamageAction(event, source, game); - if (preventEffectData.getPreventedDamage() > 0) { - used = true; - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.gainLife(preventEffectData.getPreventedDamage(), game, source); - } - } - return false; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game) && event.getTargetId().equals(source.getControllerId())) { - if (event.getSourceId().equals(getTargetPointer().getFirst(game, source))) { - return true; - } - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/i/Invulnerability.java b/Mage.Sets/src/mage/cards/i/Invulnerability.java index e1672b4dbb7..b3edd0d24e5 100644 --- a/Mage.Sets/src/mage/cards/i/Invulnerability.java +++ b/Mage.Sets/src/mage/cards/i/Invulnerability.java @@ -1,28 +1,28 @@ package mage.cards.i; -import java.util.UUID; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.BuybackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import java.util.UUID; + /** - * * @author anonymous */ public final class Invulnerability extends CardImpl { public Invulnerability(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Buyback {3} this.addAbility(new BuybackAbility("{3}")); - + // The next time a source of your choice would deal damage to you this turn, prevent that damage. - this.getSpellAbility().addEffect(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true)); } private Invulnerability(final Invulnerability card) { diff --git a/Mage.Sets/src/mage/cards/n/NewWayForward.java b/Mage.Sets/src/mage/cards/n/NewWayForward.java index 7b359e2b9ea..0d8bdfd7532 100644 --- a/Mage.Sets/src/mage/cards/n/NewWayForward.java +++ b/Mage.Sets/src/mage/cards/n/NewWayForward.java @@ -3,14 +3,13 @@ package mage.cards.n; import mage.abilities.Ability; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.effects.PreventionEffectData; -import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; import mage.target.TargetSource; @@ -27,7 +26,12 @@ public final class NewWayForward extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{R}{W}"); // The next time a source of your choice would deal damage to you this turn, prevent that damage. When damage is prevented this way, New Way Forward deals that much damage to that source's controller and you draw that many cards. - this.getSpellAbility().addEffect(new NewWayForwardEffect()); + this.getSpellAbility().addEffect( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + NewWayForwardPreventionApplier.instance + ) + ); } private NewWayForward(final NewWayForward card) { @@ -40,58 +44,26 @@ public final class NewWayForward extends CardImpl { } } -class NewWayForwardEffect extends PreventionEffectImpl { +enum NewWayForwardPreventionApplier implements PreventNextDamageFromChosenSourceEffect.ApplierOnPrevention { + instance; - private final TargetSource target; - - NewWayForwardEffect() { - super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); - this.staticText = "the next time a source of your choice would deal damage to you this turn, " + - "prevent that damage. When damage is prevented this way, " + - "{this} deals that much damage to that source's controller and you draw that many cards"; - this.target = new TargetSource(); - } - - private NewWayForwardEffect(final NewWayForwardEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public NewWayForwardEffect copy() { - return new NewWayForwardEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventionData = preventDamageAction(event, source, game); - this.used = true; - this.discard(); // only one use - if (preventionData.getPreventedDamage() < 1) { - return true; + public boolean apply(PreventionEffectData data, TargetSource targetSource, GameEvent event, Ability source, Game game) { + if (data == null || data.getPreventedDamage() <= 0) { + return false; } - UUID objectControllerId = game.getControllerId(target.getFirstTarget()); + int prevented = data.getPreventedDamage(); + UUID objectControllerId = game.getControllerId(targetSource.getFirstTarget()); ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new DamageTargetEffect(preventionData.getPreventedDamage()) + new DamageTargetEffect(prevented) .setTargetPointer(new FixedTarget(objectControllerId)), false ); - ability.addEffect(new DrawCardSourceControllerEffect(preventionData.getPreventedDamage())); + ability.addEffect(new DrawCardSourceControllerEffect(prevented)); game.fireReflexiveTriggeredAbility(ability, source); return true; } - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return !this.used - && super.applies(event, source, game) - && event.getTargetId().equals(source.getControllerId()) - && event.getSourceId().equals(target.getFirstTarget()); + public String getText() { + return "When damage is prevented this way, {this} deals that much damage to that source's controller and you draw that many cards"; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PayNoHeed.java b/Mage.Sets/src/mage/cards/p/PayNoHeed.java index ee3f33992cc..0b6b008e369 100644 --- a/Mage.Sets/src/mage/cards/p/PayNoHeed.java +++ b/Mage.Sets/src/mage/cards/p/PayNoHeed.java @@ -2,24 +2,24 @@ package mage.cards.p; import java.util.UUID; -import mage.abilities.effects.common.PreventDamageBySourceEffect; + +import mage.abilities.effects.common.PreventDamageByChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; /** - * * @author jeffwadsworth */ public final class PayNoHeed extends CardImpl { public PayNoHeed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Prevent all damage a source of your choice would deal this turn. - this.getSpellAbility().addEffect(new PreventDamageBySourceEffect()); - + this.getSpellAbility().addEffect(new PreventDamageByChosenSourceEffect()); + } private PayNoHeed(final PayNoHeed card) { diff --git a/Mage.Sets/src/mage/cards/p/Penance.java b/Mage.Sets/src/mage/cards/p/Penance.java index db6296fa3b1..dba57583455 100644 --- a/Mage.Sets/src/mage/cards/p/Penance.java +++ b/Mage.Sets/src/mage/cards/p/Penance.java @@ -1,34 +1,39 @@ package mage.cards.p; -import java.util.UUID; import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.PutCardFromHandOnTopOfLibraryCost; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.target.TargetSource; +import mage.filter.FilterObject; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class Penance extends CardImpl { + private static final FilterObject filter = new FilterObject("black or red source"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLACK), new ColorPredicate(ObjectColor.RED))); + } + public Penance(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Put a card from your hand on top of your library: The next time a black or red source of your choice would deal damage this turn, prevent that damage. - this.addAbility(new SimpleActivatedAbility(new PenanceEffect(), new PutCardFromHandOnTopOfLibraryCost())); - + this.addAbility(new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, false, filter), + new PutCardFromHandOnTopOfLibraryCost() + )); } private Penance(final Penance card) { @@ -39,49 +44,4 @@ public final class Penance extends CardImpl { public Penance copy() { return new Penance(this); } -} - -class PenanceEffect extends PreventionEffectImpl { - - private final TargetSource target; - - public PenanceEffect() { - super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); - this.staticText = "The next time a black or red source of your choice would deal damage this turn, prevent that damage."; - this.target = new TargetSource(); - } - - private PenanceEffect(final PenanceEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public PenanceEffect copy() { - return new PenanceEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - this.used = true; - this.discard(); // only one use - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - if (event.getSourceId().equals(target.getFirstTarget())) { - return (game.getObject(target.getFirstTarget()).getColor(game).contains(ObjectColor.BLACK) - || game.getObject(target.getFirstTarget()).getColor(game).contains(ObjectColor.RED)); - } - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PentagramOfTheAges.java b/Mage.Sets/src/mage/cards/p/PentagramOfTheAges.java index 5c3c1130f7d..11b08998a58 100644 --- a/Mage.Sets/src/mage/cards/p/PentagramOfTheAges.java +++ b/Mage.Sets/src/mage/cards/p/PentagramOfTheAges.java @@ -1,29 +1,28 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; + +import java.util.UUID; /** - * * @author Quercitron */ public final class PentagramOfTheAges extends CardImpl { public PentagramOfTheAges(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); - // {4}, {tap}: The next time a source of your choice would deal damage to you this turn, prevent that damage. - Ability ability = new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn), new GenericManaCost(4)); + // {4}, {T}: The next time a source of your choice would deal damage to you this turn, prevent that damage. + Ability ability = new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true), new GenericManaCost(4)); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java b/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java index e0355b3a919..50d3f014e82 100644 --- a/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java +++ b/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java @@ -6,19 +6,15 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.events.DamageEvent; -import mage.game.events.GameEvent; -import mage.game.events.PreventDamageEvent; -import mage.game.events.PreventedDamageEvent; -import mage.target.TargetSource; import java.util.UUID; @@ -27,6 +23,12 @@ import java.util.UUID; */ public final class PilgrimOfJustice extends CardImpl { + private static final FilterObject filter = new FilterObject("red source"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + public PilgrimOfJustice(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); @@ -38,7 +40,10 @@ public final class PilgrimOfJustice extends CardImpl { // Protection from red this.addAbility(ProtectionAbility.from(ObjectColor.RED)); // {W}, Sacrifice Pilgrim of Justice: The next time a red source of your choice would deal damage this turn, prevent that damage. - Ability ability = new SimpleActivatedAbility(new PilgrimOfJusticeEffect(), new ManaCostsImpl<>("{W}")); + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, false, filter), + new ManaCostsImpl<>("{W}") + ); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } @@ -51,60 +56,4 @@ public final class PilgrimOfJustice extends CardImpl { public PilgrimOfJustice copy() { return new PilgrimOfJustice(this); } -} - -class PilgrimOfJusticeEffect extends PreventionEffectImpl { - - private static final FilterObject filter = new FilterObject("red source"); - - static { - filter.add(new ColorPredicate(ObjectColor.RED)); - } - - private TargetSource target; - - public PilgrimOfJusticeEffect() { - super(Duration.EndOfTurn); - target = new TargetSource(filter); - - staticText = "The next time a red source of your choice would deal damage to you this turn, prevent that damage"; - } - - private PilgrimOfJusticeEffect(final PilgrimOfJusticeEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public PilgrimOfJusticeEffect copy() { - return new PilgrimOfJusticeEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage()); - if (!game.replaceEvent(preventEvent)) { - int damage = event.getAmount(); - event.setAmount(0); - this.used = true; // one time use - game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage)); - return true; - } - return false; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget()); - } - return false; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java b/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java index 74507f97418..57fa568fcf2 100644 --- a/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java +++ b/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java @@ -6,19 +6,15 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.events.DamageEvent; -import mage.game.events.GameEvent; -import mage.game.events.PreventDamageEvent; -import mage.game.events.PreventedDamageEvent; -import mage.target.TargetSource; import java.util.UUID; @@ -27,6 +23,12 @@ import java.util.UUID; */ public final class PilgrimOfVirtue extends CardImpl { + private static final FilterObject filter = new FilterObject("black source"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + public PilgrimOfVirtue(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); @@ -38,7 +40,10 @@ public final class PilgrimOfVirtue extends CardImpl { // Protection from black this.addAbility(ProtectionAbility.from(ObjectColor.BLACK)); // {W}, Sacrifice Pilgrim of Virtue: The next time a black source of your choice would deal damage this turn, prevent that damage. - Ability ability = new SimpleActivatedAbility(new PilgrimOfVirtueEffect(), new ManaCostsImpl<>("{W}")); + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, false, filter), + new ManaCostsImpl<>("{W}") + ); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } @@ -51,60 +56,4 @@ public final class PilgrimOfVirtue extends CardImpl { public PilgrimOfVirtue copy() { return new PilgrimOfVirtue(this); } -} - -class PilgrimOfVirtueEffect extends PreventionEffectImpl { - - private static final FilterObject filter = new FilterObject("black source"); - - static { - filter.add(new ColorPredicate(ObjectColor.BLACK)); - } - - private final TargetSource target; - - public PilgrimOfVirtueEffect() { - super(Duration.EndOfTurn); - target = new TargetSource(filter); - - staticText = "The next time a black source of your choice would deal damage to you this turn, prevent that damage"; - } - - private PilgrimOfVirtueEffect(final PilgrimOfVirtueEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public PilgrimOfVirtueEffect copy() { - return new PilgrimOfVirtueEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage()); - if (!game.replaceEvent(preventEvent)) { - int damage = event.getAmount(); - event.setAmount(0); - this.used = true; // one time use - game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage)); - return true; - } - return false; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget()); - } - return false; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PrahvSpiresOfOrder.java b/Mage.Sets/src/mage/cards/p/PrahvSpiresOfOrder.java index 5d2ab8b1010..bd031e3d675 100644 --- a/Mage.Sets/src/mage/cards/p/PrahvSpiresOfOrder.java +++ b/Mage.Sets/src/mage/cards/p/PrahvSpiresOfOrder.java @@ -2,31 +2,30 @@ package mage.cards.p; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PreventDamageBySourceEffect; +import mage.abilities.effects.common.PreventDamageByChosenSourceEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; /** - * * @author LevelX2 */ public final class PrahvSpiresOfOrder extends CardImpl { public PrahvSpiresOfOrder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); // {4}{W}{U}, {T}: Prevent all damage a source of your choice would deal this turn. - Ability ability = new SimpleActivatedAbility(new PreventDamageBySourceEffect(), new ManaCostsImpl<>("{4}{W}{U}")); + Ability ability = new SimpleActivatedAbility(new PreventDamageByChosenSourceEffect(), new ManaCostsImpl<>("{4}{W}{U}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/p/PrismaticCircle.java b/Mage.Sets/src/mage/cards/p/PrismaticCircle.java index 630f20e22a3..d2cbf98264f 100644 --- a/Mage.Sets/src/mage/cards/p/PrismaticCircle.java +++ b/Mage.Sets/src/mage/cards/p/PrismaticCircle.java @@ -1,27 +1,26 @@ package mage.cards.p; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ChooseColorEffect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CumulativeUpkeepAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class PrismaticCircle extends CardImpl { @@ -36,7 +35,10 @@ public final class PrismaticCircle extends CardImpl { this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // {1}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage. - this.addAbility(new SimpleActivatedAbility(new PrismaticCircleEffect(), new ManaCostsImpl<>("{1}"))); + this.addAbility(new SimpleActivatedAbility( + new PrismaticCircleEffect(), + new ManaCostsImpl<>("{1}") + )); } private PrismaticCircle(final PrismaticCircle card) { @@ -49,10 +51,11 @@ public final class PrismaticCircle extends CardImpl { } } -class PrismaticCircleEffect extends PreventNextDamageFromChosenSourceToYouEffect { +// TODO: create a FilterSource that can handle ChosenColorPredicate.TRUE and simplify this. +class PrismaticCircleEffect extends PreventNextDamageFromChosenSourceEffect { PrismaticCircleEffect() { - super(Duration.EndOfTurn); + super(Duration.EndOfTurn, true); staticText = "The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage."; } diff --git a/Mage.Sets/src/mage/cards/r/ReverseDamage.java b/Mage.Sets/src/mage/cards/r/ReverseDamage.java index 24ad5920abe..f38fcc05011 100644 --- a/Mage.Sets/src/mage/cards/r/ReverseDamage.java +++ b/Mage.Sets/src/mage/cards/r/ReverseDamage.java @@ -1,32 +1,30 @@ package mage.cards.r; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.PreventionEffectData; -import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.TargetSource; + +import java.util.UUID; /** - * * @author Quercitron */ public final class ReverseDamage extends CardImpl { public ReverseDamage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}{W}"); // 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 ReverseDamageEffect()); + this.getSpellAbility().addEffect( + new PreventNextDamageFromChosenSourceEffect( + Duration.EndOfTurn, true, + PreventNextDamageFromChosenSourceEffect.ON_PREVENT_YOU_GAIN_THAT_MUCH_LIFE + ) + ); } private ReverseDamage(final ReverseDamage card) { @@ -37,55 +35,4 @@ public final class ReverseDamage extends CardImpl { public ReverseDamage copy() { return new ReverseDamage(this); } -} - -class ReverseDamageEffect extends PreventionEffectImpl { - - private final TargetSource target; - - public ReverseDamageEffect() { - super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); - 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."; - this.target = new TargetSource(); - } - - private ReverseDamageEffect(final ReverseDamageEffect effect) { - super(effect); - this.target = effect.target.copy(); - } - - @Override - public ReverseDamageEffect copy() { - return new ReverseDamageEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - PreventionEffectData preventionData = preventDamageAction(event, source, game); - this.used = true; - this.discard(); // only one use - if (preventionData.getPreventedDamage() > 0) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.gainLife(preventionData.getPreventedDamage(), game, source); - } - } - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget())) { - return true; - } - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RhysticCircle.java b/Mage.Sets/src/mage/cards/r/RhysticCircle.java index 3be16bf322d..bfc1ed74086 100644 --- a/Mage.Sets/src/mage/cards/r/RhysticCircle.java +++ b/Mage.Sets/src/mage/cards/r/RhysticCircle.java @@ -1,31 +1,33 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; + +import java.util.UUID; /** - * * @author djbrez */ public final class RhysticCircle extends CardImpl { public RhysticCircle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // {1}: Any player may pay {1}. If no one does, the next time a source of your choice would deal damage to you this turn, prevent that damage. - this.addAbility(new SimpleActivatedAbility( - new DoUnlessAnyPlayerPaysEffect(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn),new GenericManaCost(1)), + this.addAbility(new SimpleActivatedAbility( + new DoUnlessAnyPlayerPaysEffect( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true), + new GenericManaCost(1) + ), new ManaCostsImpl<>("{1}"))); } diff --git a/Mage.Sets/src/mage/cards/r/RighteousAura.java b/Mage.Sets/src/mage/cards/r/RighteousAura.java index 68e05258df6..feb1b53a5df 100644 --- a/Mage.Sets/src/mage/cards/r/RighteousAura.java +++ b/Mage.Sets/src/mage/cards/r/RighteousAura.java @@ -1,29 +1,31 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; + +import java.util.UUID; /** - * * @author anonymous */ public final class RighteousAura extends CardImpl { public RighteousAura(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}, Pay 2 life: The next time a source of your choice would deal damage to you this turn, prevent that damage. - Ability ability = new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{W}")); + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true), + new ManaCostsImpl<>("{W}") + ); ability.addCost(new PayLifeCost(2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RithsCharm.java b/Mage.Sets/src/mage/cards/r/RithsCharm.java index fb2454ef123..6f5a3c61817 100644 --- a/Mage.Sets/src/mage/cards/r/RithsCharm.java +++ b/Mage.Sets/src/mage/cards/r/RithsCharm.java @@ -2,10 +2,11 @@ package mage.cards.r; import java.util.UUID; + import mage.abilities.Mode; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.PreventDamageBySourceEffect; +import mage.abilities.effects.common.PreventDamageByChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -13,13 +14,12 @@ import mage.game.permanent.token.SaprolingToken; import mage.target.common.TargetNonBasicLandPermanent; /** - * * @author FenrisulfrX */ public final class RithsCharm extends CardImpl { public RithsCharm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{G}{W}"); // Choose one - Destroy target nonbasic land; this.getSpellAbility().addEffect(new DestroyTargetEffect()); @@ -30,7 +30,7 @@ public final class RithsCharm extends CardImpl { this.getSpellAbility().addMode(mode); // or prevent all damage a source of your choice would deal this turn. - mode = new Mode(new PreventDamageBySourceEffect()); + mode = new Mode(new PreventDamageByChosenSourceEffect()); this.getSpellAbility().addMode(mode); } diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionArtifacts.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionArtifacts.java index b754410f49e..0ce84d6773f 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionArtifacts.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionArtifacts.java @@ -1,36 +1,36 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; +import java.util.UUID; + /** - * * @author fireshoes */ public final class RuneOfProtectionArtifacts extends CardImpl { private static final FilterObject filter = new FilterObject("artifact source"); + static { filter.add(CardType.ARTIFACT.getPredicate()); } public RuneOfProtectionArtifacts(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlack.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlack.java index ea231aaeb73..66c00fc55ed 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlack.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlack.java @@ -1,36 +1,38 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class RuneOfProtectionBlack extends CardImpl { private static final FilterObject filter = new FilterObject("black source"); + static { filter.add(new ColorPredicate(ObjectColor.BLACK)); } public RuneOfProtectionBlack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a black source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlue.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlue.java index 299bc336506..7357af2a1eb 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlue.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionBlue.java @@ -1,36 +1,38 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class RuneOfProtectionBlue extends CardImpl { private static final FilterObject filter = new FilterObject("blue source"); + static { filter.add(new ColorPredicate(ObjectColor.BLUE)); } public RuneOfProtectionBlue(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a blue source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionGreen.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionGreen.java index 17e83c87fa0..cbc1c1bca5f 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionGreen.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionGreen.java @@ -1,36 +1,38 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class RuneOfProtectionGreen extends CardImpl { private static final FilterObject filter = new FilterObject("green source"); + static { filter.add(new ColorPredicate(ObjectColor.GREEN)); } public RuneOfProtectionGreen(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a green source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionLands.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionLands.java index e620e0b7fa0..6a380ddf11f 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionLands.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionLands.java @@ -1,36 +1,36 @@ package mage.cards.r; -import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.FilterObject; +import java.util.UUID; + /** - * * @author fireshoes */ public final class RuneOfProtectionLands extends CardImpl { private static final FilterObject filter = new FilterObject("land source"); + static { filter.add(CardType.LAND.getPredicate()); } public RuneOfProtectionLands(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a land source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionRed.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionRed.java index 4af3ccfee3b..67298902764 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionRed.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionRed.java @@ -1,36 +1,38 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class RuneOfProtectionRed extends CardImpl { private static final FilterObject filter = new FilterObject("red source"); + static { filter.add(new ColorPredicate(ObjectColor.RED)); } public RuneOfProtectionRed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a red source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/r/RuneOfProtectionWhite.java b/Mage.Sets/src/mage/cards/r/RuneOfProtectionWhite.java index 2624dd6d2ff..85af0018656 100644 --- a/Mage.Sets/src/mage/cards/r/RuneOfProtectionWhite.java +++ b/Mage.Sets/src/mage/cards/r/RuneOfProtectionWhite.java @@ -1,36 +1,38 @@ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class RuneOfProtectionWhite extends CardImpl { private static final FilterObject filter = new FilterObject("white source"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); } public RuneOfProtectionWhite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // {W}: The next time a white source of your choice would deal damage to you this turn, prevent that damage. - Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter); + Effect effect = new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true, filter); this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{W}"))); // Cycling {2} ({2}, Discard this card: Draw a card.) this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/s/SeasonedTactician.java b/Mage.Sets/src/mage/cards/s/SeasonedTactician.java index 909dff399bb..92890863a14 100644 --- a/Mage.Sets/src/mage/cards/s/SeasonedTactician.java +++ b/Mage.Sets/src/mage/cards/s/SeasonedTactician.java @@ -1,37 +1,37 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ExileFromTopOfLibraryCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; + +import java.util.UUID; /** - * * @author LoneFox - */ public final class SeasonedTactician extends CardImpl { public SeasonedTactician(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ADVISOR); this.power = new MageInt(1); this.toughness = new MageInt(3); // {3}, Exile the top four cards of your library: The next time a source of your choice would deal damage to you this turn, prevent that damage. - Ability ability = new SimpleActivatedAbility(new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn), - new ManaCostsImpl<>("{3}")); + Ability ability = new SimpleActivatedAbility( + new PreventNextDamageFromChosenSourceEffect(Duration.EndOfTurn, true), + new ManaCostsImpl<>("{3}") + ); ability.addCost(new ExileFromTopOfLibraryCost(4)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StoryCircle.java b/Mage.Sets/src/mage/cards/s/StoryCircle.java index c39f8929f05..9ea12887807 100644 --- a/Mage.Sets/src/mage/cards/s/StoryCircle.java +++ b/Mage.Sets/src/mage/cards/s/StoryCircle.java @@ -1,38 +1,40 @@ package mage.cards.s; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ChooseColorEffect; -import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; import mage.filter.FilterObject; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; +import java.util.UUID; + /** - * * @author LoneFox */ public final class StoryCircle extends CardImpl { public StoryCircle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); // As Story Circle enters the battlefield, choose a color. this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // {W}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage. - this.addAbility(new SimpleActivatedAbility(new StoryCircleEffect(), new ManaCostsImpl<>("{W}"))); + this.addAbility(new SimpleActivatedAbility( + new StoryCircleEffect(), + new ManaCostsImpl<>("{W}") + )); } private StoryCircle(final StoryCircle card) { @@ -45,10 +47,11 @@ public final class StoryCircle extends CardImpl { } } -class StoryCircleEffect extends PreventNextDamageFromChosenSourceToYouEffect { +// TODO: create a FilterSource that can handle ChosenColorPredicate.TRUE and simplify this. +class StoryCircleEffect extends PreventNextDamageFromChosenSourceEffect { StoryCircleEffect() { - super(Duration.EndOfTurn); + super(Duration.EndOfTurn, true); staticText = "The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage."; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/aer/AjanisAidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/aer/AjanisAidTest.java new file mode 100644 index 00000000000..5534353c066 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/aer/AjanisAidTest.java @@ -0,0 +1,77 @@ +package org.mage.test.cards.single.aer; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class AjanisAidTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.a.AjanisAid Ajani's Aid} {2}{G}{W} + * Enchantment + * When this enchantment enters, you may search your library and/or graveyard for a card named Ajani, Valiant Protector, reveal it, and put it into your hand. If you search your library this way, shuffle. + * Sacrifice this enchantment: Prevent all combat damage a creature of your choice would deal this turn. + */ + private static final String aid = "Ajani's Aid"; + + @Test + public void test_DamageOnCreature_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, aid, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice"); + setChoice(playerA, "Goblin Piker"); // creature to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 0); + assertTapped("Goblin Piker", true); + assertGraveyardCount(playerA, aid, 1); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, aid, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTapped("Goblin Piker", true); + assertGraveyardCount(playerA, aid, 1); + } + + @Test + public void test_DamageNonCombat_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, aid, 1); + addCard(Zone.BATTLEFIELD, playerB, "Prodigal Pyromancer", 1); // {T}: This creature deals 1 damage to any target. + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice"); + setChoice(playerA, "Prodigal Pyromancer"); // source to prevent from + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: ", playerA); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20 - 1); + assertGraveyardCount(playerA, aid, 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/exo/PenanceTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/exo/PenanceTest.java new file mode 100644 index 00000000000..0b938b3f260 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/exo/PenanceTest.java @@ -0,0 +1,61 @@ +package org.mage.test.cards.single.exo; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class PenanceTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.p.Penance Penance} {2}{W} + * Enchantment + * Put a card from your hand on top of your library: The next time a black or red source of your choice would deal damage this turn, prevent that damage. + */ + private static final String penance = "Penance"; + + @Test + public void test_DamageOnCreature_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, penance, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.HAND, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Put a card"); + setChoice(playerA, "Plains"); // card to put on top + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 0); + assertTapped("Goblin Piker", true); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, penance, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.HAND, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Put a card"); + setChoice(playerA, "Plains"); // card to put on top + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTapped("Goblin Piker", true); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ktk/DeflectingPalmTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ktk/DeflectingPalmTest.java new file mode 100644 index 00000000000..50c424ce6c9 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ktk/DeflectingPalmTest.java @@ -0,0 +1,78 @@ +package org.mage.test.cards.single.ktk; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class DeflectingPalmTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.d.DeflectingPalm Deflecting Palm} {R}{W} + * Instant + * The next time a source of your choice would deal damage to you this turn, prevent that damage. If damage is prevented this way, Deflecting Palm deals that much damage to that source’s controller. + */ + private static final String palm = "Deflecting Palm"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.HAND, playerA, palm, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, palm); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertLife(playerB, 20); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, palm, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, palm); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20 - 2); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.HAND, playerA, palm, 1); + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, palm); + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); + assertLife(playerB, 20 - 2); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lea/CircleOfProtectionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lea/CircleOfProtectionTest.java new file mode 100644 index 00000000000..4753c845ccf --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lea/CircleOfProtectionTest.java @@ -0,0 +1,227 @@ +package org.mage.test.cards.single.lea; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class CircleOfProtectionTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.c.CircleOfProtectionRed Circle of Protection: Red} {1}{W} + * Enchantment + * {1}: The next time a red source of your choice would deal damage to you this turn, prevent that damage. + */ + private static final String circleRed = "Circle of Protection: Red"; + + /** + * {@link mage.cards.c.CircleOfProtectionGreen Circle of Protection: Green} {1}{W} + * Enchantment + * {1}: The next time a green source of your choice would deal damage to you this turn, prevent that damage. + */ + private static final String circleGreen = "Circle of Protection: Green"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 14); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertLife(playerB, 20); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}"); + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_NoSourceOfCircleColor_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleGreen, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}"); + // No possible choice for a green source + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); // no prevention + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_SpellDamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "Lightning Bolt"); + setChoice(playerA, "Lightning Bolt"); // source to prevent from + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_SpellNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleGreen, 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "Lightning Bolt"); + // no possible choice for "a green source" + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 3); + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_TriggerDamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.HAND, playerB, "Blisterstick Shaman", 1); // etb deals 1 to any target + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blisterstick Shaman"); + addTarget(playerB, playerA); // target for Shaman trigger + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "stack ability (When"); + setChoice(playerA, "Blisterstick Shaman"); // source to prevent from + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertPermanentCount(playerB, "Blisterstick Shaman", 1); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_TriggerNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleGreen, 1); + addCard(Zone.HAND, playerB, "Blisterstick Shaman", 1); // etb deals 1 to any target + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blisterstick Shaman"); + addTarget(playerB, playerA); // target for Shaman trigger + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "stack ability (When"); + // no possible choice for "a green source" + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 1); + assertPermanentCount(playerB, "Blisterstick Shaman", 1); + assertTappedCount("Plains", true, 1); + } + + @Test + public void test_ActivationDamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, circleRed, 1); + addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman", 1); // {R}, {T}: This creature deals 1 damage to any target. + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{R},", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "stack ability ({R}"); + setChoice(playerA, "Anaba Shaman"); // source to prevent from + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertTappedCount("Anaba Shaman", true, 1); + assertTappedCount("Plains", true, 1); + assertLife(playerA, 20); + } + + @Test + public void test_ActivationNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, circleGreen, 1); + addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman", 1); // {R}, {T}: This creature deals 1 damage to any target. + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{R},", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", null, "stack ability ({R}"); + // no possible choice for "a green source" + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertTappedCount("Anaba Shaman", true, 1); + assertTappedCount("Plains", true, 1); + assertLife(playerA, 20 - 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/BoneMaskTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/BoneMaskTest.java new file mode 100644 index 00000000000..2a0fe812f5e --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/BoneMaskTest.java @@ -0,0 +1,78 @@ +package org.mage.test.cards.single.mir; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class BoneMaskTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.b.BoneMask Bone Mask} {4} + * Artifact + * {2}, {T}: The next time a source of your choice would deal damage to you this turn, prevent that damage. Exile cards from the top of your library equal to the damage prevented this way. + */ + private static final String mask = "Bone Mask"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, mask, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertExileCount(playerA, 0); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, mask, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertExileCount(playerA, 2); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, mask, 1); + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}"); + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); + assertExileCount(playerA, 2); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/ChoArrimAlchemistTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/ChoArrimAlchemistTest.java new file mode 100644 index 00000000000..4b045c8acd1 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/ChoArrimAlchemistTest.java @@ -0,0 +1,86 @@ +package org.mage.test.cards.single.mmq; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class ChoArrimAlchemistTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.c.ChoArrimAlchemist Cho-Arrim Alchemist} {W} + * Creature — Human Spellshaper + * {1}{W}{W}, {T}, Discard a card: 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. + * 1/1 + */ + private static final String alchemist = "Cho-Arrim Alchemist"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, alchemist, 1); + addCard(Zone.HAND, playerA, "Lightning Bolt", 1); // to discard + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}{W}"); + setChoice(playerA, "Lightning Bolt"); // discard to activate + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertGraveyardCount(playerA, "Lightning Bolt", 1); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, alchemist, 1); + addCard(Zone.HAND, playerA, "Lightning Bolt", 1); // to discard + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}{W}"); + setChoice(playerA, "Lightning Bolt"); // discard to activate + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 + 2); + assertGraveyardCount(playerA, "Lightning Bolt", 1); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.BATTLEFIELD, playerA, alchemist, 1); + addCard(Zone.HAND, playerA, "Lightning Bolt", 1); // to discard + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}{W}"); + setChoice(playerA, "Lightning Bolt"); // discard to activate + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTapped("Blade Historian", true); + assertGraveyardCount(playerA, "Lightning Bolt", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/StoryCircleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/StoryCircleTest.java new file mode 100644 index 00000000000..cd45674ff1b --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mmq/StoryCircleTest.java @@ -0,0 +1,251 @@ +package org.mage.test.cards.single.mmq; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class StoryCircleTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.s.StoryCircle Story Circle} {1}{W}{W} + * Enchantment + * As this enchantment enters, choose a color. + * {W}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage. + */ + private static final String circle = "Story Circle"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertLife(playerB, 20); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_NoSourceOfChosenColor_NoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Green"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Goblin Piker"); // TODO: this should not be a valid choice for TargetSource(chosencolor) + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); // TODO: Should not prevent. + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_SpellDamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "Lightning Bolt"); + setChoice(playerA, "Lightning Bolt"); // source to prevent from + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_SpellNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Green"); // color chosen + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "Lightning Bolt"); + setChoice(playerA, "Lightning Bolt"); // TODO: this should not be a valid choice for TargetSource(chosencolor) + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); // TODO: Should not prevent. + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_TriggerDamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.HAND, playerB, "Blisterstick Shaman", 1); // etb deals 1 to any target + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blisterstick Shaman"); + addTarget(playerB, playerA); // target for Shaman trigger + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "stack ability (When"); + setChoice(playerA, "Blisterstick Shaman"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertPermanentCount(playerB, "Blisterstick Shaman", 1); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_TriggerNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.HAND, playerB, "Blisterstick Shaman", 1); // etb deals 1 to any target + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Green"); // color chosen + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blisterstick Shaman"); + addTarget(playerB, playerA); // target for Shaman trigger + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "stack ability (When"); + setChoice(playerA, "Blisterstick Shaman"); // TODO: this should not be a valid choice for TargetSource(chosencolor) + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); // TODO: Should not prevent. + assertPermanentCount(playerB, "Blisterstick Shaman", 1); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_ActivationDamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman", 1); // {R}, {T}: This creature deals 1 damage to any target. + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Red"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{R},", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "stack ability ({R}"); + setChoice(playerA, "Anaba Shaman"); // source to prevent from + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertTappedCount("Anaba Shaman", true, 1); + assertLife(playerA, 20); + assertTappedCount("Plains", true, 4); + } + + @Test + public void test_ActivationNotChosenColorDamageOnYou_NoPrevent() { + addCard(Zone.HAND, playerA, circle, 1); + addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman", 1); // {R}, {T}: This creature deals 1 damage to any target. + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, circle); + setChoice(playerA, "Green"); // color chosen + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{R},", playerA); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}", null, "stack ability ({R}"); + setChoice(playerA, "Anaba Shaman"); // TODO: this should not be a valid choice for TargetSource(chosencolor) + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertTappedCount("Anaba Shaman", true, 1); + assertLife(playerA, 20); // TODO: Should not prevent. + assertTappedCount("Plains", true, 4); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ody/PilgrimOfJusticeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ody/PilgrimOfJusticeTest.java new file mode 100644 index 00000000000..4753884ede7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ody/PilgrimOfJusticeTest.java @@ -0,0 +1,61 @@ +package org.mage.test.cards.single.ody; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class PilgrimOfJusticeTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.p.PilgrimOfJustice Pilgrim of Justice} {2}{W} + * Creature — Human Cleric + * Protection from red + * {W}, Sacrifice this creature: The next time a red source of your choice would deal damage this turn, prevent that damage. + * 1/3 + */ + private static final String pilgrim = "Pilgrim of Justice"; + + @Test + public void test_DamageOnCreature_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, pilgrim, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 0); + assertTapped("Goblin Piker", true); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.BATTLEFIELD, playerA, pilgrim, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{W}"); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertTapped("Goblin Piker", true); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/NewWayForwardTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/NewWayForwardTest.java new file mode 100644 index 00000000000..3c60fee8906 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/NewWayForwardTest.java @@ -0,0 +1,84 @@ +package org.mage.test.cards.single.tdm; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class NewWayForwardTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.n.NewWayForward New Way Forward} {2}{U}{R}{W} + * Instant + * The next time a source of your choice would deal damage to you this turn, prevent that damage. When damage is prevented this way, New Way Forward deals that much damage to that source’s controller and you draw that many cards. + */ + private static final String way = "New Way Forward"; + + @Test + public void test_DamageOnCreature_NoPrevent() { + addCard(Zone.HAND, playerA, way, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Caelorna, Coral Tyrant"); // 0/8 + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, way); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + block(2, playerA, "Caelorna, Coral Tyrant", "Goblin Piker"); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertDamageReceived(playerA, "Caelorna, Coral Tyrant", 2); // no prevent + assertLife(playerB, 20); + assertHandCount(playerA, 0); + } + + @Test + public void test_DamageOnYou_Prevent() { + addCard(Zone.HAND, playerA, way, 1); + addCard(Zone.BATTLEFIELD, playerB, "Goblin Piker", 1); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, way); + setChoice(playerA, "Goblin Piker"); // source to prevent from + + attack(2, playerB, "Goblin Piker", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20 - 2); + assertHandCount(playerA, 2); + } + + @Test + public void test_DoubleStrike_Prevent_ThenConsumedAndNoPrevent() { + addCard(Zone.HAND, playerA, way, 1); + addCard(Zone.BATTLEFIELD, playerB, "Blade Historian", 1); // 2/3 "Attacking creatures you control have double strike." + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, way); + setChoice(playerA, "Blade Historian"); // source to prevent from + + attack(2, playerB, "Blade Historian", playerA); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 - 2); + assertLife(playerB, 20 - 2); + assertHandCount(playerA, 2); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageBySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageByChosenSourceEffect.java similarity index 65% rename from Mage/src/main/java/mage/abilities/effects/common/PreventDamageBySourceEffect.java rename to Mage/src/main/java/mage/abilities/effects/common/PreventDamageByChosenSourceEffect.java index 2f254477516..c07f955cc2b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageBySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageByChosenSourceEffect.java @@ -16,33 +16,38 @@ import mage.target.TargetSource; * @author LevelX2 */ -public class PreventDamageBySourceEffect extends PreventionEffectImpl { +public class PreventDamageByChosenSourceEffect extends PreventionEffectImpl { private TargetSource target; private MageObjectReference mageObjectReference; - public PreventDamageBySourceEffect() { - this(new FilterObject("a")); + public PreventDamageByChosenSourceEffect() { + this(new FilterObject("a source")); } - public PreventDamageBySourceEffect(FilterObject filterObject) { - super(Duration.EndOfTurn); + public PreventDamageByChosenSourceEffect(FilterObject filterObject) { + this(filterObject, false); + } + + public PreventDamageByChosenSourceEffect(FilterObject filterObject, boolean onlyCombat) { + super(Duration.EndOfTurn, Integer.MAX_VALUE, onlyCombat); if (!filterObject.getMessage().endsWith("source")) { filterObject.setMessage(filterObject.getMessage() + " source"); } this.target = new TargetSource(filterObject); - staticText = "Prevent all damage " + filterObject.getMessage() + " of your choice would deal this turn"; + staticText = "Prevent all" + (onlyCombat ? " combat" : "") + + " damage " + filterObject.getMessage() + " of your choice would deal this turn"; } - protected PreventDamageBySourceEffect(final PreventDamageBySourceEffect effect) { + protected PreventDamageByChosenSourceEffect(final PreventDamageByChosenSourceEffect effect) { super(effect); this.target = effect.target.copy(); this.mageObjectReference = effect.mageObjectReference; } @Override - public PreventDamageBySourceEffect copy() { - return new PreventDamageBySourceEffect(this); + public PreventDamageByChosenSourceEffect copy() { + return new PreventDamageByChosenSourceEffect(this); } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceEffect.java new file mode 100644 index 00000000000..abdea7ebd8b --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceEffect.java @@ -0,0 +1,131 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.PreventionEffectData; +import mage.abilities.effects.PreventionEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterObject; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.TargetSource; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author Quercitron, Susucr + */ +public class PreventNextDamageFromChosenSourceEffect extends PreventionEffectImpl { + + protected final TargetSource targetSource; + private final boolean toYou; + private final ApplierOnPrevention onPrevention; + + public interface ApplierOnPrevention { + boolean apply(PreventionEffectData data, TargetSource targetsource, GameEvent event, Ability source, Game game); + + String getText(); + } + + public static ApplierOnPrevention ON_PREVENT_YOU_GAIN_THAT_MUCH_LIFE = new ApplierOnPrevention() { + public String getText() { + return "You gain life equal to the damage prevented this way"; + } + + public boolean apply(PreventionEffectData data, TargetSource targetSource, GameEvent event, Ability source, Game game) { + if (data == null || data.getPreventedDamage() <= 0) { + return false; + } + int prevented = data.getPreventedDamage(); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + controller.gainLife(prevented, game, source); + return true; + } + }; + + public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou) { + this(duration, toYou, new FilterObject("source")); + } + + public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter) { + this(duration, toYou, filter, false, null); + } + + public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, ApplierOnPrevention onPrevention) { + this(duration, toYou, new FilterObject("source"), onPrevention); + } + + public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter, ApplierOnPrevention onPrevention) { + this(duration, toYou, filter, false, onPrevention); + } + + public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter, boolean onlyCombat, ApplierOnPrevention onPrevention) { + super(duration, Integer.MAX_VALUE, onlyCombat); + this.targetSource = new TargetSource(filter); + this.toYou = toYou; + this.onPrevention = onPrevention; + this.staticText = setText(); + } + + protected PreventNextDamageFromChosenSourceEffect(final PreventNextDamageFromChosenSourceEffect effect) { + super(effect); + this.targetSource = effect.targetSource.copy(); + this.toYou = effect.toYou; + this.onPrevention = effect.onPrevention; + } + + @Override + public PreventNextDamageFromChosenSourceEffect copy() { + return new PreventNextDamageFromChosenSourceEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + UUID controllerId = source.getControllerId(); + if (this.targetSource.canChoose(controllerId, source, game)) { + this.targetSource.choose(Outcome.PreventDamage, controllerId, source.getSourceId(), source, game); + } + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + PreventionEffectData data = preventDamageAction(event, source, game); + this.used = true; + if (onPrevention != null) { + onPrevention.apply(data, targetSource, event, source, game); + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return !this.used + && super.applies(event, source, game) + && (!toYou || event.getTargetId().equals(source.getControllerId())) + && event.getSourceId().equals(targetSource.getFirstTarget()); + } + + private String setText() { + StringBuilder sb = new StringBuilder("The next time ") + .append(CardUtil.addArticle(targetSource.getFilter().getMessage())); + sb.append(" of your choice would deal damage"); + if (toYou) { + sb.append(" to you"); + } + if (duration == Duration.EndOfTurn) { + sb.append(" this turn"); + } + sb.append(", prevent that damage"); + if (onPrevention != null) { + sb.append(". ").append(onPrevention.getText()); + } + return sb.toString(); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToYouEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToYouEffect.java deleted file mode 100644 index 03ff1e1396a..00000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToYouEffect.java +++ /dev/null @@ -1,77 +0,0 @@ -package mage.abilities.effects.common; - -import mage.abilities.Ability; -import mage.abilities.effects.PreventionEffectImpl; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.filter.FilterObject; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.target.TargetSource; -import mage.util.CardUtil; - -/** - * @author Quercitron - */ -public class PreventNextDamageFromChosenSourceToYouEffect extends PreventionEffectImpl { - - protected final TargetSource targetSource; - - public PreventNextDamageFromChosenSourceToYouEffect(Duration duration) { - this(duration, new FilterObject("source")); - } - - public PreventNextDamageFromChosenSourceToYouEffect(Duration duration, FilterObject filter) { - this(duration, filter, false); - } - - public PreventNextDamageFromChosenSourceToYouEffect(Duration duration, FilterObject filter, boolean onlyCombat) { - super(duration, Integer.MAX_VALUE, onlyCombat); - this.targetSource = new TargetSource(filter); - this.staticText = setText(); - } - - protected PreventNextDamageFromChosenSourceToYouEffect(final PreventNextDamageFromChosenSourceToYouEffect effect) { - super(effect); - this.targetSource = effect.targetSource.copy(); - } - - @Override - public PreventNextDamageFromChosenSourceToYouEffect copy() { - return new PreventNextDamageFromChosenSourceToYouEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - this.targetSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - preventDamageAction(event, source, game); - this.used = true; - return false; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (!this.used && super.applies(event, source, game)) { - if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(targetSource.getFirstTarget())) { - return true; - } - } - return false; - } - - private String setText() { - StringBuilder sb = new StringBuilder("The next time ").append(CardUtil.addArticle(targetSource.getFilter().getMessage())); - sb.append(" of your choice would deal damage to you"); - if (duration == Duration.EndOfTurn) { - sb.append(" this turn"); - } - sb.append(", prevent that damage"); - return sb.toString(); - } - -}