Add new common effect class for Armored Transport, etc and fix #9614

This commit is contained in:
Alex W. Jackson 2022-10-11 22:48:02 -04:00
parent 17be0c11ba
commit 4bf01249a4
25 changed files with 359 additions and 809 deletions

View file

@ -1,21 +1,16 @@
package mage.cards.a;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.StaticFilters;
import java.util.UUID;
@ -24,12 +19,6 @@ import java.util.UUID;
*/
public final class ArgothianPixies extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creatures");
static {
filter.add(CardType.ARTIFACT.getPredicate());
}
public ArgothianPixies(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.FAERIE);
@ -37,13 +26,12 @@ public final class ArgothianPixies extends CardImpl {
this.toughness = new MageInt(1);
// Argothian Pixies can't be blocked by artifact creatures.
this.addAbility(new SimpleEvasionAbility(
new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(
StaticFilters.FILTER_PERMANENTS_ARTIFACT_CREATURE, Duration.WhileOnBattlefield)));
// Prevent all damage that would be dealt to Argothian Pixies by artifact creatures.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new ArgothianPixiesPreventDamageFromArtifactsEffect(Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(
StaticFilters.FILTER_PERMANENTS_ARTIFACT_CREATURE)));
}
private ArgothianPixies(final ArgothianPixies card) {
@ -55,31 +43,3 @@ public final class ArgothianPixies extends CardImpl {
return new ArgothianPixies(this);
}
}
class ArgothianPixiesPreventDamageFromArtifactsEffect extends PreventionEffectImpl {
public ArgothianPixiesPreventDamageFromArtifactsEffect(Duration duration) {
super(duration);
staticText = "Prevent all damage that would be dealt to {this} by artifact creatures";
}
public ArgothianPixiesPreventDamageFromArtifactsEffect(final ArgothianPixiesPreventDamageFromArtifactsEffect effect) {
super(effect);
}
@Override
public ArgothianPixiesPreventDamageFromArtifactsEffect copy() {
return new ArgothianPixiesPreventDamageFromArtifactsEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.getCardType(game).contains(CardType.ARTIFACT)) {
return (event.getTargetId().equals(source.getSourceId()));
}
}
return false;
}
}

View file

@ -10,7 +10,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -28,7 +27,7 @@ public final class ArgothianTreefolk extends CardImpl {
this.toughness = new MageInt(5);
// Prevent all damage that would be dealt to Argothian Treefolk by artifact sources.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageToSourceByCardTypeEffect(CardType.ARTIFACT)));
this.addAbility(new SimpleStaticAbility(new ArgothianTreefolkPreventionEffect()));
}
private ArgothianTreefolk(final ArgothianTreefolk card) {
@ -41,28 +40,29 @@ public final class ArgothianTreefolk extends CardImpl {
}
}
class PreventDamageToSourceByCardTypeEffect extends PreventAllDamageToSourceEffect {
// cannot use PreventAllDamageToSourceByPermanentsEffect: "artifact sources" not "artifacts"
class ArgothianTreefolkPreventionEffect extends PreventAllDamageToSourceEffect {
private CardType cardType;
public PreventDamageToSourceByCardTypeEffect() {
this(null);
public ArgothianTreefolkPreventionEffect() {
super(Duration.WhileOnBattlefield);
staticText = "prevent all damage that would be dealt to {this} by artifact sources";
}
public PreventDamageToSourceByCardTypeEffect(CardType cardT) {
super(Duration.WhileOnBattlefield);
staticText = "Prevent all damage that would be dealt to {this} by artifact sources";
cardType = cardT;
private ArgothianTreefolkPreventionEffect(final ArgothianTreefolkPreventionEffect effect) {
super(effect);
}
@Override
public ArgothianTreefolkPreventionEffect copy() {
return new ArgothianTreefolkPreventionEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.getCardType(game).contains(cardType)) {
return event.getTargetId().equals(source.getSourceId());
}
if (!super.applies(event, source, game)) {
return false;
}
return false;
MageObject sourceObject = game.getObject(event.getSourceId());
return sourceObject != null && sourceObject.isArtifact(game);
}
}
}

View file

@ -1,28 +1,28 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
/**
*
* @author LevelX2
* @author awjackson
*/
public final class ArmoredTransport extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures blocking it");
static {
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
}
public ArmoredTransport(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}");
this.subtype.add(SubType.CONSTRUCT);
@ -31,8 +31,7 @@ public final class ArmoredTransport extends CardImpl {
this.toughness = new MageInt(1);
// Prevent all combat damage that would be dealt to Armored Transport by creatures blocking it.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArmoredTransportPreventCombatDamageSourceEffect(Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter, true)));
}
private ArmoredTransport(final ArmoredTransport card) {
@ -44,34 +43,3 @@ public final class ArmoredTransport extends CardImpl {
return new ArmoredTransport(this);
}
}
class ArmoredTransportPreventCombatDamageSourceEffect extends PreventionEffectImpl {
public ArmoredTransportPreventCombatDamageSourceEffect(Duration duration) {
super(duration);
staticText = "Prevent all combat damage that would be dealt to {this} by creatures blocking it" + duration.toString();
}
public ArmoredTransportPreventCombatDamageSourceEffect(final ArmoredTransportPreventCombatDamageSourceEffect effect) {
super(effect);
}
@Override
public ArmoredTransportPreventCombatDamageSourceEffect copy() {
return new ArmoredTransportPreventCombatDamageSourceEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
DamageEvent damageEvent = (DamageEvent) event;
if (event.getTargetId().equals(source.getSourceId()) && damageEvent.isCombatDamage()) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null && sourcePermanent.isAttacking()) {
return true;
}
}
}
return false;
}
}

