From f2cdfa46690878d46e262b734014aa213558205a Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sun, 24 Sep 2023 02:23:05 +0200 Subject: [PATCH] [CMB1] Implement Lazier Goblin (#11169) --- Mage.Sets/src/mage/cards/l/LazierGoblin.java | 182 ++++++++++++++++++ .../src/mage/sets/MysteryBoosterPlaytest.java | 1 + 2 files changed, 183 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LazierGoblin.java diff --git a/Mage.Sets/src/mage/cards/l/LazierGoblin.java b/Mage.Sets/src/mage/cards/l/LazierGoblin.java new file mode 100644 index 00000000000..121235d0a23 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LazierGoblin.java @@ -0,0 +1,182 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.SpecialAction; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.hint.common.ConditionPermanentHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class LazierGoblin extends CardImpl { + + /** + * Key to store that a MOR permanent has been motivated by a player. + */ + static final String keyMotivation(UUID playerId, MageObjectReference mor) { + return "LazierGoblinMotivated|" + playerId.toString() + "|" + mor.getSourceId().toString() + "|" + mor.getZoneChangeCounter(); + } + + public LazierGoblin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Motivate {3}{R} (This creature can't attack or block unless you have paid its motivate cost once. Motivate only as a sorcery.) + this.addAbility(new LazierGoblinSpecialAction()); + this.addAbility(new SimpleStaticAbility(new LazierGoblinRestrictionEffect()) + .addHint(new ConditionPermanentHint(LazierGoblinMotivatedCondition.instance))); + + // When Lazier Goblin enters the battlefield, it deals 2 damage to any target. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "it")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + private LazierGoblin(final LazierGoblin card) { + super(card); + } + + @Override + public LazierGoblin copy() { + return new LazierGoblin(this); + } +} + +class LazierGoblinSpecialAction extends SpecialAction { + + // Ruling (2019-11-12): + // Paying a creature's motivate cost is a special action that its controller + // may take any time they have priority during their main phase with no spells + // or abilities on the stack. + + LazierGoblinSpecialAction() { + super(Zone.BATTLEFIELD); + this.setTiming(TimingRule.SORCERY); + this.addCost(new ManaCostsImpl<>("{3}{R}")); + this.addEffect(new LazierGoblinMotivateEffect().setText("Motivate {3}{R}")); // text is for game log to make sense. + } + + private LazierGoblinSpecialAction(final LazierGoblinSpecialAction ability) { + super(ability); + } + + @Override + public LazierGoblinSpecialAction copy() { + return new LazierGoblinSpecialAction(this); + } + + @Override + public String getRule() { + return "Motivate {3}{R} (This creature can't attack or block unless you have paid its motivate cost once. Motivate only as a sorcery.)"; + } +} + +class LazierGoblinMotivateEffect extends OneShotEffect { + LazierGoblinMotivateEffect() { + super(Outcome.Benefit); + } + + private LazierGoblinMotivateEffect(final LazierGoblinMotivateEffect effect) { + super(effect); + } + + @Override + public LazierGoblinMotivateEffect copy() { + return new LazierGoblinMotivateEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentOrLKI(game); + if (permanent == null) { + return false; + } + game.getState().setValue( + LazierGoblin.keyMotivation( + permanent.getControllerId(), + new MageObjectReference(permanent, game) + ), + true + ); + return true; + } +} + +class LazierGoblinRestrictionEffect extends RestrictionEffect { + + public LazierGoblinRestrictionEffect() { + super(Duration.WhileOnBattlefield); + staticText = ""; // no text. + } + + private LazierGoblinRestrictionEffect(final LazierGoblinRestrictionEffect effect) { + super(effect); + } + + @Override + public LazierGoblinRestrictionEffect copy() { + return new LazierGoblinRestrictionEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent != null + && permanent.getId().equals(source.getSourceId()) + && null == game.getState().getValue( + LazierGoblin.keyMotivation( + permanent.getControllerId(), + new MageObjectReference(permanent, game) + ) + ); + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { + return false; + } + + @Override + public boolean canAttack(Game game, boolean canUseChooseDialogs) { + return false; + } +} + +enum LazierGoblinMotivatedCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + return permanent != null + && null != game.getState().getValue( + LazierGoblin.keyMotivation( + permanent.getControllerId(), + new MageObjectReference(permanent, game) + ) + ); + } + + @Override + public String toString() { + return "motivated"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MysteryBoosterPlaytest.java b/Mage.Sets/src/mage/sets/MysteryBoosterPlaytest.java index 55c123eb519..82689b6150a 100644 --- a/Mage.Sets/src/mage/sets/MysteryBoosterPlaytest.java +++ b/Mage.Sets/src/mage/sets/MysteryBoosterPlaytest.java @@ -28,6 +28,7 @@ public class MysteryBoosterPlaytest extends ExpansionSet { cards.add(new SetCardInfo("Frogkin Kidnapper", 42, Rarity.RARE, mage.cards.f.FrogkinKidnapper.class)); cards.add(new SetCardInfo("How to Keep an Izzet Mage Busy", 93, Rarity.RARE, mage.cards.h.HowToKeepAnIzzetMageBusy.class)); cards.add(new SetCardInfo("Innocuous Insect", 23, Rarity.RARE, mage.cards.i.InnocuousInsect.class)); + cards.add(new SetCardInfo("Lazier Goblin", 56, Rarity.RARE, mage.cards.l.LazierGoblin.class)); cards.add(new SetCardInfo("Mirrored Lotus", 107, Rarity.RARE, mage.cards.m.MirroredLotus.class)); cards.add(new SetCardInfo("Recycla-bird", 28, Rarity.RARE, mage.cards.r.RecyclaBird.class)); cards.add(new SetCardInfo("Slivdrazi Monstrosity", 102, Rarity.RARE, mage.cards.s.SlivdraziMonstrosity.class));