diff --git a/Mage.Sets/src/mage/cards/m/MastersGuideMural.java b/Mage.Sets/src/mage/cards/m/MastersGuideMural.java new file mode 100644 index 00000000000..b53450a195c --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MastersGuideMural.java @@ -0,0 +1,37 @@ +package mage.cards.m; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.CraftAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.GolemWhiteBlueToken; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class MastersGuideMural extends CardImpl { + + public MastersGuideMural(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{W}{U}"); + this.secondSideCardClazz = mage.cards.m.MastersManufactory.class; + + // When Master's Guide-Mural enters the battlefield, create a 4/4 white and blue Golem artifact creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemWhiteBlueToken()))); + + // Craft with artifact {4}{W}{W}{U} + this.addAbility(new CraftAbility("{4}{W}{W}{U}")); + } + + private MastersGuideMural(final MastersGuideMural card) { + super(card); + } + + @Override + public MastersGuideMural copy() { + return new MastersGuideMural(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MastersManufactory.java b/Mage.Sets/src/mage/cards/m/MastersManufactory.java new file mode 100644 index 00000000000..574f0371abd --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MastersManufactory.java @@ -0,0 +1,113 @@ +package mage.cards.m; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.GolemWhiteBlueToken; +import mage.watchers.Watcher; + +import java.util.*; + +/** + * @author Susucr + */ +public final class MastersManufactory extends CardImpl { + + private static final Hint hint = new ConditionHint( + MastersManufactoryCondition.instance, + "{this} or another artifact entered under your control this turn" + ); + + public MastersManufactory(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); + + // {T}: Create a 4/4 white and blue Golem artifact creature token. Activate only if Master's Manufactory or another artifact entered the battlefield under your control this turn. + this.addAbility(new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, + new CreateTokenEffect(new GolemWhiteBlueToken()), + new TapSourceCost(), + MastersManufactoryCondition.instance + ).addHint(hint), new MastersManufactoryWatcher()); + } + + private MastersManufactory(final MastersManufactory card) { + super(card); + } + + @Override + public MastersManufactory copy() { + return new MastersManufactory(this); + } +} + +enum MastersManufactoryCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + MastersManufactoryWatcher watcher = game.getState().getWatcher(MastersManufactoryWatcher.class); + return watcher != null + && permanent != null + && watcher.check(source.getControllerId(), new MageObjectReference(permanent, game)); + } + + @Override + public String toString() { + return "if {this} or another artifact entered the battlefield under your control this turn"; + } +} + +class MastersManufactoryWatcher extends Watcher { + + // player -> an artifact entered this turn + private final Set playerHadArtifactEnter = new HashSet<>(); + // We need to store a lot for edges cases: + // -> Master's Manufactory could have entered as a non-artifact + // -> Another permanent could gain Manufactory's ability (copy effect), and we need to have tracked if it entered + // player -> set of all MOR of permanents that entered this turn under that player's control + private final Map> allEnteredThisTurn = new HashMap<>(); + + MastersManufactoryWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent.isArtifact(game)) { + playerHadArtifactEnter.add(event.getPlayerId()); + } + allEnteredThisTurn + .computeIfAbsent(event.getPlayerId(), k -> new HashSet<>()) + .add(new MageObjectReference(permanent, game)); + } + } + + @Override + public void reset() { + super.reset(); + playerHadArtifactEnter.clear(); + allEnteredThisTurn.clear(); + } + + boolean check(UUID playerId, MageObjectReference mor) { + return playerHadArtifactEnter.contains(playerId) + || allEnteredThisTurn.getOrDefault(playerId, Collections.emptySet()).contains(mor); + } +} diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index bf23c207972..1e2fd14011f 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -70,6 +70,8 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Kellan, Daring Traveler", 231, Rarity.RARE, mage.cards.k.KellanDaringTraveler.class)); cards.add(new SetCardInfo("Kinjalli's Dawnrunner", 19, Rarity.UNCOMMON, mage.cards.k.KinjallisDawnrunner.class)); cards.add(new SetCardInfo("Malamet War Scribe", 21, Rarity.UNCOMMON, mage.cards.m.MalametWarScribe.class)); + cards.add(new SetCardInfo("Master's Guide-Mural", 233, Rarity.UNCOMMON, mage.cards.m.MastersGuideMural.class)); + cards.add(new SetCardInfo("Master's Manufactory", 233, Rarity.UNCOMMON, mage.cards.m.MastersManufactory.class)); cards.add(new SetCardInfo("Miner's Guidewing", 24, Rarity.COMMON, mage.cards.m.MinersGuidewing.class)); cards.add(new SetCardInfo("Mischievous Pup", 25, Rarity.UNCOMMON, mage.cards.m.MischievousPup.class)); cards.add(new SetCardInfo("Mountain", 399, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/game/permanent/token/GolemWhiteBlueToken.java b/Mage/src/main/java/mage/game/permanent/token/GolemWhiteBlueToken.java new file mode 100644 index 00000000000..617fe33d947 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/GolemWhiteBlueToken.java @@ -0,0 +1,30 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author Susucr + */ +public final class GolemWhiteBlueToken extends TokenImpl { + + public GolemWhiteBlueToken() { + super("Golem Token", "4/4 white and blue Golem artifact creature token"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.GOLEM); + color.setWhite(true); + color.setBlue(true); + power = new MageInt(4); + toughness = new MageInt(4); + } + + protected GolemWhiteBlueToken(final GolemWhiteBlueToken token) { + super(token); + } + + public GolemWhiteBlueToken copy() { + return new GolemWhiteBlueToken(this); + } +}