From 688003c8e08f2d7ec531b9e5bae272162a4a8259 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Mon, 30 Oct 2023 21:40:20 -0400 Subject: [PATCH] [LCI] Implement Gargantuan Leech --- .../src/mage/cards/g/GargantuanLeech.java | 48 +++++++++++++ .../src/mage/cards/s/SinuousBenthisaur.java | 30 ++------ .../src/mage/sets/TheLostCavernsOfIxalan.java | 1 + .../CavesControlledAndInGraveCount.java | 72 +++++++++++++++++++ 4 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GargantuanLeech.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/CavesControlledAndInGraveCount.java diff --git a/Mage.Sets/src/mage/cards/g/GargantuanLeech.java b/Mage.Sets/src/mage/cards/g/GargantuanLeech.java new file mode 100644 index 00000000000..7e9c5d5729c --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GargantuanLeech.java @@ -0,0 +1,48 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.CavesControlledAndInGraveCount; +import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GargantuanLeech extends CardImpl { + + public GargantuanLeech(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{B}"); + + this.subtype.add(SubType.LEECH); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // This spell costs {1} less to cast for each Cave you control and each Cave card in your graveyard. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, + new SpellCostReductionForEachSourceEffect( + 1, CavesControlledAndInGraveCount.FOR_EACH + ) + ).addHint(CavesControlledAndInGraveCount.getHint())); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + } + + private GargantuanLeech(final GargantuanLeech card) { + super(card); + } + + @Override + public GargantuanLeech copy() { + return new GargantuanLeech(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SinuousBenthisaur.java b/Mage.Sets/src/mage/cards/s/SinuousBenthisaur.java index 8a443695b23..a884affe099 100644 --- a/Mage.Sets/src/mage/cards/s/SinuousBenthisaur.java +++ b/Mage.Sets/src/mage/cards/s/SinuousBenthisaur.java @@ -2,20 +2,13 @@ package mage.cards.s; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.dynamicvalue.AdditiveDynamicValue; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.CavesControlledAndInGraveCount; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.PutCards; import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -24,20 +17,6 @@ import java.util.UUID; */ public final class SinuousBenthisaur extends CardImpl { - private static final FilterPermanent filter - = new FilterControlledPermanent(SubType.CAVE, "Caves you control"); - - private static final FilterCard filterCard = new FilterCard("plus the number of Cave cards"); - - static { - filterCard.add(SubType.CAVE.getPredicate()); - } - - private static final DynamicValue xValue = new AdditiveDynamicValue( - new PermanentsOnBattlefieldCount(filter, null), - new CardsInControllerGraveyardCount(filterCard) - ); - public SinuousBenthisaur(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); @@ -47,8 +26,11 @@ public final class SinuousBenthisaur extends CardImpl { // When Sinuous Benthisaur enters the battlefield, look at the top X cards of your library, where X is the number of Caves you control plus the number of Cave cards in your graveyard. Put two of those cards into your hand and the rest on the bottom of your library in a random order. this.addAbility(new EntersBattlefieldTriggeredAbility( - new LookLibraryAndPickControllerEffect(xValue, 2, PutCards.HAND, PutCards.BOTTOM_RANDOM) - ).addHint(new ValueHint("Caves count", xValue))); + new LookLibraryAndPickControllerEffect( + CavesControlledAndInGraveCount.WHERE_X, + 2, PutCards.HAND, PutCards.BOTTOM_RANDOM + ) + ).addHint(CavesControlledAndInGraveCount.getHint())); } private SinuousBenthisaur(final SinuousBenthisaur card) { diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index 9dd522b73e3..3db911b12e1 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -60,6 +60,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Explorer's Cache", 184, Rarity.UNCOMMON, mage.cards.e.ExplorersCache.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Forest", 401, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gargantuan Leech", 107, Rarity.UNCOMMON, mage.cards.g.GargantuanLeech.class)); cards.add(new SetCardInfo("Geode Grotto", 146, Rarity.UNCOMMON, mage.cards.g.GeodeGrotto.class)); cards.add(new SetCardInfo("Geological Appraiser", 150, Rarity.UNCOMMON, mage.cards.g.GeologicalAppraiser.class)); cards.add(new SetCardInfo("Get Lost", 14, Rarity.RARE, mage.cards.g.GetLost.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CavesControlledAndInGraveCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CavesControlledAndInGraveCount.java new file mode 100644 index 00000000000..7c8e4d2cedb --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CavesControlledAndInGraveCount.java @@ -0,0 +1,72 @@ +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.players.Player; + +import java.util.Objects; +import java.util.Optional; + +/** + * @author TheElk801 + */ +public enum CavesControlledAndInGraveCount implements DynamicValue { + FOR_EACH("1", "Cave you control and each Cave card in your graveyard"), + WHERE_X("X", "Caves you control plus the number of Cave cards in your graveyard"); + private static final FilterPermanent filter1 = new FilterControlledPermanent(SubType.CAVE); + private static final FilterCard filter2 = new FilterCard(); + + static { + filter2.add(SubType.CAVE.getPredicate()); + } + + private static final Hint hint = new ValueHint("Caves you control and Cave cards in your graveyard", FOR_EACH); + + public static Hint getHint() { + return hint; + } + + private final String number; + private final String message; + + CavesControlledAndInGraveCount(String number, String message) { + this.number = number; + this.message = message; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return game + .getBattlefield() + .count(filter1, sourceAbility.getControllerId(), sourceAbility, game) + + Optional + .ofNullable(game.getPlayer(sourceAbility.getControllerId())) + .filter(Objects::nonNull) + .map(Player::getGraveyard) + .map(g -> g.count(filter2, game)) + .orElse(0); + } + + @Override + public CavesControlledAndInGraveCount copy() { + return this; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String toString() { + return number; + } +}