diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java b/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java new file mode 100644 index 00000000000..88068a9d499 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java @@ -0,0 +1,62 @@ +package mage.cards.i; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SiegeAbility; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.m.MarchesaResoluteMonarch; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class InvasionOfFiora extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("legendary creatures"); + private static final FilterPermanent filter2 = new FilterCreaturePermanent("nonlegendary creatures"); + + static { + filter.add(SuperType.LEGENDARY.getPredicate()); + filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } + + public InvasionOfFiora(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}{B}"); + + this.subtype.add(SubType.SIEGE); + this.setStartingDefense(4); + this.secondSideCardClazz = mage.cards.m.MarchesaResoluteMonarch.class; + + // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) + this.addAbility(new SiegeAbility()); + + // When Invasion of Fiora enters the battlefield, choose one or both -- + // * Destroy all legendary creatures. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter)); + ability.getModes().setMinModes(1); + ability.getModes().setMaxModes(2); + + // * Destroy all nonlegendary creatures. + ability.addMode(new Mode(new DestroyAllEffect(filter2))); + this.addAbility(ability, MarchesaResoluteMonarch.makeWatcher()); + } + + private InvasionOfFiora(final InvasionOfFiora card) { + super(card); + } + + @Override + public InvasionOfFiora copy() { + return new InvasionOfFiora(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java b/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java new file mode 100644 index 00000000000..303413a69bf --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java @@ -0,0 +1,140 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.watchers.Watcher; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MarchesaResoluteMonarch extends CardImpl { + + public MarchesaResoluteMonarch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.NOBLE); + this.power = new MageInt(3); + this.toughness = new MageInt(6); + this.color.setBlack(true); + this.nightCard = true; + + // Menace + this.addAbility(new MenaceAbility()); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever Marchesa, Resolute Monarch attacks, remove all counters from up to one target permanent. + Ability ability = new AttacksTriggeredAbility(new MarchesaResoluteMonarchEffect()); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT)); + this.addAbility(ability); + + // At the beginning of your upkeep, if you haven't been dealt combat damage since your last turn, you draw a card and you lose 1 life. + ability = new ConditionalInterveningIfTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility( + new DrawCardSourceControllerEffect(1), TargetController.YOU, false + ), MarchesaResoluteMonarchWatcher::checkPlayer, "At the beginning of your upkeep, " + + "if you haven't been dealt combat damage since your last turn, you draw a card and you lose 1 life." + ); + ability.addEffect(new LoseLifeSourceControllerEffect(1)); + this.addAbility(ability); + } + + private MarchesaResoluteMonarch(final MarchesaResoluteMonarch card) { + super(card); + } + + @Override + public MarchesaResoluteMonarch copy() { + return new MarchesaResoluteMonarch(this); + } + + public static MarchesaResoluteMonarchWatcher makeWatcher() { + return new MarchesaResoluteMonarchWatcher(); + } +} + +class MarchesaResoluteMonarchEffect extends OneShotEffect { + + MarchesaResoluteMonarchEffect() { + super(Outcome.Benefit); + staticText = "remove all counters from up to one target permanent"; + } + + private MarchesaResoluteMonarchEffect(final MarchesaResoluteMonarchEffect effect) { + super(effect); + } + + @Override + public MarchesaResoluteMonarchEffect copy() { + return new MarchesaResoluteMonarchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + for (String counterType : new ArrayList<>(permanent.getCounters(game).keySet())) { + permanent.getCounters(game).removeAllCounters(counterType); + } + return true; + } +} + +class MarchesaResoluteMonarchWatcher extends Watcher { + + private final Set players = new HashSet<>(); + + MarchesaResoluteMonarchWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + switch (event.getType()) { + case DAMAGED_PLAYER: + if (((DamagedEvent) event).isCombatDamage()) { + players.add(event.getTargetId()); + } + return; + case END_TURN_STEP_POST: + players.remove(game.getActivePlayerId()); + return; + + } + } + + static boolean checkPlayer(Game game, Ability source) { + return game + .getState() + .getWatcher(MarchesaResoluteMonarchWatcher.class) + .players + .contains(source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java index bf64915f8d2..72d61a5c55c 100644 --- a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java +++ b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java @@ -149,6 +149,7 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Invasion of Dominaria", 21, Rarity.UNCOMMON, mage.cards.i.InvasionOfDominaria.class)); cards.add(new SetCardInfo("Invasion of Eldraine", 113, Rarity.UNCOMMON, mage.cards.i.InvasionOfEldraine.class)); cards.add(new SetCardInfo("Invasion of Ergamon", 233, Rarity.UNCOMMON, mage.cards.i.InvasionOfErgamon.class)); + cards.add(new SetCardInfo("Invasion of Fiora", 114, Rarity.RARE, mage.cards.i.InvasionOfFiora.class)); cards.add(new SetCardInfo("Invasion of Innistrad", 115, Rarity.MYTHIC, mage.cards.i.InvasionOfInnistrad.class)); cards.add(new SetCardInfo("Invasion of Ixalan", 191, Rarity.RARE, mage.cards.i.InvasionOfIxalan.class)); cards.add(new SetCardInfo("Invasion of Kaladesh", 234, Rarity.UNCOMMON, mage.cards.i.InvasionOfKaladesh.class)); @@ -186,6 +187,7 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Lithomantic Barrage", 152, Rarity.UNCOMMON, mage.cards.l.LithomanticBarrage.class)); cards.add(new SetCardInfo("Malady Invoker", 189, Rarity.UNCOMMON, mage.cards.m.MaladyInvoker.class)); cards.add(new SetCardInfo("Marauding Dreadship", 153, Rarity.COMMON, mage.cards.m.MaraudingDreadship.class)); + cards.add(new SetCardInfo("Marchesa, Resolute Monarch", 114, Rarity.RARE, mage.cards.m.MarchesaResoluteMonarch.class)); cards.add(new SetCardInfo("Marshal of Zhalfir", 246, Rarity.UNCOMMON, mage.cards.m.MarshalOfZhalfir.class)); cards.add(new SetCardInfo("Meeting of Minds", 66, Rarity.COMMON, mage.cards.m.MeetingOfMinds.class)); cards.add(new SetCardInfo("Merciless Repurposing", 117, Rarity.UNCOMMON, mage.cards.m.MercilessRepurposing.class));