View file

@ -6,9 +6,8 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalReplacementEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
@ -16,7 +15,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
@ -26,16 +24,10 @@ import mage.target.Target;
/**
*
* @author L_J
* @author awjackson
*/
public final class BronzeHorse extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
public BronzeHorse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT, CardType.CREATURE},"{7}");
this.subtype.add(SubType.HORSE);
@ -44,11 +36,9 @@ public final class BronzeHorse extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// As long as you control another creature, prevent all damage that would be dealt to Bronze Horse by spells that target it.
Effect effect = new ConditionalReplacementEffect(new PreventDamageToSourceBySpellsThatTargetIt(), new PermanentsOnTheBattlefieldCondition(filter));
effect.setText("As long as you control another creature, prevent all damage that would be dealt to {this} by spells that target it.");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
this.addAbility(new SimpleStaticAbility(new BronzeHorsePreventionEffect()));
}
private BronzeHorse(final BronzeHorse card) {
@ -61,27 +51,43 @@ public final class BronzeHorse extends CardImpl {
}
}
class PreventDamageToSourceBySpellsThatTargetIt extends PreventAllDamageToSourceEffect {
class BronzeHorsePreventionEffect extends PreventAllDamageToSourceEffect {
public PreventDamageToSourceBySpellsThatTargetIt() {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
public BronzeHorsePreventionEffect() {
super(Duration.WhileOnBattlefield);
staticText = "as long as you control another creature, prevent all damage that would be dealt to {this} by spells that target it";
}
private BronzeHorsePreventionEffect(final BronzeHorsePreventionEffect effect) {
super(effect);
}
@Override
public BronzeHorsePreventionEffect copy() {
return new BronzeHorsePreventionEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (event.getTargetId().equals(source.getSourceId())) {
Spell spell = game.getStack().getSpell(event.getSourceId());
if (spell != null) {
for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) {
Mode mode = spell.getStackAbility().getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetId : target.getTargets()) {
if (targetId.equals(source.getSourceId())) {
return true;
}
}
}
if (!super.applies(event, source, game) || !condition.apply(game, source)) {
return false;
}
Spell spell = game.getStack().getSpell(event.getSourceId());
if (spell == null) {
return false;
}
for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) {
Mode mode = spell.getStackAbility().getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetId : target.getTargets()) {
if (targetId.equals(source.getSourceId())) {
return true;
}
}
}

View file

@ -1,20 +1,14 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.constants.SubType;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.constants.SubType;
import mage.filter.StaticFilters;
/**
*
@ -31,7 +25,7 @@ public final class ChampionLancer extends CardImpl {
this.toughness = new MageInt(3);
// Prevent all damage that would be dealt to Champion Lancer by creatures.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageToSourceByCardTypeEffect()));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(StaticFilters.FILTER_PERMANENT_CREATURES)));
}
private ChampionLancer(final ChampionLancer card) {
@ -43,33 +37,3 @@ public final class ChampionLancer extends CardImpl {
return new ChampionLancer(this);
}
}
class PreventDamageToSourceByCardTypeEffect extends PreventAllDamageToSourceEffect {
public PreventDamageToSourceByCardTypeEffect() {
super(Duration.WhileOnBattlefield);
}
public PreventDamageToSourceByCardTypeEffect(final PreventDamageToSourceByCardTypeEffect effect) {
super(effect.duration);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.isCreature(game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
}
return false;
}
@Override
public PreventAllDamageToSourceEffect copy() {
return new PreventAllDamageToSourceEffect(this);
}
}

View file

@ -1,20 +1,15 @@
package mage.cards.d;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.keyword.LandwalkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.common.FilterLandPermanent;
import java.util.UUID;
@ -23,24 +18,20 @@ import java.util.UUID;
*/
public final class DesertNomads extends CardImpl {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("desert");
static {
filter.add(SubType.DESERT.getPredicate());
}
private static final FilterControlledLandPermanent filterWalk = new FilterControlledLandPermanent(SubType.DESERT, "desert");
private static final FilterLandPermanent filterPrevent = new FilterLandPermanent(SubType.DESERT, "Deserts");
public DesertNomads(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.NOMAD);
this.subtype.add(SubType.HUMAN, SubType.NOMAD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Desertwalk
this.addAbility(new LandwalkAbility(filter));
this.addAbility(new LandwalkAbility(filterWalk));
// Prevent all damage that would be dealt to Desert Nomads by Deserts.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageToSourceBySubtypeEffect(SubType.DESERT)));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filterPrevent)));
}
private DesertNomads(final DesertNomads card) {
@ -52,28 +43,3 @@ public final class DesertNomads extends CardImpl {
return new DesertNomads(this);
}
}
class PreventDamageToSourceBySubtypeEffect extends PreventAllDamageToSourceEffect {
private SubType subtype;
public PreventDamageToSourceBySubtypeEffect(SubType sub) {
super(Duration.WhileOnBattlefield);
subtype = sub;
staticText = "Prevent all damage that would be dealt to {this} by " + subtype.getDescription();
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.hasSubtype(subtype, game)) {
return event.getTargetId().equals(source.getSourceId());
}
}
return false;
}
}

View file

@ -1,22 +1,15 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
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.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.EnchantedPredicate;
/**
*
@ -24,6 +17,12 @@ import mage.game.permanent.Permanent;
*/
public final class EnchantedBeing extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("enchanted creatures");
static {
filter.add(EnchantedPredicate.instance);
}
public EnchantedBeing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.subtype.add(SubType.HUMAN);
@ -31,9 +30,7 @@ public final class EnchantedBeing extends CardImpl {
this.toughness = new MageInt(2);
// Prevent all damage that would be dealt to Enchanted Being by enchanted creatures.
Effect effect = new PreventDamageToSourceByEnchantedCreatures();
effect.setText("Prevent all damage that would be dealt to {this} by enchanted creatures.");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter)));
}
private EnchantedBeing(final EnchantedBeing card) {
@ -45,35 +42,3 @@ public final class EnchantedBeing extends CardImpl {
return new EnchantedBeing(this);
}
}
class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSourceEffect {
public PreventDamageToSourceByEnchantedCreatures() {
super(Duration.WhileOnBattlefield);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (isEnchantedCreature(game.getObject(event.getSourceId()), game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
}
return false;
}
public boolean isEnchantedCreature(MageObject input, Game game) {
if (input == null || input.isCreature(game)) {
return false;
}
for (UUID attachmentId : ((Permanent) input).getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.isEnchantment(game)) {
return true;
}
}
return false;
}
}

