From 97591808efdd61c5c24ce0a4a968183dfd4c44cb Mon Sep 17 00:00:00 2001 From: karapuzz14 Date: Sat, 24 Aug 2024 22:31:14 +0300 Subject: [PATCH 1/3] Implemented Pool of Vigorous Growth --- .../mage/cards/p/PoolOfVigorousGrowth.java | 92 +++++++++++++++++++ .../mage/sets/JumpstartHistoricHorizons.java | 1 + 2 files changed, 93 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java diff --git a/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java new file mode 100644 index 000000000000..9ad5d8756038 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java @@ -0,0 +1,92 @@ +package mage.cards.p; + +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.cards.*; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.RandomUtil; + +/** + * + * @author karapuzz14 + */ +public final class PoolOfVigorousGrowth extends CardImpl { + + public PoolOfVigorousGrowth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}"); + + + // {X}, {T}, Discard a card: Create a token that's a copy of a random creature card with mana value X. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new PoolOfVigorousGrowthEffect(), new ManaCostsImpl<>("{X}") + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + } + + private PoolOfVigorousGrowth(final PoolOfVigorousGrowth card) { + super(card); + } + + @Override + public PoolOfVigorousGrowth copy() { + return new PoolOfVigorousGrowth(this); + } +} +class PoolOfVigorousGrowthEffect extends OneShotEffect { + + PoolOfVigorousGrowthEffect() { + super(Outcome.PutCardInPlay); + staticText = "Create a token that's a copy of a random creature card with mana value X"; + } + + private PoolOfVigorousGrowthEffect(final PoolOfVigorousGrowthEffect effect) { + super(effect); + } + + @Override + public PoolOfVigorousGrowthEffect copy() { + return new PoolOfVigorousGrowthEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + int xValue = source.getManaCostsToPay().getX(); + CardCriteria creatureWithManaValueX = new CardCriteria().types(CardType.CREATURE).manaValue(xValue); + List cards = CardRepository.instance.findCards(creatureWithManaValueX); + if (cards != null) { + Card randomCard = Objects.requireNonNull(RandomUtil.randomFromCollection(cards)).createCard(); + HashSet card = new HashSet<>(); + card.add(randomCard); + game.loadCards(card, player.getId()); + Effect effect = new CreateTokenCopyTargetEffect().setTargetPointer(new FixedTarget(randomCard, game)); + boolean result = effect.apply(game, source); + game.getCards().remove(randomCard); + return result; + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java index 17a881be011f..741404a064a0 100644 --- a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java +++ b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java @@ -237,6 +237,7 @@ private JumpstartHistoricHorizons() { cards.add(new SetCardInfo("Phantasmal Form", 229, Rarity.COMMON, mage.cards.p.PhantasmalForm.class)); cards.add(new SetCardInfo("Phantom Ninja", 230, Rarity.COMMON, mage.cards.p.PhantomNinja.class)); cards.add(new SetCardInfo("Pondering Mage", 231, Rarity.COMMON, mage.cards.p.PonderingMage.class)); + cards.add(new SetCardInfo("Pool of Vigorous Growth", 28, Rarity.RARE, mage.cards.p.PoolOfVigorousGrowth.class)); cards.add(new SetCardInfo("Predatory Sliver", 619, Rarity.COMMON, mage.cards.p.PredatorySliver.class)); cards.add(new SetCardInfo("Prey's Vengeance", 620, Rarity.COMMON, mage.cards.p.PreysVengeance.class)); cards.add(new SetCardInfo("Priest of Fell Rites", 707, Rarity.RARE, mage.cards.p.PriestOfFellRites.class)); From fbefc1082543ab6debab9d23963e5821be3c14c2 Mon Sep 17 00:00:00 2001 From: karapuzz14 Date: Sun, 25 Aug 2024 15:37:41 +0300 Subject: [PATCH 2/3] Card rework based on Momir Emblem implementation --- .../mage/cards/p/PoolOfVigorousGrowth.java | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java index 9ad5d8756038..167e7c1fbe4f 100644 --- a/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java +++ b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java @@ -1,8 +1,6 @@ package mage.cards.p; -import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.UUID; import mage.abilities.Ability; @@ -10,9 +8,7 @@ import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.*; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; @@ -20,9 +16,11 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.token.Token; +import mage.game.permanent.token.custom.CreatureToken; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; import mage.util.RandomUtil; +import mage.util.functions.CopyTokenFunction; /** * @@ -74,19 +72,44 @@ public boolean apply(Game game, Ability source) { if (player == null) { return false; } + int xValue = source.getManaCostsToPay().getX(); - CardCriteria creatureWithManaValueX = new CardCriteria().types(CardType.CREATURE).manaValue(xValue); - List cards = CardRepository.instance.findCards(creatureWithManaValueX); - if (cards != null) { - Card randomCard = Objects.requireNonNull(RandomUtil.randomFromCollection(cards)).createCard(); - HashSet card = new HashSet<>(); - card.add(randomCard); - game.loadCards(card, player.getId()); - Effect effect = new CreateTokenCopyTargetEffect().setTargetPointer(new FixedTarget(randomCard, game)); - boolean result = effect.apply(game, source); - game.getCards().remove(randomCard); - return result; + if (game.isSimulation()) { + // Create dummy token to prevent multiple DB find cards what causes H2 java.lang.IllegalStateException if AI cancels calculation because of time out + Token token = new CreatureToken(xValue, xValue + 1); + token.putOntoBattlefield(1, game, source, source.getControllerId(), false, false); + return true; } + + CardCriteria criteria = new CardCriteria().types(CardType.CREATURE).manaValue(xValue); + List options = CardRepository.instance.findCards(criteria); + if (options == null || options.isEmpty()) { + game.informPlayers("No random creature card with mana value of " + xValue + " was found."); + return false; + } + + Token token = null; + while (!options.isEmpty()) { + int index = RandomUtil.nextInt(options.size()); + ExpansionSet expansionSet = Sets.findSet(options.get(index).getSetCode()); + if (expansionSet == null || expansionSet.getSetType().isCustomSet() || expansionSet.getSetType().isJokeSet()) { + options.remove(index); + } else { + Card card = options.get(index).createCard(); + if (card != null) { + token = CopyTokenFunction.createTokenCopy(card, game); + break; + } else { + options.remove(index); + } + } + } + if (token != null) { + token.putOntoBattlefield(1, game, source, source.getControllerId(), false, false); + return true; + } + return false; + } } \ No newline at end of file From 32a230e25e8862889ec25d73d3fde733a291301a Mon Sep 17 00:00:00 2001 From: karapuzz14 Date: Sun, 25 Aug 2024 16:37:35 +0300 Subject: [PATCH 3/3] Replacing obsolete function --- Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java index 167e7c1fbe4f..fd37739076e1 100644 --- a/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java +++ b/Mage.Sets/src/mage/cards/p/PoolOfVigorousGrowth.java @@ -19,6 +19,7 @@ import mage.game.permanent.token.Token; import mage.game.permanent.token.custom.CreatureToken; import mage.players.Player; +import mage.util.CardUtil; import mage.util.RandomUtil; import mage.util.functions.CopyTokenFunction; @@ -72,8 +73,8 @@ public boolean apply(Game game, Ability source) { if (player == null) { return false; } - - int xValue = source.getManaCostsToPay().getX(); + + int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); if (game.isSimulation()) { // Create dummy token to prevent multiple DB find cards what causes H2 java.lang.IllegalStateException if AI cancels calculation because of time out Token token = new CreatureToken(xValue, xValue + 1);