diff --git a/Mage.Sets/src/mage/cards/r/RamblingPossum.java b/Mage.Sets/src/mage/cards/r/RamblingPossum.java new file mode 100644 index 00000000000..0781a9cc936 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RamblingPossum.java @@ -0,0 +1,98 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksWhileSaddledTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.SaddleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.SaddledSourceThisTurnPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.watchers.common.SaddledMountWatcher; + +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class RamblingPossum extends CardImpl { + + public RamblingPossum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.POSSUM); + this.subtype.add(SubType.MOUNT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever Rambling Possum attacks while saddled, it gains +1/+2 until end of turn. Then you may return any number of creatures that saddled it this turn to their owner's hand. + Ability ability = new AttacksWhileSaddledTriggeredAbility(new BoostSourceEffect( + 1, 2, Duration.EndOfTurn, "it" + )); + ability.addEffect(new RamblingPossumEffect()); + this.addAbility(ability, new SaddledMountWatcher()); + + // Saddle 1 + this.addAbility(new SaddleAbility(1)); + } + + private RamblingPossum(final RamblingPossum card) { + super(card); + } + + @Override + public RamblingPossum copy() { + return new RamblingPossum(this); + } +} + +class RamblingPossumEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creatures that saddled it this turn"); + + static { + filter.add(SaddledSourceThisTurnPredicate.instance); + } + + RamblingPossumEffect() { + super(Outcome.Benefit); + staticText = "then you may return any number of creatures that saddled it this turn to their owner's hand"; + } + + private RamblingPossumEffect(final RamblingPossumEffect effect) { + super(effect); + } + + @Override + public RamblingPossumEffect copy() { + return new RamblingPossumEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); + player.choose(outcome, target, source, game); + Set permanents = target + .getTargets() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + return player.moveCards(permanents, Zone.HAND, source, game); + } +} diff --git a/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java b/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java index b351cbee522..dfd79d056b0 100644 --- a/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java +++ b/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java @@ -150,6 +150,7 @@ public final class OutlawsOfThunderJunction extends ExpansionSet { cards.add(new SetCardInfo("Quilled Charger", 139, Rarity.COMMON, mage.cards.q.QuilledCharger.class)); cards.add(new SetCardInfo("Railway Brawler", 175, Rarity.MYTHIC, mage.cards.r.RailwayBrawler.class)); cards.add(new SetCardInfo("Rakish Crew", 99, Rarity.UNCOMMON, mage.cards.r.RakishCrew.class)); + cards.add(new SetCardInfo("Rambling Possum", 176, Rarity.UNCOMMON, mage.cards.r.RamblingPossum.class)); cards.add(new SetCardInfo("Rattleback Apothecary", 100, Rarity.UNCOMMON, mage.cards.r.RattlebackApothecary.class)); cards.add(new SetCardInfo("Raucous Entertainer", 177, Rarity.UNCOMMON, mage.cards.r.RaucousEntertainer.class)); cards.add(new SetCardInfo("Raven of Fell Omens", 101, Rarity.COMMON, mage.cards.r.RavenOfFellOmens.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index d611e0ba973..74a5f0da246 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -316,6 +316,7 @@ public enum SubType { PIRATE("Pirate", SubTypeSet.CreatureType), PLANT("Plant", SubTypeSet.CreatureType), PORCUPINE("Porcupine", SubTypeSet.CreatureType), + POSSUM("Possum", SubTypeSet.CreatureType), PRAETOR("Praetor", SubTypeSet.CreatureType), PRIMARCH("Primarch", SubTypeSet.CreatureType), PRISM("Prism", SubTypeSet.CreatureType), diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/SaddledSourceThisTurnPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/SaddledSourceThisTurnPredicate.java new file mode 100644 index 00000000000..ba5121621c4 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/SaddledSourceThisTurnPredicate.java @@ -0,0 +1,26 @@ +package mage.filter.predicate.permanent; + +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.watchers.common.SaddledMountWatcher; + +/** + * @author TheElk801 + */ +public enum SaddledSourceThisTurnPredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return SaddledMountWatcher.checkIfSaddledThisTurn( + input.getObject(), input.getSource().getSourcePermanentOrLKI(game), game + ); + } + + @Override + public String toString() { + return "saddled {this} this turn"; + } +} diff --git a/Mage/src/main/java/mage/watchers/common/SaddledMountWatcher.java b/Mage/src/main/java/mage/watchers/common/SaddledMountWatcher.java new file mode 100644 index 00000000000..25fb33825c0 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/SaddledMountWatcher.java @@ -0,0 +1,55 @@ +package mage.watchers.common; + +import mage.MageObjectReference; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +import java.util.*; + +/** + * @author TheElk801 + */ +public class SaddledMountWatcher extends Watcher { + + private final Map> saddleMap = new HashMap<>(); + + public SaddledMountWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SADDLED_MOUNT) { + saddleMap.computeIfAbsent(new MageObjectReference(event.getSourceId(), game), x -> new HashSet<>()) + .add(new MageObjectReference(event.getTargetId(), game)); + } + } + + @Override + public void reset() { + super.reset(); + saddleMap.clear(); + } + + public static boolean checkIfSaddledThisTurn(Permanent saddler, Permanent mount, Game game) { + return game + .getState() + .getWatcher(SaddledMountWatcher.class) + .saddleMap + .getOrDefault(new MageObjectReference(mount, game), Collections.emptySet()) + .stream() + .anyMatch(mor -> mor.refersTo(saddler, game)); + } + + public static int getSaddleCount(Permanent vehicle, Game game) { + return game + .getState() + .getWatcher(SaddledMountWatcher.class) + .saddleMap + .getOrDefault(new MageObjectReference(vehicle, game), Collections.emptySet()) + .size(); + } +}