From ae9330802d28ae5280e028642cfec35e19602a3f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 22 Oct 2022 17:53:13 -0400 Subject: [PATCH] [40K] Implemented Chaos Mutation --- Mage.Sets/src/mage/cards/c/ChaosMutation.java | 142 ++++++++++++++++++ Mage.Sets/src/mage/sets/Warhammer40000.java | 1 + 2 files changed, 143 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChaosMutation.java diff --git a/Mage.Sets/src/mage/cards/c/ChaosMutation.java b/Mage.Sets/src/mage/cards/c/ChaosMutation.java new file mode 100644 index 00000000000..3fdbc94e7e5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosMutation.java @@ -0,0 +1,142 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Controllable; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class ChaosMutation extends CardImpl { + + public ChaosMutation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{R}"); + + // Exile any number of target creatures controlled by different players. For each creature exiled this way, its controller reveals cards from the top of their library until they reveal a creature card, puts that card onto the battlefield, then puts the rest on the bottom of their library in a random order. + this.getSpellAbility().addEffect(new ChaosMutationEffect()); + this.getSpellAbility().addTarget(new ChaosMutationTarget()); + } + + private ChaosMutation(final ChaosMutation card) { + super(card); + } + + @Override + public ChaosMutation copy() { + return new ChaosMutation(this); + } +} + +class ChaosMutationEffect extends OneShotEffect { + + ChaosMutationEffect() { + super(Outcome.Benefit); + staticText = "exile any number of target creatures controlled by different players. " + + "For each creature exiled this way, its controller reveals cards from the top of their library " + + "until they reveal a creature card, puts that card onto the battlefield, " + + "then puts the rest on the bottom of their library in a random order"; + } + + private ChaosMutationEffect(final ChaosMutationEffect effect) { + super(effect); + } + + @Override + public ChaosMutationEffect copy() { + return new ChaosMutationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Set permanents = this + .getTargetPointer() + .getTargets(game, source) + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + if (controller == null || permanents.isEmpty()) { + return false; + } + List players = permanents + .stream() + .map(Controllable::getControllerId) + .map(game::getPlayer) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + controller.moveCards(permanents, Zone.EXILED, source, game); + for (Player player : players) { + Cards cards = new CardsImpl(); + Card card = this.getCreatureCard(player, cards, game); + player.revealCards(source, cards, game); + player.moveCards(card, Zone.BATTLEFIELD, source, game); + cards.retainZone(Zone.LIBRARY, game); + player.putCardsOnBottomOfLibrary(cards, game, source, false); + } + return true; + } + + private static Card getCreatureCard(Player player, Cards cards, Game game) { + for (Card card : player.getLibrary().getCards(game)) { + cards.add(card); + if (card.isCreature(game)) { + return card; + } + } + return null; + } +} + +class ChaosMutationTarget extends TargetPermanent { + + private static final FilterPermanent filter + = new FilterCreaturePermanent("creatures controlled by different players"); + + ChaosMutationTarget() { + super(0, Integer.MAX_VALUE, filter, false); + } + + private ChaosMutationTarget(final ChaosMutationTarget target) { + super(target); + } + + @Override + public ChaosMutationTarget copy() { + return new ChaosMutationTarget(this); + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (!super.canTarget(controllerId, id, source, game)) { + return false; + } + Permanent creature = game.getPermanent(id); + if (creature == null) { + return false; + } + return this.getTargets() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .noneMatch(permanent -> !creature.getId().equals(permanent.getId()) + && creature.isControlledBy(permanent.getControllerId()) + ); + } +} diff --git a/Mage.Sets/src/mage/sets/Warhammer40000.java b/Mage.Sets/src/mage/sets/Warhammer40000.java index eb18938834e..f6a30b20073 100644 --- a/Mage.Sets/src/mage/sets/Warhammer40000.java +++ b/Mage.Sets/src/mage/sets/Warhammer40000.java @@ -65,6 +65,7 @@ public final class Warhammer40000 extends ExpansionSet { cards.add(new SetCardInfo("Cave of Temptation", 267, Rarity.COMMON, mage.cards.c.CaveOfTemptation.class)); cards.add(new SetCardInfo("Celestine, the Living Saint", 10, Rarity.RARE, mage.cards.c.CelestineTheLivingSaint.class)); cards.add(new SetCardInfo("Chaos Defiler", 110, Rarity.RARE, mage.cards.c.ChaosDefiler.class)); + cards.add(new SetCardInfo("Chaos Mutation", 111, Rarity.RARE, mage.cards.c.ChaosMutation.class)); cards.add(new SetCardInfo("Chaos Terminator Lord", 74, Rarity.UNCOMMON, mage.cards.c.ChaosTerminatorLord.class)); cards.add(new SetCardInfo("Chaos Warp", 205, Rarity.RARE, mage.cards.c.ChaosWarp.class)); cards.add(new SetCardInfo("Choked Estuary", 268, Rarity.RARE, mage.cards.c.ChokedEstuary.class));