From 8b5abfa2bbddaf1fbf295e53e44c68dd1284c383 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 22 May 2025 18:16:40 -0400 Subject: [PATCH] [FIN] Implement Sidequest: Hunt the Mark / Yiazmat, Ultimate Mark --- .../mage/cards/s/SidequestHuntTheMark.java | 129 ++++++++++++++++++ .../src/mage/cards/y/YiazmatUltimateMark.java | 64 +++++++++ Mage.Sets/src/mage/sets/FinalFantasy.java | 4 + 3 files changed, 197 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java create mode 100644 Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java diff --git a/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java b/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java new file mode 100644 index 00000000000..4b1ce5df4a5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java @@ -0,0 +1,129 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.TransformAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SidequestHuntTheMark extends CardImpl { + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledPermanent(SubType.TREASURE), ComparisonType.MORE_THAN, 2 + ); + private static final Hint hint = new ValueHint( + "Treasures you control", new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.TREASURE)) + ); + + public SidequestHuntTheMark(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); + + this.secondSideCardClazz = mage.cards.y.YiazmatUltimateMark.class; + + // When this enchantment enters, destroy up to one target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + + // At the beginning of your end step, if a creature died under an opponent's control this turn, create a Treasure token. Then if you control three or more Treasures, transform this enchantment. + this.addAbility(new TransformAbility()); + ability = new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new TreasureToken())) + .withInterveningIf(SidequestHuntTheMarkCondition.instance); + ability.addEffect(new ConditionalOneShotEffect( + new TransformSourceEffect(), condition, + "Then if you control three or more Treasures, transform {this}" + )); + this.addAbility(ability.addHint(hint).addHint(SidequestHuntTheMarkCondition.getHint()), new SidequestHuntTheMarkWatcher()); + } + + private SidequestHuntTheMark(final SidequestHuntTheMark card) { + super(card); + } + + @Override + public SidequestHuntTheMark copy() { + return new SidequestHuntTheMark(this); + } +} + +enum SidequestHuntTheMarkCondition implements Condition { + instance; + private static final Hint hint = new ConditionHint(instance); + + public static Hint getHint() { + return hint; + } + + @Override + public boolean apply(Game game, Ability source) { + return SidequestHuntTheMarkWatcher.checkPlayer(game, source); + } + + @Override + public String toString() { + return "a creature died under an opponent's control this turn"; + } +} + +class SidequestHuntTheMarkWatcher extends Watcher { + + private static final Set set = new HashSet<>(); + + SidequestHuntTheMarkWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.ZONE_CHANGE) { + return; + } + ZoneChangeEvent zEvent = ((ZoneChangeEvent) event); + if (zEvent.isDiesEvent() && zEvent.getTarget().isCreature(game)) { + set.addAll(game.getOpponents(zEvent.getTarget().getControllerId())); + } + } + + @Override + public void reset() { + super.reset(); + set.clear(); + } + + static boolean checkPlayer(Game game, Ability source) { + return game + .getState() + .getWatcher(SidequestHuntTheMarkWatcher.class) + .set + .contains(source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java b/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java new file mode 100644 index 00000000000..fc358bd8549 --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java @@ -0,0 +1,64 @@ +package mage.cards.y; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.TapSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class YiazmatUltimateMark extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another creature or artifact"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.ARTIFACT.getPredicate() + )); + } + + public YiazmatUltimateMark(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + this.nightCard = true; + this.color.setBlack(true); + + // {1}{B}, Sacrifice another creature or artifact: Yiazmat gains indestructible until end of turn. Tap it. + Ability ability = new SimpleActivatedAbility( + new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), new ManaCostsImpl<>("{1}{B}") + ); + ability.addCost(new SacrificeTargetCost(filter)); + ability.addEffect(new TapSourceEffect().setText("tap it")); + this.addAbility(ability); + } + + private YiazmatUltimateMark(final YiazmatUltimateMark card) { + super(card); + } + + @Override + public YiazmatUltimateMark copy() { + return new YiazmatUltimateMark(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index f830dc75da4..ad884ffdc86 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -340,6 +340,8 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Shiva, Warden of Ice", 523, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Shiva, Warden of Ice", 58, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sidequest: Catch a Fish", 31, Rarity.UNCOMMON, mage.cards.s.SidequestCatchAFish.class)); + cards.add(new SetCardInfo("Sidequest: Hunt the Mark", 119, Rarity.UNCOMMON, mage.cards.s.SidequestHuntTheMark.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sidequest: Hunt the Mark", 453, Rarity.UNCOMMON, mage.cards.s.SidequestHuntTheMark.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sidequest: Play Blitzball", 158, Rarity.UNCOMMON, mage.cards.s.SidequestPlayBlitzball.class)); cards.add(new SetCardInfo("Sin, Spira's Punishment", 242, Rarity.RARE, mage.cards.s.SinSpirasPunishment.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sin, Spira's Punishment", 348, Rarity.RARE, mage.cards.s.SinSpirasPunishment.class, NON_FULL_USE_VARIOUS)); @@ -466,6 +468,8 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Y'shtola Rhul", 443, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 577, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 86, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Yiazmat, Ultimate Mark", 119, Rarity.UNCOMMON, mage.cards.y.YiazmatUltimateMark.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Yiazmat, Ultimate Mark", 453, Rarity.UNCOMMON, mage.cards.y.YiazmatUltimateMark.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("You're Not Alone", 44, Rarity.COMMON, mage.cards.y.YoureNotAlone.class)); cards.add(new SetCardInfo("Yuna, Hope of Spira", 250, Rarity.MYTHIC, mage.cards.y.YunaHopeOfSpira.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuna, Hope of Spira", 404, Rarity.MYTHIC, mage.cards.y.YunaHopeOfSpira.class, NON_FULL_USE_VARIOUS));