View file

@ -1,11 +1,12 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect;
import mage.abilities.effects.common.PreventAllDamageByAllObjectsEffect;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -13,10 +14,11 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
/**
*
@ -34,15 +36,13 @@ public final class EnergyStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
// Cumulative upkeep {1}
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl<>("{1}")));
this.addAbility(new CumulativeUpkeepAbility(new GenericManaCost(1)));
// Prevent all damage that would be dealt by instant and sorcery spells.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new PreventAllDamageByAllObjectsEffect(StaticFilters.FILTER_SPELLS_INSTANT_OR_SORCERY, Duration.WhileOnBattlefield, false)
));
this.addAbility(new SimpleStaticAbility(new EnergyStormPreventionEffect()));
// Creatures with flying don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter)));
this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter)));
}
private EnergyStorm(final EnergyStorm card) {
@ -54,3 +54,29 @@ public final class EnergyStorm extends CardImpl {
return new EnergyStorm(this);
}
}
class EnergyStormPreventionEffect extends PreventionEffectImpl {
public EnergyStormPreventionEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false);
staticText = "prevent all damage that would be dealt by instant and sorcery spells";
}
private EnergyStormPreventionEffect(final EnergyStormPreventionEffect effect) {
super(effect);
}
@Override
public EnergyStormPreventionEffect copy() {
return new EnergyStormPreventionEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!super.applies(event, source, game)) {
return false;
}
Spell spell = game.getStack().getSpell(event.getSourceId());
return spell != null && (spell.isInstant(game) || spell.isSorcery(game));
}
}

View file

@ -1,19 +1,15 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventCombatDamageToSourceEffect;
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.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author L_J
@ -22,13 +18,12 @@ public final class EverdawnChampion extends CardImpl {
public EverdawnChampion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.subtype.add(SubType.HUMAN, SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Prevent all combat damage that would be dealt to Everdawn Champion.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EverdawnChampionEffect()));
this.addAbility(new SimpleStaticAbility(new PreventCombatDamageToSourceEffect(Duration.WhileOnBattlefield)));
}
private EverdawnChampion(final EverdawnChampion card) {
@ -40,31 +35,3 @@ public final class EverdawnChampion extends CardImpl {
return new EverdawnChampion(this);
}
}
class EverdawnChampionEffect extends PreventionEffectImpl {
public EverdawnChampionEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, true);
staticText = "Prevent all combat damage that would be dealt to {this}";
}
public EverdawnChampionEffect(final EverdawnChampionEffect effect) {
super(effect);
}
@Override
public EverdawnChampionEffect copy() {
return new EverdawnChampionEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
return false;
}
}

View file

@ -5,15 +5,16 @@ 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.PreventionEffectImpl;
import mage.abilities.effects.common.PreventDamageToTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game;
import mage.game.events.*;
import mage.target.common.TargetCreaturePermanent;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -30,18 +31,18 @@ public final class Godtoucher extends CardImpl {
public Godtoucher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.CLERIC);
this.subtype.add(SubType.ELF, SubType.CLERIC);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {1}{W}, {T}: Prevent all damage that would be dealt to target creature with power 5 or greater this turn.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new GodtoucherEffect(Duration.EndOfTurn),
new ManaCostsImpl<>("{1}{W}"));
Ability ability = new SimpleActivatedAbility(
new PreventDamageToTargetEffect(Duration.EndOfTurn),
new ManaCostsImpl<>("{1}{W}")
);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
@ -54,45 +55,3 @@ public final class Godtoucher extends CardImpl {
return new Godtoucher(this);
}
}
class GodtoucherEffect extends PreventionEffectImpl {
public GodtoucherEffect(Duration duration) {
super(duration);
staticText = "Prevent all damage that would be dealt to target creature with power 5 or greater this turn";
}
public GodtoucherEffect(final GodtoucherEffect effect) {
super(effect);
}
@Override
public GodtoucherEffect copy() {
return new GodtoucherEffect(Duration.EndOfTurn);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;
}
@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);
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
}
return false;
}
}

View file

@ -1,29 +1,30 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventAllDamageByAllPermanentsEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
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.game.permanent.Permanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
/**
* @author jeffwadsworth
* @author awjackson
*/
public final class HazeFrog extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
public HazeFrog(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.subtype.add(SubType.FROG);
@ -35,7 +36,10 @@ public final class HazeFrog extends CardImpl {
this.addAbility(FlashAbility.getInstance());
// When Haze Frog enters the battlefield, prevent all combat damage that other creatures would deal this turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new HazeFrogEffect()));
this.addAbility(new EntersBattlefieldTriggeredAbility(
new PreventAllDamageByAllPermanentsEffect(filter, Duration.EndOfTurn, true)
.setText("prevent all combat damage that other creatures would deal this turn")
));
}
private HazeFrog(final HazeFrog card) {
@ -47,53 +51,3 @@ public final class HazeFrog extends CardImpl {
return new HazeFrog(this);
}
}
class HazeFrogEffect extends PreventionEffectImpl {
public HazeFrogEffect() {
super(Duration.EndOfTurn);
this.staticText = "prevent all combat damage that other creatures would deal this turn";
}
public HazeFrogEffect(final HazeFrogEffect effect) {
super(effect);
}
@Override
public HazeFrogEffect copy() {
return new HazeFrogEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@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();
Permanent permanent = game.getPermanent(event.getSourceId());
StringBuilder message = new StringBuilder();
if (permanent != null) {
message.append(" from ").append(permanent.getName());
}
message.insert(0, "Damage").append(" has been prevented: ").append(damage);
event.setAmount(0);
game.informPlayers(message.toString());
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageEvent) {
DamageEvent damageEvent = (DamageEvent) event;
return damageEvent.isCombatDamage() && !damageEvent.getSourceId().equals(source.getSourceId());
}
return false;
}
}

