From c24d45312ca221b4de89fa2ed5091d4cc23bc1e9 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Tue, 18 Apr 2023 19:36:11 -0400 Subject: [PATCH] [MOM] Implement Invasion of Ikoria / Zilortha, Apex of Ikoria --- .../src/mage/cards/i/InvasionOfIkoria.java | 65 +++++++++++++++ .../mage/cards/z/ZilorthaApexOfIkoria.java | 82 +++++++++++++++++++ .../src/mage/sets/MarchOfTheMachine.java | 2 + 3 files changed, 149 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java create mode 100644 Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java b/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java new file mode 100644 index 00000000000..9cf0c702476 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java @@ -0,0 +1,65 @@ +package mage.cards.i; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SiegeAbility; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutOntoBattlefieldEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.filter.predicate.Predicates; +import mage.game.Game; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class InvasionOfIkoria extends CardImpl { + + private static final FilterCard filter = new FilterCreatureCard("non-Human creature card with mana value X or less"); + + static { + filter.add(Predicates.not(SubType.HUMAN.getPredicate())); + filter.add(InvasionOfIkoriaPredicate.instance); + } + + public InvasionOfIkoria(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{X}{G}{G}"); + + this.subtype.add(SubType.SIEGE); + this.setStartingDefense(6); + this.secondSideCardClazz = mage.cards.z.ZilorthaApexOfIkoria.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 Ikoria enters the battlefield, search your library and/or graveyard for a non-Human creature card with mana value X or less and put it onto the battlefield. If you search your library this way, shuffle. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutOntoBattlefieldEffect(filter))); + } + + private InvasionOfIkoria(final InvasionOfIkoria card) { + super(card); + } + + @Override + public InvasionOfIkoria copy() { + return new InvasionOfIkoria(this); + } +} + +enum InvasionOfIkoriaPredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getManaValue() + <= ManacostVariableValue.ETB.calculate(game, input.getSource(), null); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java b/Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java new file mode 100644 index 00000000000..be429a65ba5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java @@ -0,0 +1,82 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZilorthaApexOfIkoria extends CardImpl { + + public ZilorthaApexOfIkoria(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + this.color.setGreen(true); + this.nightCard = true; + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // For each non-Human creature you control, you may have that creature assign its combat damage as though it weren't blocked. + this.addAbility(new SimpleStaticAbility(new ZilorthaApexOfIkoriaEffect())); + } + + private ZilorthaApexOfIkoria(final ZilorthaApexOfIkoria card) { + super(card); + } + + @Override + public ZilorthaApexOfIkoria copy() { + return new ZilorthaApexOfIkoria(this); + } +} + +class ZilorthaApexOfIkoriaEffect extends AsThoughEffectImpl { + + ZilorthaApexOfIkoriaEffect() { + super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.WhileOnBattlefield, Outcome.Damage); + this.staticText = "for each non-Human creature you control, you may have that " + + "creature assign its combat damage as though it weren't blocked"; + } + + private ZilorthaApexOfIkoriaEffect(ZilorthaApexOfIkoriaEffect effect) { + super(effect); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(sourceId); + return controller != null + && permanent != null + && permanent.isControlledBy(controller.getId()) + && !permanent.hasSubtype(SubType.HUMAN, game) + && controller.chooseUse(Outcome.Damage, "Have " + permanent.getLogName() + + " assign damage as though it weren't blocked?", source, game); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ZilorthaApexOfIkoriaEffect copy() { + return new ZilorthaApexOfIkoriaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java index 184c26648b2..806f717fcf8 100644 --- a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java +++ b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java @@ -175,6 +175,7 @@ public final class MarchOfTheMachine extends ExpansionSet { 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 Gobakhan", 22, Rarity.RARE, mage.cards.i.InvasionOfGobakhan.class)); + cards.add(new SetCardInfo("Invasion of Ikoria", 190, Rarity.RARE, mage.cards.i.InvasionOfIkoria.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)); @@ -376,6 +377,7 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Zephyr Winder", 328, Rarity.COMMON, mage.cards.z.ZephyrWinder.class)); cards.add(new SetCardInfo("Zhalfirin Lancer", 45, Rarity.UNCOMMON, mage.cards.z.ZhalfirinLancer.class)); cards.add(new SetCardInfo("Zhalfirin Shapecraft", 87, Rarity.COMMON, mage.cards.z.ZhalfirinShapecraft.class)); + cards.add(new SetCardInfo("Zilortha, Apex of Ikoria", 190, Rarity.RARE, mage.cards.z.ZilorthaApexOfIkoria.class)); cards.add(new SetCardInfo("Zimone and Dina", 257, Rarity.MYTHIC, mage.cards.z.ZimoneAndDina.class)); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); // remove when mechanic is implemented