[CSP] rework Jester's Scepter

This commit is contained in:
theelk801 2024-10-16 15:35:40 -04:00
parent 542ea3664d
commit ad7c62cff4

View file

@ -1,29 +1,27 @@
package mage.cards.j;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.game.ExileZone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInExile;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import java.util.Set;
import java.util.Optional;
import java.util.UUID;
/**
@ -34,21 +32,17 @@ public final class JestersScepter extends CardImpl {
public JestersScepter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down.
// When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.
Ability ability = new EntersBattlefieldTriggeredAbility(new JestersScepterEffect(), false);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
// You may look at those cards for as long as they remain exiled.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new JestersScepterLookAtCardEffect()));
// {2}, {tap}, Put a card exiled with Jester's Scepter into its owner's graveyard: Counter target spell if it has the same name as that card.
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JestersScepterCounterEffect(), new ManaCostsImpl<>("{2}"));
ability2.addCost(new TapSourceCost());
ability2.addCost(new JestersScepterCost());
ability2.addTarget(new TargetSpell());
this.addAbility(ability2);
ability = new SimpleActivatedAbility(new JestersScepterCounterEffect(), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
ability.addCost(new JestersScepterCost());
ability.addTarget(new TargetSpell());
this.addAbility(ability);
}
private JestersScepter(final JestersScepter card) {
@ -75,22 +69,22 @@ class JestersScepterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetedPlayer = game.getPlayer(source.getFirstTarget());
MageObject sourceObject = game.getObject(source);
if (controller != null
&& targetedPlayer != null
&& sourceObject != null) {
if (targetedPlayer.getLibrary().hasCards()) {
Set<Card> cardsToExile = targetedPlayer.getLibrary().getTopCards(game, 5);
for (Card card : cardsToExile) {
if (card.moveToExile(CardUtil.getCardExileZoneId(game, source), sourceObject.getName(), source, game)) {
card.setFaceDown(true, game);
}
}
}
return true;
Player targetedPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (controller == null || targetedPlayer == null) {
return false;
}
return false;
Cards cards = new CardsImpl(targetedPlayer.getLibrary().getTopCards(game, 5));
controller.moveCardsToExile(
cards.getCards(game), source, game, false,
CardUtil.getExileZoneId(game, source),
CardUtil.getSourceName(game, source)
);
cards.retainZone(Zone.EXILED, game);
for (Card card : cards.getCards(game)) {
card.setFaceDown(true, game);
}
game.addEffect(new JestersScepterLookAtCardEffect().setTargetPointer(new FixedTargets(cards, game)), source);
return true;
}
@Override
@ -122,26 +116,15 @@ class JestersScepterLookAtCardEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(objectId);
if (card != null) {
MageObject sourceObject = game.getObject(source);
if (sourceObject == null) {
return false;
}
UUID exileId = CardUtil.getCardExileZoneId(game, source);
ExileZone exile = game.getExile().getExileZone(exileId);
return exile != null
&& exile.contains(objectId);
}
}
return false;
return objectId != null
&& source.isControlledBy(affectedControllerId)
&& this.getTargetPointer().getTargets(game, source).contains(objectId);
}
}
class JestersScepterCost extends CostImpl {
public JestersScepterCost() {
JestersScepterCost() {
this.text = "Put a card exiled with {this} into its owner's graveyard";
}
@ -152,37 +135,31 @@ class JestersScepterCost extends CostImpl {
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
TargetCardInExile target = new TargetCardInExile(new FilterCard(), CardUtil.getCardExileZoneId(game, ability));
target.withNotTarget(true);
Cards cards = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, ability));
if (cards != null
&& !cards.isEmpty()
&& controller.choose(Outcome.Benefit, cards, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
if (controller.moveCardToGraveyardWithInfo(card, source, game, Zone.EXILED)) {
if (card instanceof SplitCard) {
game.getState().setValue(source.getSourceId() + "_nameOfExiledCardPayment", ((SplitCard) card).getLeftHalfCard().getName());
game.getState().setValue(source.getSourceId() + "_nameOfExiledCardPayment2", ((SplitCard) card).getRightHalfCard().getName());
} else if (card instanceof ModalDoubleFacedCard) {
game.getState().setValue(source.getSourceId() + "_nameOfExiledCardPayment", ((ModalDoubleFacedCard) card).getLeftHalfCard().getName());
game.getState().setValue(source.getSourceId() + "_nameOfExiledCardPayment2", ((ModalDoubleFacedCard) card).getRightHalfCard().getName());
} else {
game.getState().setValue(source.getSourceId() + "_nameOfExiledCardPayment", card.getName());
}
paid = true;
}
}
}
if (controller == null) {
return paid;
}
TargetCardInExile target = new TargetCardInExile(
0, 1, StaticFilters.FILTER_CARD, CardUtil.getExileZoneId(game, source)
);
target.withNotTarget(true);
controller.choose(Outcome.Neutral, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
return paid;
}
controller.moveCards(card, Zone.GRAVEYARD, source, game);
source.getEffects().setValue("graveyardCard", card);
paid = true;
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player player = game.getPlayer(controllerId);
return player != null;
return Optional
.ofNullable(CardUtil.getExileZoneId(game, source))
.map(game.getExile()::getExileZone)
.map(e -> !e.isEmpty())
.orElse(false);
}
@Override
@ -195,7 +172,7 @@ class JestersScepterCounterEffect extends OneShotEffect {
JestersScepterCounterEffect() {
super(Outcome.Detriment);
staticText = "Counter target spell if it has the same name as that card";
staticText = "counter target spell if it has the same name as that card";
}
private JestersScepterCounterEffect(final JestersScepterCounterEffect effect) {
@ -205,15 +182,11 @@ class JestersScepterCounterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
if (spell != null) {
String nameOfExiledCardPayment = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment");
String nameOfExiledCardPayment2 = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment2");
if (CardUtil.haveSameNames(spell.getCard(), nameOfExiledCardPayment, game)
|| CardUtil.haveSameNames(spell.getCard(), nameOfExiledCardPayment2, game)) {
return game.getStack().counter(getTargetPointer().getFirst(game, source), source, game);
}
}
return false;
Card card = (Card) getValue("graveyardCard");
return spell != null
&& card != null
&& spell.sharesName(card, game)
&& game.getStack().counter(getTargetPointer().getFirst(game, source), source, game);
}
@Override