View file

@ -1,20 +1,15 @@
package mage.cards.m;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAllSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
@ -33,19 +28,10 @@ public final class MarblePriest extends CardImpl {
this.toughness = new MageInt(3);
// All Walls able to block Marble Priest do so.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new MustBeBlockedByAllSourceEffect(
Duration.WhileOnBattlefield,
filter
)
));
this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAllSourceEffect(Duration.WhileOnBattlefield, filter)));
// Prevent all combat damage that would be dealt to Marble Priest by Walls.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new MarblePriestPreventionEffect()
));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter, true)));
}
private MarblePriest(final MarblePriest card) {
@ -57,21 +43,3 @@ public final class MarblePriest extends CardImpl {
return new MarblePriest(this);
}
}
class MarblePriestPreventionEffect extends PreventAllDamageToSourceEffect {
public MarblePriestPreventionEffect() {
super(Duration.WhileOnBattlefield);
staticText = "Prevent all combat damage that would be dealt to {this} by Walls";
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
MageObject sourceObject = game.getObject(event.getSourceId());
return super.applies(event, source, game)
&& event.getFlag()
&& sourceObject != null
&& sourceObject.hasSubtype(SubType.WALL, game)
&& event.getTargetId().equals(source.getSourceId());
}
}

View file

@ -1,15 +1,16 @@
package mage.cards.r;
import java.util.UUID;
import mage.abilities.effects.common.PreventAllDamageByAllObjectsEffect;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterObject;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
@ -17,17 +18,11 @@ import mage.filter.predicate.Predicates;
*/
public final class RepelTheAbominable extends CardImpl {
private static final FilterObject filter = new FilterObject("non-Human sources");
static {
filter.add(Predicates.not(SubType.HUMAN.getPredicate()));
}
public RepelTheAbominable(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
// Prevent all damage that would be dealt this turn by non-Human sources.
this.getSpellAbility().addEffect(new PreventAllDamageByAllObjectsEffect(filter, Duration.EndOfTurn, false));
this.getSpellAbility().addEffect(new RepelTheAbominablePreventionEffect());
}
private RepelTheAbominable(final RepelTheAbominable card) {
@ -39,3 +34,29 @@ public final class RepelTheAbominable extends CardImpl {
return new RepelTheAbominable(this);
}
}
class RepelTheAbominablePreventionEffect extends PreventionEffectImpl {
public RepelTheAbominablePreventionEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, false);
staticText = "prevent all damage that would be dealt this turn by non-Human sources";
}
private RepelTheAbominablePreventionEffect(final RepelTheAbominablePreventionEffect effect) {
super(effect);
}
@Override
public RepelTheAbominablePreventionEffect copy() {
return new RepelTheAbominablePreventionEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!super.applies(event, source, game)) {
return false;
}
MageObject sourceObject = game.getObject(event.getSourceId());
return sourceObject != null && !sourceObject.hasSubtype(SubType.HUMAN, game);
}
}

