From 9d8991f5afc631393fb6ae7e7fc23f3a60f57be2 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 17 Jan 2024 15:11:12 -0500 Subject: [PATCH] [MKM] Implement Gadget Technician --- .../src/mage/cards/e/EfreetWeaponmaster.java | 61 ++++--------------- .../src/mage/cards/g/GadgetTechnician.java | 44 +++++++++++++ .../src/mage/cards/p/PonybackBrigade.java | 53 ++-------------- .../src/mage/sets/MurdersAtKarlovManor.java | 1 + ...lefieldOrTurnedFaceUpTriggeredAbility.java | 61 +++++++++++++++++++ 5 files changed, 123 insertions(+), 97 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GadgetTechnician.java create mode 100644 Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrTurnedFaceUpTriggeredAbility.java diff --git a/Mage.Sets/src/mage/cards/e/EfreetWeaponmaster.java b/Mage.Sets/src/mage/cards/e/EfreetWeaponmaster.java index 7fcb7cd103b..d166d5247b4 100644 --- a/Mage.Sets/src/mage/cards/e/EfreetWeaponmaster.java +++ b/Mage.Sets/src/mage/cards/e/EfreetWeaponmaster.java @@ -1,8 +1,8 @@ package mage.cards.e; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrTurnedFaceUpTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; @@ -10,23 +10,20 @@ import mage.abilities.keyword.MorphAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class EfreetWeaponmaster extends CardImpl { public EfreetWeaponmaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{R}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{R}{W}"); this.subtype.add(SubType.EFREET); this.subtype.add(SubType.MONK); @@ -35,9 +32,13 @@ public final class EfreetWeaponmaster extends CardImpl { // First strike this.addAbility(FirstStrikeAbility.getInstance()); - + // When Efreet Weaponmaster enters the battlefield or is turned face up, another target creature you control gets +3/+0 until end of turn. - this.addAbility(new EfreetWeaponmasterAbility()); + Ability ability = new EntersBattlefieldOrTurnedFaceUpTriggeredAbility( + new BoostTargetEffect(3, 0, Duration.EndOfTurn) + ); + ability.addTarget(new TargetControlledCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); + this.addAbility(ability); // Morph {2}{U}{R}{W} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{2}{U}{R}{W}"))); @@ -52,41 +53,3 @@ public final class EfreetWeaponmaster extends CardImpl { return new EfreetWeaponmaster(this); } } - -class EfreetWeaponmasterAbility extends TriggeredAbilityImpl { - - public EfreetWeaponmasterAbility() { - super(Zone.BATTLEFIELD, new BoostTargetEffect(3,0, Duration.EndOfTurn), false); - this.addTarget(new TargetControlledCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); - this.setWorksFaceDown(true); - setTriggerPhrase("When {this} enters the battlefield or is turned face up, "); - } - - private EfreetWeaponmasterAbility(final EfreetWeaponmasterAbility ability) { - super(ability); - } - - @Override - public EfreetWeaponmasterAbility copy() { - return new EfreetWeaponmasterAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TURNEDFACEUP || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.TURNEDFACEUP && event.getTargetId().equals(this.getSourceId())) { - return true; - } - if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GadgetTechnician.java b/Mage.Sets/src/mage/cards/g/GadgetTechnician.java new file mode 100644 index 00000000000..9141a53c1c3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GadgetTechnician.java @@ -0,0 +1,44 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldOrTurnedFaceUpTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.DisguiseAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.ThopterColorlessToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GadgetTechnician extends CardImpl { + + public GadgetTechnician(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.ARTIFICER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Gadget Technician enters the battlefield or is turned face up, create a 1/1 colorless Thopter artifact creature token with flying. + this.addAbility(new EntersBattlefieldOrTurnedFaceUpTriggeredAbility(new CreateTokenEffect(new ThopterColorlessToken()))); + + // Disguise {U/R}{U/R} + this.addAbility(new DisguiseAbility(this, new ManaCostsImpl<>("{U/R}{U/R}"))); + } + + private GadgetTechnician(final GadgetTechnician card) { + super(card); + } + + @Override + public GadgetTechnician copy() { + return new GadgetTechnician(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PonybackBrigade.java b/Mage.Sets/src/mage/cards/p/PonybackBrigade.java index b5b7708843b..3a88b06db73 100644 --- a/Mage.Sets/src/mage/cards/p/PonybackBrigade.java +++ b/Mage.Sets/src/mage/cards/p/PonybackBrigade.java @@ -1,9 +1,7 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldOrTurnedFaceUpTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.MorphAbility; @@ -11,21 +9,17 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.game.permanent.token.GoblinToken; -import mage.game.permanent.token.Token; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class PonybackBrigade extends CardImpl { public PonybackBrigade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{W}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}{B}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.WARRIOR); @@ -33,7 +27,7 @@ public final class PonybackBrigade extends CardImpl { this.toughness = new MageInt(2); // When Ponyback Brigade enters the battlefield or is turned face up, create three 1/1 red Goblin creature tokens. - this.addAbility(new PonybackBrigadeAbility(new GoblinToken())); + this.addAbility(new EntersBattlefieldOrTurnedFaceUpTriggeredAbility(new CreateTokenEffect(new GoblinToken(), 3))); // Morph {2}{R}{W}{B} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{2}{R}{W}{B}"))); @@ -48,40 +42,3 @@ public final class PonybackBrigade extends CardImpl { return new PonybackBrigade(this); } } - -class PonybackBrigadeAbility extends TriggeredAbilityImpl { - - public PonybackBrigadeAbility(Token token) { - super(Zone.BATTLEFIELD, new CreateTokenEffect(token, 3), false); - this.setWorksFaceDown(true); - setTriggerPhrase("When {this} enters the battlefield or is turned face up, "); - } - - private PonybackBrigadeAbility(final PonybackBrigadeAbility ability) { - super(ability); - } - - @Override - public PonybackBrigadeAbility copy() { - return new PonybackBrigadeAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TURNEDFACEUP || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.TURNEDFACEUP && event.getTargetId().equals(this.getSourceId())) { - return true; - } - if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java index df502fee7cd..6a9bfae1e51 100644 --- a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java +++ b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java @@ -43,6 +43,7 @@ public final class MurdersAtKarlovManor extends ExpansionSet { cards.add(new SetCardInfo("Faerie Snoop", 203, Rarity.COMMON, mage.cards.f.FaerieSnoop.class)); cards.add(new SetCardInfo("Fanatical Strength", 159, Rarity.COMMON, mage.cards.f.FanaticalStrength.class)); cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Gadget Technician", 204, Rarity.COMMON, mage.cards.g.GadgetTechnician.class)); cards.add(new SetCardInfo("Galvanize", 128, Rarity.COMMON, mage.cards.g.Galvanize.class)); cards.add(new SetCardInfo("Gleaming Geardrake", 205, Rarity.UNCOMMON, mage.cards.g.GleamingGeardrake.class)); cards.add(new SetCardInfo("Hedge Maze", 262, Rarity.RARE, mage.cards.h.HedgeMaze.class)); diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrTurnedFaceUpTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrTurnedFaceUpTriggeredAbility.java new file mode 100644 index 00000000000..bac7b8edd59 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrTurnedFaceUpTriggeredAbility.java @@ -0,0 +1,61 @@ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +import java.util.Objects; +import java.util.Optional; + +/** + * @author TheElk801 + */ +public class EntersBattlefieldOrTurnedFaceUpTriggeredAbility extends TriggeredAbilityImpl { + + public EntersBattlefieldOrTurnedFaceUpTriggeredAbility(Effect effect) { + this(effect, false); + } + + public EntersBattlefieldOrTurnedFaceUpTriggeredAbility(Effect effect, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + this.setWorksFaceDown(true); + this.setTriggerPhrase("When {this} enters the battlefield or is turned face up, "); + } + + private EntersBattlefieldOrTurnedFaceUpTriggeredAbility(final EntersBattlefieldOrTurnedFaceUpTriggeredAbility ability) { + super(ability); + } + + @Override + public EntersBattlefieldOrTurnedFaceUpTriggeredAbility copy() { + return new EntersBattlefieldOrTurnedFaceUpTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TURNEDFACEUP + || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!event.getTargetId().equals(this.getSourceId())) { + return false; + } + switch (event.getType()) { + case TURNEDFACEUP: + return true; + case ENTERS_THE_BATTLEFIELD: + Permanent sourcePermanent = getSourcePermanentIfItStillExists(game); + return Optional + .ofNullable(getSourcePermanentIfItStillExists(game)) + .filter(Objects::nonNull) + .map(permanent -> permanent.isFaceDown(game)) + .orElse(false); + } + return false; + } +}