From 5b4a1618f960b7ff8896eb42aa4469a6cca20c38 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 16 Jan 2026 13:49:35 -0500 Subject: [PATCH] [ECL] Implement Deepway Navigator --- .../src/mage/cards/d/DeepwayNavigator.java | 149 ++++++++++++++++++ Mage.Sets/src/mage/sets/LorwynEclipsed.java | 2 + 2 files changed, 151 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeepwayNavigator.java diff --git a/Mage.Sets/src/mage/cards/d/DeepwayNavigator.java b/Mage.Sets/src/mage/cards/d/DeepwayNavigator.java new file mode 100644 index 00000000000..99f61709740 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeepwayNavigator.java @@ -0,0 +1,149 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.UntapAllEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +import java.util.*; + +/** + * @author TheElk801 + */ +public final class DeepwayNavigator extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledPermanent(SubType.MERFOLK, "each other Merfolk you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + public DeepwayNavigator(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When this creature enters, untap each other Merfolk you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new UntapAllEffect(filter))); + + // As long as you attacked with three or more Merfolk this turn, Merfolk you control get +1/+0. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostControlledEffect( + 1, 0, Duration.WhileOnBattlefield, filter, false + ), DeepwayNavigatorCondition.instance, "as long as you attacked " + + "with three or more Merfolk this turn, Merfolk you control get +1/+0" + )).addHint(DeepwayNavigatorValue.getHint()), new DeepwayNavigatorWatcher()); + } + + private DeepwayNavigator(final DeepwayNavigator card) { + super(card); + } + + @Override + public DeepwayNavigator copy() { + return new DeepwayNavigator(this); + } +} + +enum DeepwayNavigatorCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return DeepwayNavigatorValue.instance.calculate(game, source, null) >= 3; + } +} + +enum DeepwayNavigatorValue implements DynamicValue { + instance; + private static final Hint hint = new ValueHint("Merfolk you attacked with this turn", instance); + + public static Hint getHint() { + return hint; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return DeepwayNavigatorWatcher.getCount(game, sourceAbility); + } + + @Override + public DeepwayNavigatorValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } +} + +class DeepwayNavigatorWatcher extends Watcher { + + private final Map> map = new HashMap<>(); + + DeepwayNavigatorWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.ATTACKER_DECLARED) { + return; + } + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.hasSubtype(SubType.MERFOLK, game)) { + map.computeIfAbsent(permanent.getControllerId(), x -> new HashSet<>()) + .add(new MageObjectReference(permanent, game)); + } + } + + @Override + public void reset() { + super.reset(); + map.clear(); + } + + static int getCount(Game game, Ability source) { + return game.getState() + .getWatcher(DeepwayNavigatorWatcher.class) + .map + .getOrDefault(source.getControllerId(), Collections.emptySet()) + .size(); + } +} diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index 9c6feff1fed..ea6e5a74569 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -115,6 +115,8 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Deceit", 293, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deepchannel Duelist", 213, Rarity.UNCOMMON, mage.cards.d.DeepchannelDuelist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deepchannel Duelist", 333, Rarity.UNCOMMON, mage.cards.d.DeepchannelDuelist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Deepway Navigator", 214, Rarity.RARE, mage.cards.d.DeepwayNavigator.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Deepway Navigator", 370, Rarity.RARE, mage.cards.d.DeepwayNavigator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Disruptor of Currents", 303, Rarity.RARE, mage.cards.d.DisruptorOfCurrents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Disruptor of Currents", 47, Rarity.RARE, mage.cards.d.DisruptorOfCurrents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Doran, Besieged by Time", 215, Rarity.RARE, mage.cards.d.DoranBesiegedByTime.class, NON_FULL_USE_VARIOUS));