View file

@ -1,6 +1,6 @@
package mage.cards.t;
import mage.abilities.effects.common.PreventAllDamageByAllObjectsEffect;
import mage.abilities.effects.common.PreventAllDamageByAllPermanentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -18,7 +18,7 @@ public final class ThwartTheEnemy extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Prevent all damage that would be dealt this turn by creatures your opponents control.
this.getSpellAbility().addEffect(new PreventAllDamageByAllObjectsEffect(
this.getSpellAbility().addEffect(new PreventAllDamageByAllPermanentsEffect(
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, Duration.EndOfTurn, false
));
}

View file

@ -1,25 +1,18 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
@ -27,10 +20,15 @@ import mage.game.permanent.Permanent;
*/
public final class TresserhornSkyknight extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with first strike");
static {
filter.add(new AbilityPredicate(FirstStrikeAbility.class));
}
public TresserhornSkyknight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.KNIGHT);
this.subtype.add(SubType.ZOMBIE, SubType.KNIGHT);
this.power = new MageInt(5);
this.toughness = new MageInt(3);
@ -38,7 +36,7 @@ public final class TresserhornSkyknight extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Prevent all damage that would be dealt to Tresserhorn Skyknight by creatures with first strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TresserhornSkyknightEffect()));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter)));
}
private TresserhornSkyknight(final TresserhornSkyknight card) {
@ -50,40 +48,3 @@ public final class TresserhornSkyknight extends CardImpl {
return new TresserhornSkyknight(this);
}
}
class TresserhornSkyknightEffect extends PreventionEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with first strike");
static {
filter.add(new AbilityPredicate(FirstStrikeAbility.class));
}
TresserhornSkyknightEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false);
staticText = "Prevent all damage that would be dealt to Tresserhorn Skyknight by creatures with first strike";
}
TresserhornSkyknightEffect(final TresserhornSkyknightEffect effect) {
super(effect);
}
@Override
public TresserhornSkyknightEffect copy() {
return new TresserhornSkyknightEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
DamageEvent damageEvent = (DamageEvent) event;
if (event.getTargetId().equals(source.getSourceId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId());
if (permanent != null && filter.match(permanent, game)) {
return true;
}
}
}
return false;
}
}

View file

