diff --git a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java index 633d44dec74..def750d9b3c 100644 --- a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java +++ b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java @@ -4,28 +4,29 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.hint.common.ControllerDiscardedHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.Watcher; +import mage.watchers.common.DiscardedCardWatcher; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -53,9 +54,9 @@ public final class Asmoranomardicadaistinaculdacar extends CardImpl { // As long as you've discarded a card this turn, you may pay {B/R} to cast this spell. this.addAbility(new AlternativeCostSourceAbility( - new ManaCostsImpl<>("{B/R}"), AsmoranomardicadaistinaculdacarCondition.instance, + new ManaCostsImpl<>("{B/R}"), ControllerDiscardedThisTurnCondition.instance, "as long as you've discarded a card this turn, you may pay {B/R} to cast this spell" - ), new AsmoranomardicadaistinaculdacarWatcher()); + ).addHint(ControllerDiscardedHint.instance), new DiscardedCardWatcher()); // When Asmoranomardicadaistinaculdacar enters the battlefield, you may search your library for a card named The Underworld Cookbook, reveal it, put it into your hand, then shuffle. this.addAbility(new EntersBattlefieldTriggeredAbility( @@ -81,15 +82,6 @@ public final class Asmoranomardicadaistinaculdacar extends CardImpl { } } -enum AsmoranomardicadaistinaculdacarCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return AsmoranomardicadaistinaculdacarWatcher.checkPlayer(source.getControllerId(), game); - } -} - class AsmoranomardicadaistinaculdacarEffect extends OneShotEffect { AsmoranomardicadaistinaculdacarEffect() { @@ -115,32 +107,4 @@ class AsmoranomardicadaistinaculdacarEffect extends OneShotEffect { return permanent.damage(6, permanent.getId(), source, game) > 0; } } - -class AsmoranomardicadaistinaculdacarWatcher extends Watcher { - - private final Set playerSet = new HashSet<>(); - - AsmoranomardicadaistinaculdacarWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DISCARDED_CARD) { - playerSet.add(event.getPlayerId()); - } - } - - @Override - public void reset() { - playerSet.clear(); - super.reset(); - } - - static boolean checkPlayer(UUID playerId, Game game) { - AsmoranomardicadaistinaculdacarWatcher watcher - = game.getState().getWatcher(AsmoranomardicadaistinaculdacarWatcher.class); - return watcher != null && watcher.playerSet.contains(playerId); - } -} // it's easier to pronounce if you break it into separate words: asmorano mardica daistina culdacar diff --git a/Mage.Sets/src/mage/cards/r/Recalibrate.java b/Mage.Sets/src/mage/cards/r/Recalibrate.java new file mode 100644 index 00000000000..3455a5c6858 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Recalibrate.java @@ -0,0 +1,44 @@ +package mage.cards.r; + +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.hint.common.ControllerDiscardedHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.DiscardedCardWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Recalibrate extends CardImpl { + + public Recalibrate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Return target creature to its owner's hand. If you've discarded a card this turn, draw a card. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), + ControllerDiscardedThisTurnCondition.instance, + "If you've discarded a card this turn, draw a card" + )); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addHint(ControllerDiscardedHint.instance); + this.getSpellAbility().addWatcher(new DiscardedCardWatcher()); + } + + private Recalibrate(final Recalibrate card) { + super(card); + } + + @Override + public Recalibrate copy() { + return new Recalibrate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons2.java b/Mage.Sets/src/mage/sets/ModernHorizons2.java index 5446efb0a71..bd77a77f271 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons2.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons2.java @@ -194,6 +194,7 @@ public final class ModernHorizons2 extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Squirrel", 211, Rarity.UNCOMMON, mage.cards.r.RavenousSquirrel.class)); cards.add(new SetCardInfo("Raving Visionary", 56, Rarity.UNCOMMON, mage.cards.r.RavingVisionary.class)); cards.add(new SetCardInfo("Razortide Bridge", 252, Rarity.COMMON, mage.cards.r.RazortideBridge.class)); + cards.add(new SetCardInfo("Recalibrate", 57, Rarity.COMMON, mage.cards.r.Recalibrate.class)); cards.add(new SetCardInfo("Revolutionist", 139, Rarity.COMMON, mage.cards.r.Revolutionist.class)); cards.add(new SetCardInfo("Rift Sower", 170, Rarity.COMMON, mage.cards.r.RiftSower.class)); cards.add(new SetCardInfo("Riptide Laboratory", 303, Rarity.RARE, mage.cards.r.RiptideLaboratory.class)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java new file mode 100644 index 00000000000..8cdea17eb8d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/ControllerDiscardedThisTurnCondition.java @@ -0,0 +1,18 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.watchers.common.DiscardedCardWatcher; + +/** + * @author TheElk801 + */ +public enum ControllerDiscardedThisTurnCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return DiscardedCardWatcher.checkPlayerDiscarded(source.getControllerId(), game); + } +} diff --git a/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java b/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java new file mode 100644 index 00000000000..213fb416184 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/hint/common/ControllerDiscardedHint.java @@ -0,0 +1,28 @@ +package mage.abilities.hint.common; + +import mage.abilities.Ability; +import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum ControllerDiscardedHint implements Hint { + instance; + + private static final Hint hint = new ConditionHint( + ControllerDiscardedThisTurnCondition.instance, "You discarded a card this turn" + ); + + @Override + public String getText(Game game, Ability ability) { + return hint.getText(game, ability); + } + + @Override + public ControllerDiscardedHint copy() { + return instance; + } +} diff --git a/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java new file mode 100644 index 00000000000..5237835f378 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/DiscardedCardWatcher.java @@ -0,0 +1,40 @@ +package mage.watchers.common; + +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class DiscardedCardWatcher extends Watcher { + + private final Map playerMap = new HashMap<>(); + + public DiscardedCardWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DISCARDED_CARD) { + playerMap.compute(event.getPlayerId(), (u, i) -> i == null ? 1 : Integer.sum(i, 1)); + } + } + + @Override + public void reset() { + playerMap.clear(); + super.reset(); + } + + public static boolean checkPlayerDiscarded(UUID playerId, Game game) { + DiscardedCardWatcher watcher = game.getState().getWatcher(DiscardedCardWatcher.class); + return watcher != null && watcher.playerMap.getOrDefault(playerId, 0) > 0; + } +}