From dfe9390a2a58f1fdc1ef094494e3171c4f86e047 Mon Sep 17 00:00:00 2001
From: Susucre <34709007+Susucre@users.noreply.github.com>
Date: Fri, 31 May 2024 18:26:42 +0200
Subject: [PATCH] implement [MH3] Crabomination
---
Mage.Sets/src/mage/cards/c/Crabomination.java | 108 ++++++++++++++++++
Mage.Sets/src/mage/sets/ModernHorizons3.java | 1 +
.../mage/abilities/keyword/EmergeAbility.java | 39 +++++--
3 files changed, 139 insertions(+), 9 deletions(-)
create mode 100644 Mage.Sets/src/mage/cards/c/Crabomination.java
diff --git a/Mage.Sets/src/mage/cards/c/Crabomination.java b/Mage.Sets/src/mage/cards/c/Crabomination.java
new file mode 100644
index 00000000000..74158b09d64
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/Crabomination.java
@@ -0,0 +1,108 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.EmergeAbility;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledArtifactPermanent;
+import mage.filter.predicate.permanent.CanBeSacrificedPredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetOpponent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author Susucr
+ */
+public final class Crabomination extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledArtifactPermanent();
+
+ static {
+ filter.add(CanBeSacrificedPredicate.instance);
+ }
+
+ public Crabomination(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
+
+ this.subtype.add(SubType.CRAB);
+ this.subtype.add(SubType.DEMON);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Emerge from artifact {5}{B}{B}
+ this.addAbility(new EmergeAbility(this, "{5}{B}{B}", filter, "from artifact"));
+
+ // When Crabomination enters the battlefield, target opponent exiles the top card of their library, a card at random from their graveyard, and a card at random from their hand. You may cast a spell from among cards exiled this way without paying its mana cost.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new CrabominationEffect());
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+ }
+
+ private Crabomination(final Crabomination card) {
+ super(card);
+ }
+
+ @Override
+ public Crabomination copy() {
+ return new Crabomination(this);
+ }
+}
+
+class CrabominationEffect extends OneShotEffect {
+
+ CrabominationEffect() {
+ super(Outcome.Benefit);
+ staticText = "target opponent exiles the top card of their library, "
+ + "a card at random from their graveyard, "
+ + "and a card at random from their hand. "
+ + "You may cast a spell from among cards exiled this way without paying its mana cost";
+ }
+
+ private CrabominationEffect(final CrabominationEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CrabominationEffect copy() {
+ return new CrabominationEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
+ Player controller = game.getPlayer(source.getControllerId());
+ if (opponent == null || controller == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl();
+ Card fromTop = opponent.getLibrary().getFromTop(game);
+ if (fromTop != null) {
+ cards.add(fromTop);
+ }
+ Card fromGraveyard = opponent.getGraveyard().getRandom(game);
+ if (fromGraveyard != null) {
+ cards.add(fromGraveyard);
+ }
+ Card fromHand = opponent.getHand().getRandom(game);
+ if (fromHand != null) {
+ cards.add(fromHand);
+ }
+ opponent.moveCardsToExile(cards.getCards(game), source, game, true, null, "");
+ game.getState().processAction(game);
+ cards.retainZone(Zone.EXILED, game);
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, cards, StaticFilters.FILTER_CARD);
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3.java b/Mage.Sets/src/mage/sets/ModernHorizons3.java
index 9796891dae4..2aca9b9a855 100644
--- a/Mage.Sets/src/mage/sets/ModernHorizons3.java
+++ b/Mage.Sets/src/mage/sets/ModernHorizons3.java
@@ -53,6 +53,7 @@ public final class ModernHorizons3 extends ExpansionSet {
cards.add(new SetCardInfo("Consuming Corruption", 84, Rarity.UNCOMMON, mage.cards.c.ConsumingCorruption.class));
cards.add(new SetCardInfo("Contaminated Landscape", 218, Rarity.COMMON, mage.cards.c.ContaminatedLandscape.class));
cards.add(new SetCardInfo("Copycrook", 55, Rarity.UNCOMMON, mage.cards.c.Copycrook.class));
+ cards.add(new SetCardInfo("Crabomination", 85, Rarity.RARE, mage.cards.c.Crabomination.class));
cards.add(new SetCardInfo("Cranial Ram", 180, Rarity.COMMON, mage.cards.c.CranialRam.class));
cards.add(new SetCardInfo("Cursed Mirror", 279, Rarity.RARE, mage.cards.c.CursedMirror.class));
cards.add(new SetCardInfo("Cursed Wombat", 181, Rarity.UNCOMMON, mage.cards.c.CursedWombat.class));
diff --git a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java
index 54d1c457e7a..3c06cccbd34 100644
--- a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java
@@ -13,7 +13,6 @@ import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.CanBeSacrificedPredicate;
import mage.game.Game;
@@ -33,17 +32,29 @@ public class EmergeAbility extends SpellAbility {
public static final String EMERGE_ACTIVATION_CREATURE_REFERENCE = "emergeActivationMOR";
private static final FilterPermanent SAC_FILTER = new FilterControlledCreaturePermanent();
+
static {
SAC_FILTER.add(CanBeSacrificedPredicate.instance);
}
- public EmergeAbility(Card card, String emergeString) {
+ private final String emergeFromText;
+ private final FilterPermanent filter;
+
+ public EmergeAbility(Card card, String emergeManaString) {
+ this(card, emergeManaString, SAC_FILTER, "");
+ }
+
+ public EmergeAbility(Card card, String emergeManaString, FilterPermanent filter, String emergeFromText) {
super(card.getSpellAbility());
- this.emergeCost = new ManaCostsImpl<>(emergeString);
+
+ this.filter = filter;
+ this.emergeFromText = emergeFromText;
+
+ this.emergeCost = new ManaCostsImpl<>(emergeManaString);
this.newId(); // Set newId because cards spell ability is copied and needs own id
this.setCardName(card.getName() + " with emerge");
- zone = Zone.HAND;
- spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
+ this.zone = Zone.HAND;
+ this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
this.clearManaCosts();
this.clearManaCostsToPay();
@@ -52,9 +63,11 @@ public class EmergeAbility extends SpellAbility {
this.setRuleAtTheTop(true);
}
- protected EmergeAbility(final EmergeAbility ability) {
+ private EmergeAbility(final EmergeAbility ability) {
super(ability);
this.emergeCost = ability.emergeCost.copy();
+ this.filter = ability.filter;
+ this.emergeFromText = ability.emergeFromText;
}
@Override
@@ -63,7 +76,7 @@ public class EmergeAbility extends SpellAbility {
Player controller = game.getPlayer(this.getControllerId());
if (controller != null) {
for (Permanent creature : game.getBattlefield().getActivePermanents(
- SAC_FILTER, this.getControllerId(), this, game)) {
+ filter, this.getControllerId(), this, game)) {
ManaCost costToPay = CardUtil.reduceCost(emergeCost.copy(), creature.getManaValue());
if (costToPay.canPay(this, this, this.getControllerId(), game)) {
return new ActivationStatus(new ApprovingObject(this, game));
@@ -98,7 +111,7 @@ public class EmergeAbility extends SpellAbility {
public boolean activate(Game game, boolean noMana) {
Player controller = game.getPlayer(this.getControllerId());
if (controller != null) {
- TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE);
+ TargetSacrifice target = new TargetSacrifice(filter);
target.withChooseHint("to sacrifice for emerge");
if (controller.choose(Outcome.Sacrifice, target, this, game)) {
Permanent creature = game.getPermanent(target.getFirstTarget());
@@ -131,6 +144,14 @@ public class EmergeAbility extends SpellAbility {
@Override
public String getRule() {
- return "Emerge " + emergeCost.getText() + " (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's mana value.)";
+ String text = "Emerge ";
+ if (!emergeFromText.isEmpty()) {
+ text += emergeFromText + " ";
+ }
+ text += emergeCost.getText();
+ if (emergeFromText.isEmpty()) {
+ text += " (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's mana value.)";
+ }
+ return text;
}
}