@ -1,20 +1,14 @@
package mage.cards.u;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
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.game.Game;
import mage.game.events.GameEvent;
import mage.filter.StaticFilters;
/**
*
@ -29,7 +23,7 @@ public final class UncleIstvan extends CardImpl {
this.toughness = new MageInt(3);
// Prevent all damage that would be dealt to Uncle Istvan by creatures.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageToSourceByCardTypeEffect()));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(StaticFilters.FILTER_PERMANENT_CREATURES)));
}
private UncleIstvan(final UncleIstvan card) {
@ -41,34 +35,3 @@ public final class UncleIstvan extends CardImpl {
return new UncleIstvan(this);
}
}
class PreventDamageToSourceByCardTypeEffect extends PreventAllDamageToSourceEffect {
public PreventDamageToSourceByCardTypeEffect() {
super(Duration.WhileOnBattlefield);
staticText = "Prevent all damage that would be dealt to {this} by creatures";
}
public PreventDamageToSourceByCardTypeEffect(final PreventDamageToSourceByCardTypeEffect effect) {
super(effect.duration);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.isCreature(game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
}
return false;
}
@Override
public PreventAllDamageToSourceEffect copy() {
return new PreventAllDamageToSourceEffect(this);
}
}

View file

@ -1,25 +1,18 @@
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.ProtectionAbility;
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.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.EnchantedPredicate;
/**
*
@ -27,6 +20,12 @@ import mage.game.permanent.Permanent;
*/
public final class WallOfPutridFlesh extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("enchanted creatures");
static {
filter.add(EnchantedPredicate.instance);
}
public WallOfPutridFlesh(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
@ -36,13 +35,12 @@ public final class WallOfPutridFlesh extends CardImpl {
// Defender
this.addAbility(DefenderAbility.getInstance());
// Protection from white
this.addAbility(ProtectionAbility.from(ObjectColor.WHITE));
// Prevent all damage that would be dealt to Wall of Putrid Flesh by enchanted creatures.
// The term enchanted creatures means creatures with an Aura on them.
Effect effect = new PreventDamageToSourceByEnchantedCreatures();
effect.setText("Prevent all damage that would be dealt to {this} by enchanted creatures.");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter)));
}
private WallOfPutridFlesh(final WallOfPutridFlesh card) {
@ -54,35 +52,3 @@ public final class WallOfPutridFlesh extends CardImpl {
return new WallOfPutridFlesh(this);
}
}
class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSourceEffect {
public PreventDamageToSourceByEnchantedCreatures() {
super(Duration.WhileOnBattlefield);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (isEnchantedCreature(game.getObject(event.getSourceId()), game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
}
return false;
}
public boolean isEnchantedCreature(MageObject input, Game game) {
if (input == null || input.isCreature(game)) {
return false;
}
for (UUID attachmentId : ((Permanent) input).getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.isEnchantment(game)) {
return true;
}
}
return false;
}
}

View file

@ -6,25 +6,22 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.CantBeTargetedSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.FilterObject;
import mage.filter.FilterPermanent;
import mage.filter.FilterStackObject;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.permanent.BlockedByIdPredicate;
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.target.Target;
@ -36,10 +33,12 @@ import java.util.UUID;
*/
public final class WallOfShadows extends CardImpl {
private static final FilterObject filter = new FilterStackObject("spells that can target only Walls or of abilities that can target only Walls");
private static final FilterPermanent filterPrevent = new FilterCreaturePermanent("creatures it's blocking");
private static final FilterObject filterCantTarget = new FilterStackObject("spells that can target only Walls or of abilities that can target only Walls");
static {
filter.add(CanTargetOnlyWallsPredicate.instance);
filterPrevent.add(BlockingOrBlockedBySourcePredicate.BLOCKED_BY);
filterCantTarget.add(CanTargetOnlyWallsPredicate.instance);
}
public WallOfShadows(UUID ownerId, CardSetInfo setInfo) {
@ -52,10 +51,10 @@ public final class WallOfShadows extends CardImpl {
this.addAbility(DefenderAbility.getInstance());
// Prevent all damage that would be dealt to Wall of Vapor by creatures it's blocking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WallOfShadowsEffect()));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filterPrevent)));
// Wall of Shadows can't be the target of spells that can target only Walls or of abilities that can target only Walls.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filter, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new CantBeTargetedSourceEffect(filterCantTarget, Duration.WhileOnBattlefield)));
}
private WallOfShadows(final WallOfShadows card) {
@ -68,40 +67,6 @@ public final class WallOfShadows extends CardImpl {
}
}
class WallOfShadowsEffect extends PreventionEffectImpl {
WallOfShadowsEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false);
staticText = "Prevent all damage that would be dealt to {this} by creatures it's blocking";
}
private WallOfShadowsEffect(final WallOfShadowsEffect effect) {
super(effect);
}
@Override
public WallOfShadowsEffect copy() {
return new WallOfShadowsEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!super.applies(event, source, game)
|| !(event instanceof DamageEvent)
|| event.getAmount() <= 0) {
return false;
}
DamageEvent damageEvent = (DamageEvent) event;
if (!event.getTargetId().equals(source.getSourceId())) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId());
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new BlockedByIdPredicate(source.getSourceId()));
return permanent != null && filter.match(permanent, game);
}
}
enum CanTargetOnlyWallsPredicate implements Predicate<MageObject> {
instance;

View file

@ -1,24 +1,17 @@
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventAllDamageToSourceByPermanentsEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.BlockedByIdPredicate;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
/**
*
@ -26,6 +19,12 @@ import mage.game.permanent.Permanent;
*/
public final class WallOfVapor extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures it's blocking");
static {
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKED_BY);
}
public WallOfVapor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.WALL);
@ -36,7 +35,7 @@ public final class WallOfVapor extends CardImpl {
this.addAbility(DefenderAbility.getInstance());
// Prevent all damage that would be dealt to Wall of Vapor by creatures it's blocking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WallOfVaporEffect()));
this.addAbility(new SimpleStaticAbility(new PreventAllDamageToSourceByPermanentsEffect(filter)));
}
private WallOfVapor(final WallOfVapor card) {
@ -48,36 +47,3 @@ public final class WallOfVapor extends CardImpl {
return new WallOfVapor(this);
}
}
class WallOfVaporEffect extends PreventionEffectImpl {
WallOfVaporEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false);
staticText = "Prevent all damage that would be dealt to Wall of Vapor by creatures it's blocking";
}
WallOfVaporEffect(final WallOfVaporEffect effect) {
super(effect);
}
@Override
public WallOfVaporEffect copy() {
return new WallOfVaporEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
DamageEvent damageEvent = (DamageEvent) event;
if (event.getTargetId().equals(source.getSourceId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId());
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new BlockedByIdPredicate(source.getSourceId()));
if (permanent != null && filter.match(permanent, game)) {
return true;
}
}
}
return false;
}
}

