From 3776a39683e174d6e2389f3c0b7bbaf00b33254e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Sat, 1 Feb 2025 19:21:46 -0500 Subject: [PATCH] [DFT] Implement Spikeshell Harrier --- .../src/mage/cards/s/SpikeshellHarrier.java | 101 ++++++++++++++++++ Mage.Sets/src/mage/sets/Aetherdrift.java | 1 + .../java/org/mage/test/player/TestPlayer.java | 5 + Mage/src/main/java/mage/players/Player.java | 2 + .../main/java/mage/players/PlayerImpl.java | 8 ++ 5 files changed, 117 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpikeshellHarrier.java diff --git a/Mage.Sets/src/mage/cards/s/SpikeshellHarrier.java b/Mage.Sets/src/mage/cards/s/SpikeshellHarrier.java new file mode 100644 index 00000000000..0cee12c0bb2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpikeshellHarrier.java @@ -0,0 +1,101 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SpikeshellHarrier extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("creature or Vehicle an opponent controls"); + + static { + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + SubType.VEHICLE.getPredicate() + )); + filter.add(TargetController.OPPONENT.getControllerPredicate()); + } + + public SpikeshellHarrier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.ROBOT); + this.subtype.add(SubType.TURTLE); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When this creature enters, return target creature or Vehicle an opponent controls to its owner's hand. If that opponent's speed is greater than each other player's speed, reduce that opponent's speed by 1. This effect can't reduce their speed below 1. + Ability ability = new EntersBattlefieldTriggeredAbility(new SpikeshellHarrierEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private SpikeshellHarrier(final SpikeshellHarrier card) { + super(card); + } + + @Override + public SpikeshellHarrier copy() { + return new SpikeshellHarrier(this); + } +} + +class SpikeshellHarrierEffect extends OneShotEffect { + + SpikeshellHarrierEffect() { + super(Outcome.Benefit); + staticText = "return target creature or Vehicle an opponent controls to its owner's hand. " + + "If that opponent's speed is greater than each other player's speed, " + + "reduce that opponent's speed by 1. This effect can't reduce their speed below 1"; + } + + private SpikeshellHarrierEffect(final SpikeshellHarrierEffect effect) { + super(effect); + } + + @Override + public SpikeshellHarrierEffect copy() { + return new SpikeshellHarrierEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + Player player = game.getPlayer(permanent.getControllerId()); + if (player == null) { + return false; + } + player.moveCards(permanent, Zone.HAND, source, game); + int minSpeed = game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .filter(uuid -> !uuid.equals(player.getId())) + .map(game::getPlayer) + .mapToInt(Player::getSpeed) + .min() + .orElse(0); + if (player.getSpeed() > minSpeed) { + player.decreaseSpeed(game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Aetherdrift.java b/Mage.Sets/src/mage/sets/Aetherdrift.java index 255a4217694..92248e07799 100644 --- a/Mage.Sets/src/mage/sets/Aetherdrift.java +++ b/Mage.Sets/src/mage/sets/Aetherdrift.java @@ -174,6 +174,7 @@ public final class Aetherdrift extends ExpansionSet { cards.add(new SetCardInfo("Slick Imitator", 62, Rarity.UNCOMMON, mage.cards.s.SlickImitator.class)); cards.add(new SetCardInfo("Spectral Interference", 63, Rarity.COMMON, mage.cards.s.SpectralInterference.class)); cards.add(new SetCardInfo("Spell Pierce", 64, Rarity.UNCOMMON, mage.cards.s.SpellPierce.class)); + cards.add(new SetCardInfo("Spikeshell Harrier", 65, Rarity.UNCOMMON, mage.cards.s.SpikeshellHarrier.class)); cards.add(new SetCardInfo("Spin Out", 106, Rarity.COMMON, mage.cards.s.SpinOut.class)); cards.add(new SetCardInfo("Spotcycle Scouter", 30, Rarity.COMMON, mage.cards.s.SpotcycleScouter.class)); cards.add(new SetCardInfo("Stall Out", 66, Rarity.COMMON, mage.cards.s.StallOut.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 8d9394141ef..19f793bba68 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -3992,6 +3992,11 @@ public class TestPlayer implements Player { computerPlayer.increaseSpeed(game); } + @Override + public void decreaseSpeed(Game game) { + computerPlayer.decreaseSpeed(game); + } + @Override public void setPayManaMode(boolean payManaMode) { computerPlayer.setPayManaMode(payManaMode); diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index cdf5a8bed3c..aed45f3a4a7 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -222,6 +222,8 @@ public interface Player extends MageItem, Copyable { void increaseSpeed(Game game); + void decreaseSpeed(Game game); + /** * Returns alternative casting costs a player can cast spells for * diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 0966ac467e2..55f2383cba4 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -4702,6 +4702,14 @@ public abstract class PlayerImpl implements Player, Serializable { } } + @Override + public void decreaseSpeed(Game game) { + if (speed > 1) { + speed--; + game.informPlayers(this.getLogName() + "'s speed has decreased to " + speed); + } + } + @Override public boolean autoLoseGame() { return false;