diff --git a/Mage.Sets/src/mage/cards/i/IllicitMasquerade.java b/Mage.Sets/src/mage/cards/i/IllicitMasquerade.java new file mode 100644 index 00000000000..406e9c698b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IllicitMasquerade.java @@ -0,0 +1,116 @@ +package mage.cards.i; + +import java.util.UUID; + +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetpointer.FirstTargetPointer; + +/** + * + * @author DominionSpy + */ +public final class IllicitMasquerade extends CardImpl { + + public IllicitMasquerade(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Illicit Masquerade enters the battlefield, put an impostor counter on each creature you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( + CounterType.IMPOSTOR.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE))); + + // Whenever a creature you control with an impostor counter on it dies, exile it. Return up to one other target creature card from your graveyard to the battlefield. + this.addAbility(new IllicitMasquerageAbility()); + } + + private IllicitMasquerade(final IllicitMasquerade card) { + super(card); + } + + @Override + public IllicitMasquerade copy() { + return new IllicitMasquerade(this); + } +} + +class IllicitMasquerageAbility extends DiesCreatureTriggeredAbility { + + private static final FilterPermanent filter1 = + new FilterCreaturePermanent("a creature you control with an impostor counter on it"); + private static final FilterCard filter2 = + new FilterCreatureCard("other target creature card from your graveyard"); + + static { + filter1.add(TargetController.YOU.getControllerPredicate()); + filter1.add(CounterType.IMPOSTOR.getPredicate()); + + filter2.add(IllicitMasqueradePredicate.instance); + } + + IllicitMasquerageAbility() { + super(new ExileTargetEffect().setText("exile it"), false, filter1, true); + this.addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); + this.addTarget(new TargetCardInYourGraveyard(0, 1, filter2)); + } + + private IllicitMasquerageAbility(final IllicitMasquerageAbility ability) { + super(ability); + } + + @Override + public IllicitMasquerageAbility copy() { + return new IllicitMasquerageAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (super.checkTrigger(event, game)) { + // DiesCreatureTriggeredAbility rewrites targets, so need to point the second effect + // back to the correct target. + getEffects().stream() + .filter(ReturnFromGraveyardToBattlefieldTargetEffect.class::isInstance) + .forEach(effect -> effect.setTargetPointer(new FirstTargetPointer())); + return true; + } + return false; + } +} + +enum IllicitMasqueradePredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Ability ability = input.getSource(); + if (!(ability instanceof TriggeredAbility)) { + return true; + } + GameEvent event = ((TriggeredAbility) ability).getTriggerEvent(); + return event == null || !input.getObject().getId().equals(event.getTargetId()); + } +} diff --git a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java index a5ae8febb8d..9cade3be47c 100644 --- a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java +++ b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java @@ -133,6 +133,7 @@ public final class MurdersAtKarlovManor extends ExpansionSet { cards.add(new SetCardInfo("Hunted Bonebrute", 87, Rarity.RARE, mage.cards.h.HuntedBonebrute.class)); cards.add(new SetCardInfo("Hustle // Bustle", 249, Rarity.UNCOMMON, mage.cards.h.HustleBustle.class)); cards.add(new SetCardInfo("Ill-Timed Explosion", 207, Rarity.RARE, mage.cards.i.IllTimedExplosion.class)); + cards.add(new SetCardInfo("Illicit Masquerade", 88, Rarity.RARE, mage.cards.i.IllicitMasquerade.class)); cards.add(new SetCardInfo("Incinerator of the Guilty", 132, Rarity.MYTHIC, mage.cards.i.IncineratorOfTheGuilty.class)); cards.add(new SetCardInfo("Innocent Bystander", 133, Rarity.COMMON, mage.cards.i.InnocentBystander.class)); cards.add(new SetCardInfo("Inside Source", 19, Rarity.COMMON, mage.cards.i.InsideSource.class)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 4acfdb94ded..c509013a28b 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -105,6 +105,7 @@ public enum CounterType { HOURGLASS("hourglass", "an"), HUNGER("hunger"), ICE("ice"), + IMPOSTOR("impostor"), INCARNATION("incarnation"), INDESTRUCTIBLE("indestructible"), INFECTION("infection"),