From d350485d648611268df445ffa73011dd5464861f Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:52:31 +0200 Subject: [PATCH] implement [MH3] Kozilek's Command --- .../src/mage/cards/k/KozileksCommand.java | 102 ++++++++++++++++++ Mage.Sets/src/mage/sets/ModernHorizons3.java | 1 + .../effects/keyword/ScryTargetEffect.java | 63 +++++++++++ 3 files changed, 166 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KozileksCommand.java create mode 100644 Mage/src/main/java/mage/abilities/effects/keyword/ScryTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/k/KozileksCommand.java b/Mage.Sets/src/mage/cards/k/KozileksCommand.java new file mode 100644 index 00000000000..95c86f2d7b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KozileksCommand.java @@ -0,0 +1,102 @@ +package mage.cards.k; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.keyword.ScryTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.Game; +import mage.game.permanent.token.EldraziSpawnToken; +import mage.target.Target; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class KozileksCommand extends CardImpl { + + public KozileksCommand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.INSTANT}, "{X}{C}{C}"); + + this.subtype.add(SubType.ELDRAZI); + + // Choose two -- + this.getSpellAbility().getModes().setMinModes(2); + this.getSpellAbility().getModes().setMaxModes(2); + + // * Target player creates X 0/1 colorless Eldrazi Spawn creature tokens with "Sacrifice this creature: Add {C}." + this.getSpellAbility().addEffect(new CreateTokenTargetEffect(new EldraziSpawnToken(), ManacostVariableValue.REGULAR)); + this.getSpellAbility().addTarget(new TargetPlayer().withChooseHint("create tokens")); + + // * Target player scries X, then draws a card. + Mode mode = new Mode(new ScryTargetEffect(ManacostVariableValue.REGULAR)); + mode.addEffect(new DrawCardTargetEffect(1).setText(", then draws a card")); + mode.addTarget(new TargetPlayer().withChooseHint("scries then draw")); + this.getSpellAbility().addMode(mode); + + // * Exile target creature with mana value X or less. + mode = new Mode(new ExileTargetEffect() + .setText("exile target creature with mana value X or less")); + mode.addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addMode(mode); + + // * Exile up to X target cards from graveyards. + mode = new Mode(new ExileTargetEffect() + .setText("exile up to X target cards from graveyards")); + mode.addTarget(new TargetCardInGraveyard(0, 0, new FilterCard("cards from graveyards"))); + this.getSpellAbility().addMode(mode); + + this.getSpellAbility().setTargetAdjuster(KozileksCommandAdjuster.instance); + } + + private KozileksCommand(final KozileksCommand card) { + super(card); + } + + @Override + public KozileksCommand copy() { + return new KozileksCommand(this); + } +} + +enum KozileksCommandAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + // adjust targets is called for every selected mode + Mode mode = ability.getModes().getMode(); + int xValue = ability.getManaCostsToPay().getX(); + for (Effect effect : mode.getEffects()) { + if (effect instanceof ExileTargetEffect) { + Target target = mode.getTargets().get(0); + if (target instanceof TargetCreaturePermanent) { + mode.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with mana value " + xValue + " or less"); + filter.add(new ManaValuePredicate(ComparisonType.OR_LESS, xValue)); + mode.addTarget(new TargetCreaturePermanent(filter)); + } + if (target instanceof TargetCardInGraveyard) { + mode.getTargets().clear(); + mode.addTarget(new TargetCardInGraveyard(0, xValue, new FilterCard("cards from graveyards"))); + } + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3.java b/Mage.Sets/src/mage/sets/ModernHorizons3.java index 1f9e71c30c7..3908ab8b81b 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons3.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons3.java @@ -157,6 +157,7 @@ public final class ModernHorizons3 extends ExpansionSet { cards.add(new SetCardInfo("Kaalia of the Vast", 290, Rarity.MYTHIC, mage.cards.k.KaaliaOfTheVast.class)); cards.add(new SetCardInfo("Kami of Jealous Thirst", 98, Rarity.COMMON, mage.cards.k.KamiOfJealousThirst.class)); cards.add(new SetCardInfo("Kappa Cannoneer", 270, Rarity.RARE, mage.cards.k.KappaCannoneer.class)); + cards.add(new SetCardInfo("Kozilek's Command", 11, Rarity.RARE, mage.cards.k.KozileksCommand.class)); cards.add(new SetCardInfo("Kozilek's Unsealing", 65, Rarity.UNCOMMON, mage.cards.k.KozileksUnsealing.class)); cards.add(new SetCardInfo("Kudo, King Among Bears", 192, Rarity.RARE, mage.cards.k.KudoKingAmongBears.class)); cards.add(new SetCardInfo("Laelia, the Blade Reforged", 281, Rarity.RARE, mage.cards.l.LaeliaTheBladeReforged.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ScryTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ScryTargetEffect.java new file mode 100644 index 00000000000..634b2da4d30 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ScryTargetEffect.java @@ -0,0 +1,63 @@ +package mage.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author Susucr + */ +public class ScryTargetEffect extends OneShotEffect { + + protected final DynamicValue amount; + + public ScryTargetEffect(int amount) { + this(StaticValue.get(amount)); + } + + public ScryTargetEffect(DynamicValue amount) { + super(Outcome.Benefit); + this.amount = amount; + } + + protected ScryTargetEffect(final ScryTargetEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID playerId : getTargetPointer().getTargets(game, source)) { + Player player = game.getPlayer(playerId); + if (player != null && player.canRespond()) { + int toScry = amount.calculate(game, source, this); + player.scry(toScry, source, game); + } + } + return true; + } + + @Override + public ScryTargetEffect copy() { + return new ScryTargetEffect(this); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(getTargetPointer().describeTargets(mode.getTargets(), "that player")); + sb.append(" scries "); + sb.append(CardUtil.numberToText(amount.toString())); + return sb.toString(); + } +}