View file

@ -101,17 +101,15 @@ public class PreventAllDamageTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 1); // (2/2)
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); // (2/2)
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 4);
addCard(Zone.HAND, playerB, "Lightning Bolt", 2); // Instant {R}
// Fire Ambush deals 3 damage to any target.
addCard(Zone.HAND, playerB, "Fire Ambush", 2); // Sorcery {1}{R}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Energy Storm");
attack(1, playerA, "Abbey Griffin");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Abbey Griffin");
@ -122,8 +120,8 @@ public class PreventAllDamageTest extends CardTestPlayerBase {
attack(2, playerB, "Silvercoat Lion");
setChoice(playerA, false); // Pay {1}? Energy Storm - CumulativeUpkeepAbility: Cumulative upkeep {1}
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
assertGraveyardCount(playerA, "Energy Storm", 1);
@ -136,4 +134,55 @@ public class PreventAllDamageTest extends CardTestPlayerBase {
assertLife(playerA, 18);
assertLife(playerB, 18);
}
@Test
public void test_ArmoredTransport() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Armored Transport");
addCard(Zone.BATTLEFIELD, playerB, "Armored Transport");
attack(1, playerA, "Armored Transport");
block(1, playerB, "Armored Transport", "Armored Transport");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerA, "Armored Transport", 1);
assertGraveyardCount(playerB, "Armored Transport", 1);
}
@Test
public void test_HazeFrog() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Glory Seeker");
addCard(Zone.BATTLEFIELD, playerA, "Jwari Scuttler");
addCard(Zone.BATTLEFIELD, playerA, "Lagac Lizard");
addCard(Zone.BATTLEFIELD, playerB, "Daggerback Basilisk");
addCard(Zone.BATTLEFIELD, playerB, "Forest", 5);
addCard(Zone.HAND, playerB, "Haze Frog");
attack(1, playerA, "Glory Seeker");
attack(1, playerA, "Jwari Scuttler");
attack(1, playerA, "Lagac Lizard");
castSpell(1, PhaseStep.DECLARE_ATTACKERS, playerB, "Haze Frog");
block(1, playerB, "Daggerback Basilisk", "Lagac Lizard");
block(1, playerB, "Haze Frog", "Glory Seeker");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerA, "Glory Seeker", 1); // blocked by the one creature not being prevented
assertPermanentCount(playerA, "Jwari Scuttler", 1);
assertPermanentCount(playerA, "Lagac Lizard", 1);
assertPermanentCount(playerB, "Daggerback Basilisk", 1);
assertPermanentCount(playerB, "Haze Frog", 1);
assertLife(playerB, 20);
}
}

View file

