From 3486c57364f902bfbc2b292e55539ed6f773051f Mon Sep 17 00:00:00 2001 From: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:29:36 +0000 Subject: [PATCH] [MKC] Implement Printlifter Ooze (#11865) --- .../src/mage/cards/p/PrintlifterOoze.java | 87 +++++++++++++++++++ .../sets/MurdersAtKarlovManorCommander.java | 2 + .../common/CreateTokenCopyTargetEffect.java | 5 +- .../effects/common/CreateTokenEffect.java | 21 ++++- 4 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/PrintlifterOoze.java diff --git a/Mage.Sets/src/mage/cards/p/PrintlifterOoze.java b/Mage.Sets/src/mage/cards/p/PrintlifterOoze.java new file mode 100644 index 00000000000..fbf5faf0c45 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrintlifterOoze.java @@ -0,0 +1,87 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.TurnedFaceUpAllTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.DisguiseAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.token.OozeTrampleToken; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class PrintlifterOoze extends CardImpl { + + public PrintlifterOoze(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.subtype.add(SubType.OOZE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever Printlifter Ooze or another creature you control is turned face up, create a 0/0 green Ooze creature token with trample. + // The token enters the battlefield with X +1/+1 counters on it, where X is the number of other creatures you control. + this.addAbility(new TurnedFaceUpAllTriggeredAbility( + new PrintlifterOozeEffect(), new FilterControlledCreaturePermanent("{this} or another creature you control") + )); + + // Disguise {3}{G} + this.addAbility(new DisguiseAbility(this, new ManaCostsImpl<>("{3}{G}"))); + } + + private PrintlifterOoze(final PrintlifterOoze card) { + super(card); + } + + @Override + public PrintlifterOoze copy() { + return new PrintlifterOoze(this); + } +} + +class PrintlifterOozeEffect extends OneShotEffect { + + PrintlifterOozeEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "create a 0/0 green Ooze creature token with trample. The token enters the battlefield " + + "with X +1/+1 counters on it, where X is the number of other creatures you control"; + } + + private PrintlifterOozeEffect(final PrintlifterOozeEffect effect) { + super(effect); + } + + @Override + public PrintlifterOozeEffect copy() { + return new PrintlifterOozeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID controller = source.getControllerId(); + if (controller == null) { + return false; + } + int xVal = game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_CREATURE, controller, source, game); + Effect effect = new CreateTokenEffect(new OozeTrampleToken()).entersWithCounters(CounterType.P1P1, StaticValue.get(xVal)); + return effect.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/MurdersAtKarlovManorCommander.java b/Mage.Sets/src/mage/sets/MurdersAtKarlovManorCommander.java index d659b8a8173..daff2a76e47 100644 --- a/Mage.Sets/src/mage/sets/MurdersAtKarlovManorCommander.java +++ b/Mage.Sets/src/mage/sets/MurdersAtKarlovManorCommander.java @@ -190,6 +190,8 @@ public final class MurdersAtKarlovManorCommander extends ExpansionSet { cards.add(new SetCardInfo("Port of Karfell", 280, Rarity.UNCOMMON, mage.cards.p.PortOfKarfell.class)); cards.add(new SetCardInfo("Prairie Stream", 281, Rarity.RARE, mage.cards.p.PrairieStream.class)); cards.add(new SetCardInfo("Price of Fame", 135, Rarity.UNCOMMON, mage.cards.p.PriceOfFame.class)); + cards.add(new SetCardInfo("Printlifter Ooze", 40, Rarity.RARE, mage.cards.p.PrintlifterOoze.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Printlifter Ooze", 350, Rarity.RARE, mage.cards.p.PrintlifterOoze.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Promise of Loyalty", 79, Rarity.RARE, mage.cards.p.PromiseOfLoyalty.class)); cards.add(new SetCardInfo("Psychosis Crawler", 234, Rarity.RARE, mage.cards.p.PsychosisCrawler.class)); cards.add(new SetCardInfo("Ravenous Chupacabra", 136, Rarity.UNCOMMON, mage.cards.r.RavenousChupacabra.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index b5ec85ad1d1..6e35a885845 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -274,9 +274,8 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { Permanent tokenPermanent = game.getPermanent(tokenId); if (tokenPermanent != null) { addedTokenPermanents.add(tokenPermanent); - // add counters if necessary ie Ochre Jelly - if (counter != null - && numberOfCounters > 0) { + // TODO: Workaround to add counters to all created tokens, necessary for correct interactions with cards like Chatterfang, Squirrel General and Ochre Jelly / Printlifter Ooze. See #10786 + if (counter != null && numberOfCounters > 0) { tokenPermanent.addCounters(counter.createInstance(numberOfCounters), source.getControllerId(), source, game); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 96eb67cfb98..d15cec34ac5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common; import mage.abilities.Ability; @@ -9,6 +8,7 @@ import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.constants.Zone; +import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; @@ -30,6 +30,8 @@ public class CreateTokenEffect extends OneShotEffect { private final boolean attacking; private String additionalRules; private List lastAddedTokenIds = new ArrayList<>(); + private CounterType counterType; + private DynamicValue numberOfCounters; public CreateTokenEffect(Token token) { this(token, StaticValue.get(1)); @@ -67,9 +69,17 @@ public class CreateTokenEffect extends OneShotEffect { this.tapped = effect.tapped; this.attacking = effect.attacking; this.lastAddedTokenIds.addAll(effect.lastAddedTokenIds); + this.counterType = effect.counterType; + this.numberOfCounters = effect.numberOfCounters; this.additionalRules = effect.additionalRules; } + public CreateTokenEffect entersWithCounters(CounterType counterType, DynamicValue numberOfCounters) { + this.counterType = counterType; + this.numberOfCounters = numberOfCounters; + return this; + } + @Override public CreateTokenEffect copy() { return new CreateTokenEffect(this); @@ -80,6 +90,15 @@ public class CreateTokenEffect extends OneShotEffect { int value = amount.calculate(game, source, this); token.putOntoBattlefield(value, game, source, source.getControllerId(), tapped, attacking); this.lastAddedTokenIds = token.getLastAddedTokenIds(); + // TODO: Workaround to add counters to all created tokens, necessary for correct interactions with cards like Chatterfang, Squirrel General and Ochre Jelly / Printlifter Ooze. See #10786 + if (counterType != null) { + for (UUID tokenId : lastAddedTokenIds) { + Permanent tokenPermanent = game.getPermanent(tokenId); + if (tokenPermanent != null) { + tokenPermanent.addCounters(counterType.createInstance(numberOfCounters.calculate(game, source, this)), source.getControllerId(), source, game); + } + } + } return true; }