@ -1,87 +0,0 @@
package mage.abilities.effects.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.PreventionEffectImpl;
import mage.constants.Duration;
import mage.filter.FilterInPlay;
import mage.filter.FilterObject;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
/**
* @author LevelX2
*/
public class PreventAllDamageByAllObjectsEffect extends PreventionEffectImpl {
private FilterObject filter;
public PreventAllDamageByAllObjectsEffect(Duration duration) {
this(null, duration, false);
}
public PreventAllDamageByAllObjectsEffect(Duration duration, boolean onlyCombat) {
this(null, duration, onlyCombat);
}
public PreventAllDamageByAllObjectsEffect(FilterObject filter, Duration duration, boolean onlyCombat) {
super(duration, Integer.MAX_VALUE, onlyCombat);
this.filter = filter;
}
private PreventAllDamageByAllObjectsEffect(final PreventAllDamageByAllObjectsEffect effect) {
super(effect);
if (effect.filter != null) {
this.filter = effect.filter.copy();
}
}
@Override
public PreventAllDamageByAllObjectsEffect copy() {
return new PreventAllDamageByAllObjectsEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!super.applies(event, source, game) || !(event instanceof DamageEvent) || event.getAmount() <= 0) {
return false;
}
DamageEvent damageEvent = (DamageEvent) event;
if (!damageEvent.isCombatDamage() && onlyCombat) {
return false;
}
if (filter == null) {
return true;
}
MageObject damageSource = game.getObject(damageEvent.getSourceId());
if (damageSource == null) {
return false;
}
if (filter instanceof FilterInPlay) {
return ((FilterInPlay) filter).match(damageSource, source.getControllerId(), source, game);
}
return filter.match(damageSource, game);
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
StringBuilder sb = new StringBuilder("Prevent all ");
if (onlyCombat) {
sb.append("combat ");
}
sb.append("damage that would be dealt");
if (duration == Duration.EndOfTurn) {
sb.append(" this turn");
}
if (filter != null) {
sb.append(" by ");
sb.append(filter.getMessage());
}
return sb.toString();
}
}

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
@ -17,7 +16,7 @@ import mage.game.permanent.Permanent;
*/
public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl {
private FilterPermanent filter;
protected final FilterPermanent filter;
public PreventAllDamageByAllPermanentsEffect(Duration duration) {
this(null, duration, false);
@ -30,13 +29,12 @@ public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl
public PreventAllDamageByAllPermanentsEffect(FilterPermanent filter, Duration duration, boolean onlyCombat) {
super(duration, Integer.MAX_VALUE, onlyCombat);
this.filter = filter;
setText();
}
public PreventAllDamageByAllPermanentsEffect(final PreventAllDamageByAllPermanentsEffect effect) {
super(effect);
if (effect.filter != null) {
this.filter = effect.filter.copy();
}
this.filter = effect.filter;
}
@Override
@ -61,11 +59,7 @@ public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl
return false;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
private void setText() {
StringBuilder sb = new StringBuilder("prevent all ");
if (onlyCombat) {
sb.append("combat ");
@ -78,6 +72,6 @@ public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl
sb.append(" by ");
sb.append(filter.getMessage());
}
return sb.toString();
staticText = sb.toString();
}
}

View file

@ -0,0 +1,54 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.constants.Duration;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author awjackson
*/
public class PreventAllDamageToSourceByPermanentsEffect extends PreventAllDamageByAllPermanentsEffect {
public PreventAllDamageToSourceByPermanentsEffect(FilterPermanent filter) {
this(filter, false);
}
public PreventAllDamageToSourceByPermanentsEffect(FilterPermanent filter, boolean onlyCombat) {
this(filter, Duration.WhileOnBattlefield, onlyCombat);
}
public PreventAllDamageToSourceByPermanentsEffect(FilterPermanent filter, Duration duration, boolean onlyCombat) {
super(filter, duration, onlyCombat);
setText();
}
public PreventAllDamageToSourceByPermanentsEffect(final PreventAllDamageToSourceByPermanentsEffect effect) {
super(effect);
}
public PreventAllDamageToSourceByPermanentsEffect copy() {
return new PreventAllDamageToSourceByPermanentsEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return super.applies(event, source, game) && event.getTargetId().equals(source.getSourceId());
}
private void setText() {
StringBuilder sb = new StringBuilder("prevent all ");
if (onlyCombat) {
sb.append("combat ");
}
sb.append("damage that would be dealt to {this} ");
if (duration == Duration.EndOfTurn) {
sb.append("this turn ");
}
sb.append("by ");
sb.append(filter.getMessage());
staticText = sb.toString();
}
}

View file

@ -1,5 +1,3 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
@ -16,9 +14,8 @@ public class PreventAllDamageToSourceEffect extends PreventionEffectImpl {
public PreventAllDamageToSourceEffect(Duration duration) {
super(duration, Integer.MAX_VALUE, false);
//Some durations have no text
if ( duration.toString().length()>0){
staticText = "Prevent all damage that would be dealt to {this} " + duration.toString();
if (duration == Duration.EndOfTurn) {
staticText = "Prevent all damage that would be dealt to {this} this turn";
} else {
staticText = "Prevent all damage that would be dealt to {this}";
}
@ -35,12 +32,6 @@ public class PreventAllDamageToSourceEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
return false;
return super.applies(event, source, game) && event.getTargetId().equals(source.getSourceId());
}
}

View file

@ -1,8 +1,7 @@
package mage.filter.common;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
@ -19,6 +18,12 @@ public class FilterControlledLandPermanent extends FilterControlledPermanent {
this.add(CardType.LAND.getPredicate());
}
public FilterControlledLandPermanent(SubType subtype, String name) {
super(name);
this.add(CardType.LAND.getPredicate());
this.add(subtype.getPredicate());
}
public FilterControlledLandPermanent(final FilterControlledLandPermanent filter) {
super(filter);
}
@ -27,5 +32,4 @@ public class FilterControlledLandPermanent extends FilterControlledPermanent {
public FilterControlledLandPermanent copy() {
return new FilterControlledLandPermanent(this);
}
}