This commit is contained in:
jeffwadsworth 2019-12-31 15:40:13 -06:00
parent 06657e4980
commit 13cb86d69f
9 changed files with 152 additions and 78 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.c;
import java.util.ArrayList;
@ -32,7 +31,8 @@ public final class Counterlash extends CardImpl {
public Counterlash(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}");
// Counter target spell. You may cast a nonland card in your hand that shares a card type with that spell without paying its mana cost.
// Counter target spell. You may cast a nonland card in your hand
// that shares a card type with that spell without paying its mana cost.
this.getSpellAbility().addTarget(new TargetSpell());
this.getSpellAbility().addEffect(new CounterlashEffect());
}
@ -51,7 +51,9 @@ class CounterlashEffect extends OneShotEffect {
public CounterlashEffect() {
super(Outcome.Detriment);
this.staticText = "Counter target spell. You may cast a nonland card in your hand that shares a card type with that spell without paying its mana cost";
this.staticText = "Counter target spell. You may cast a nonland "
+ "card in your hand that shares a card type with that "
+ "spell without paying its mana cost";
}
public CounterlashEffect(final CounterlashEffect effect) {
@ -66,10 +68,12 @@ class CounterlashEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
Player player = game.getPlayer(source.getControllerId());
if (stackObject != null && player != null) {
Player controller = game.getPlayer(source.getControllerId());
if (stackObject != null
&& controller != null) {
game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game);
if (player.chooseUse(Outcome.PutCardInPlay, "Cast a nonland card in your hand that shares a card type with that spell without paying its mana cost?", source, game)) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast a nonland card in your hand that "
+ "shares a card type with that spell without paying its mana cost?", source, game)) {
FilterCard filter = new FilterCard();
List<Predicate<MageObject>> types = new ArrayList<>();
for (CardType type : stackObject.getCardType()) {
@ -79,10 +83,13 @@ class CounterlashEffect extends OneShotEffect {
}
filter.add(Predicates.or(types));
TargetCardInHand target = new TargetCardInHand(filter);
if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}

View file

@ -41,7 +41,8 @@ public final class Guile extends CardImpl {
// Guile can't be blocked except by three or more creatures.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByOneEffect(3)));
// If a spell or ability you control would counter a spell, instead exile that spell and you may play that card without paying its mana cost.
// If a spell or ability you control would counter a spell, instead exile that
// spell and you may play that card without paying its mana cost.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GuileReplacementEffect()));
// When Guile is put into a graveyard from anywhere, shuffle it into its owner's library.
@ -62,7 +63,8 @@ class GuileReplacementEffect extends ReplacementEffectImpl {
GuileReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Exile);
staticText = "If a spell or ability you control would counter a spell, instead exile that spell and you may play that card without paying its mana cost";
staticText = "If a spell or ability you control would counter a spell, "
+ "instead exile that spell and you may play that card without paying its mana cost";
}
GuileReplacementEffect(final GuileReplacementEffect effect) {
@ -83,11 +85,13 @@ class GuileReplacementEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Spell spell = game.getStack().getSpell(event.getTargetId());
Player controller = game.getPlayer(source.getControllerId());
if (spell != null && controller != null) {
if (spell != null
&& controller != null) {
controller.moveCards(spell, Zone.EXILED, source, game);
if (!spell.isCopy()) {
Card spellCard = spell.getCard();
if (spellCard != null && controller.chooseUse(Outcome.PlayForFree, "Cast " + spellCard.getIdName() + " for free?", source, game)) {
if (spellCard != null
&& controller.chooseUse(Outcome.PlayForFree, "Play " + spellCard.getIdName() + " for free?", source, game)) {
controller.playCard(spellCard, game, true, true, new MageObjectReference(source.getSourceObject(game), game));
}
return true;

View file

@ -47,8 +47,11 @@ public final class JelevaNephaliasScourge extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Jeleva, Nephalia's Scourge enters the battlefield, each player exiles the top X cards of their library, where X is the amount of mana spent to cast Jeleva.
// When Jeleva, Nephalia's Scourge enters the battlefield, each player exiles
// the top X cards of their library, where X is the amount of mana spent to cast Jeleva.
this.addAbility(new EntersBattlefieldTriggeredAbility(new JelevaNephaliasScourgeEffect(), false));
// Whenever Jeleva attacks, you may cast an instant or sorcery card exiled with it without paying its mana cost.
this.addAbility(new AttacksTriggeredAbility(new JelevaNephaliasCastEffect(), false), new JelevaNephaliasWatcher());
@ -68,7 +71,8 @@ class JelevaNephaliasScourgeEffect extends OneShotEffect {
public JelevaNephaliasScourgeEffect() {
super(Outcome.Benefit);
this.staticText = "each player exiles the top X cards of their library, where X is the amount of mana spent to cast {this}";
this.staticText = "each player exiles the top X cards of their library, "
+ "where X is the amount of mana spent to cast {this}";
}
public JelevaNephaliasScourgeEffect(final JelevaNephaliasScourgeEffect effect) {
@ -85,13 +89,16 @@ class JelevaNephaliasScourgeEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
JelevaNephaliasWatcher watcher = game.getState().getWatcher(JelevaNephaliasWatcher.class);
if (controller != null && sourceObject != null && watcher != null) {
if (controller != null
&& sourceObject != null
&& watcher != null) {
int xValue = watcher.getManaSpentToCastLastTime(sourceObject.getId(), sourceObject.getZoneChangeCounter(game) - 1);
if (xValue > 0) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
player.moveCardsToExile(player.getLibrary().getTopCards(game, xValue), source, game, true, CardUtil.getCardExileZoneId(game, source), sourceObject.getIdName());
player.moveCardsToExile(player.getLibrary().getTopCards(game, xValue),
source, game, true, CardUtil.getCardExileZoneId(game, source), sourceObject.getIdName());
}
}
}
@ -105,7 +112,8 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
public JelevaNephaliasCastEffect() {
super(Outcome.PlayForFree);
this.staticText = "you may cast an instant or sorcery card exiled with it without paying its mana cost";
this.staticText = "you may cast an instant or sorcery card "
+ "exiled with it without paying its mana cost";
}
public JelevaNephaliasCastEffect(final JelevaNephaliasCastEffect effect) {
@ -122,13 +130,20 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (exileZone != null && exileZone.count(new FilterInstantOrSorceryCard(), game) > 0) {
if (controller.chooseUse(outcome, "Cast an instant or sorcery card from exile?", source, game)) {
TargetCardInExile target = new TargetCardInExile(new FilterInstantOrSorceryCard(), CardUtil.getCardExileZoneId(game, source));
if (exileZone != null
&& exileZone.count(new FilterInstantOrSorceryCard(), game) > 0) {
if (controller.chooseUse(outcome, "Cast an instant or sorcery card from "
+ "exile without paying its mana cost?", source, game)) {
TargetCardInExile target = new TargetCardInExile(
new FilterInstantOrSorceryCard(), CardUtil.getCardExileZoneId(game, source));
if (controller.choose(Outcome.PlayForFree, exileZone, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
return controller.playCard(card, game, true, false, new MageObjectReference(source.getSourceId(), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return cardWasCast;
}
}
}
@ -164,7 +179,8 @@ class JelevaNephaliasWatcher extends Watcher {
for (StackObject stackObject : game.getStack()) {
if (stackObject instanceof Spell) {
Spell spell = (Spell) stackObject;
manaSpendToCast.putIfAbsent(spell.getSourceId().toString() + spell.getCard().getZoneChangeCounter(game),
manaSpendToCast.putIfAbsent(spell.getSourceId().toString()
+ spell.getCard().getZoneChangeCounter(game),
spell.getSpellAbility().getManaCostsToPay().convertedManaCost());
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.m;
import java.util.UUID;
@ -10,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -53,8 +53,9 @@ public final class MemoryPlunder extends CardImpl {
class MemoryPlunderEffect extends OneShotEffect {
public MemoryPlunderEffect() {
super(Outcome.Benefit);
this.staticText = "You may cast target instant or sorcery card from an opponent's graveyard without paying its mana cost";
super(Outcome.PlayForFree);
this.staticText = "You may cast target instant or sorcery card from "
+ "an opponent's graveyard without paying its mana cost";
}
public MemoryPlunderEffect(final MemoryPlunderEffect effect) {
@ -70,9 +71,15 @@ class MemoryPlunderEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() + " without paying cost?", source, game)) {
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
Player controller = game.getPlayer(source.getControllerId());
if (controller != null
&& game.getState().getZone(card.getId()) == Zone.GRAVEYARD
&& controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return cardWasCast;
}
}
return false;

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common;
import mage.MageObjectReference;
@ -35,8 +34,13 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card target = (Card) game.getObject(source.getFirstTarget());
if (controller != null && target != null) {
return controller.cast(target.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
if (controller != null
&& target != null) {
game.getState().setValue("PlayFromNotOwnHandZone" + target.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(target, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + target.getId(), null);
return cardWasCast;
}
return false;
}

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common.cost;
import mage.MageObjectReference;
@ -40,7 +39,8 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect {
public CastWithoutPayingManaCostEffect(DynamicValue maxCost) {
super(Outcome.PlayForFree);
this.manaCost = maxCost;
this.staticText = "you may cast a card with converted mana cost " + maxCost + " or less from your hand without paying its mana cost";
this.staticText = "you may cast a card with converted mana cost "
+ maxCost + " or less from your hand without paying its mana cost";
}
public CastWithoutPayingManaCostEffect(final CastWithoutPayingManaCostEffect effect) {
@ -56,21 +56,24 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect {
return false;
}
int cmc = manaCost.calculate(game, source, this);
FilterCard filter = new FilterNonlandCard("card with converted mana cost " + cmc + " or less from your hand");
FilterCard filter = new FilterNonlandCard("card with converted mana cost "
+ cmc + " or less from your hand");
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, cmc + 1));
Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game)
&& controller.chooseUse(outcome, "Cast a card with converted mana cost " + cmc
&& controller.chooseUse(Outcome.PlayForFree, "Cast a card with converted mana cost " + cmc
+ " or less from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null;
boolean cancel = false;
while (controller.canRespond() && !cancel) {
if (controller.chooseTarget(outcome, target, source, game)) {
while (controller.canRespond()
&& !cancel) {
if (controller.chooseTarget(Outcome.PlayForFree, target, source, game)) {
cardToCast = game.getCard(target.getFirstTarget());
if (cardToCast != null) {
if (cardToCast.getSpellAbility() == null) {
Logger.getLogger(CastWithoutPayingManaCostEffect.class).fatal("Card: " + cardToCast.getName() + " is no land and has no spell ability!");
Logger.getLogger(CastWithoutPayingManaCostEffect.class).fatal("Card: "
+ cardToCast.getName() + " is no land and has no spell ability!");
cancel = true;
}
if (cardToCast.getSpellAbility().canChooseTarget(game)) {
@ -82,7 +85,10 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(cardToCast, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), null);
}
}
return true;

View file

@ -20,8 +20,11 @@ import mage.players.Player;
public class CascadeAbility extends TriggeredAbilityImpl {
//20091005 - 702.82
private static final String REMINDERTEXT = " <i>(When you cast this spell, exile cards from the top of your library until you exile a nonland card that costs less."
+ " You may cast it without paying its mana cost. Put the exiled cards on the bottom in a random order.)</i>";
private static final String REMINDERTEXT = " <i>(When you cast this spell, "
+ "exile cards from the top of your library until you exile a "
+ "nonland card that costs less."
+ " You may cast it without paying its mana cost. "
+ "Put the exiled cards on the bottom in a random order.)</i>";
private boolean withReminder;
public CascadeAbility() {
@ -46,7 +49,8 @@ public class CascadeAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Spell spell = game.getStack().getSpell(event.getTargetId());
return spell != null && spell.getSourceId().equals(this.getSourceId());
return spell != null
&& spell.getSourceId().equals(this.getSourceId());
}
@Override
@ -82,7 +86,8 @@ class CascadeEffect extends OneShotEffect {
if (controller == null) {
return false;
}
ExileZone exile = game.getExile().createZone(source.getSourceId(), controller.getName() + " Cascade");
ExileZone exile = game.getExile().createZone(source.getSourceId(),
controller.getName() + " Cascade");
card = game.getCard(source.getSourceId());
if (card == null) {
return false;
@ -102,7 +107,10 @@ class CascadeEffect extends OneShotEffect {
if (card != null) {
if (controller.chooseUse(outcome, "Use cascade effect on " + card.getLogName() + '?', source, game)) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
// Move the remaining cards to the buttom of the library in a random order

View file

@ -3,7 +3,6 @@ package mage.abilities.keyword;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.effects.OneShotEffect;
@ -64,7 +63,9 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
ReboundCastFromHandReplacementEffect() {
super(Duration.WhileOnStack, Outcome.Benefit);
this.staticText = "Rebound <i>(If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)</i>";
this.staticText = "Rebound <i>(If you cast this spell from your hand, "
+ "exile it as it resolves. At the beginning of your next upkeep, "
+ "you may cast this card from exile without paying its mana cost.)</i>";
}
ReboundCastFromHandReplacementEffect(ReboundCastFromHandReplacementEffect effect) {
@ -83,7 +84,8 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
&& event.getSourceId() != null
&& event.getSourceId().equals(source.getSourceId())) { // if countered the source.sourceId is different or null if it fizzles
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getFromZone() == Zone.HAND) {
if (spell != null
&& spell.getFromZone() == Zone.HAND) {
return true;
}
}
@ -101,10 +103,12 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
Player player = game.getPlayer(sourceCard.getOwnerId());
if (player != null) {
// Add the delayed triggered effect
ReboundEffectCastFromExileDelayedTrigger trigger = new ReboundEffectCastFromExileDelayedTrigger(source.getSourceId(), source.getSourceId());
ReboundEffectCastFromExileDelayedTrigger trigger
= new ReboundEffectCastFromExileDelayedTrigger(source.getSourceId(), source.getSourceId());
game.addDelayedTriggeredAbility(trigger, source);
player.moveCardToExileWithInfo(sourceCard, sourceCard.getId(), player.getName() + " Rebound", source.getSourceId(), game, Zone.STACK, true);
player.moveCardToExileWithInfo(sourceCard, sourceCard.getId(),
player.getName() + " Rebound", source.getSourceId(), game, Zone.STACK, true);
return true;
}
}
@ -160,10 +164,11 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
*/
class ReboundCastSpellFromExileEffect extends OneShotEffect {
private static String castFromExileText = "Rebound - You may cast {this} from exile without paying its mana cost";
private static String castFromExileText = "Rebound - You may cast {this} "
+ "from exile without paying its mana cost";
ReboundCastSpellFromExileEffect() {
super(Outcome.Benefit);
super(Outcome.PlayForFree);
staticText = castFromExileText;
}
@ -174,16 +179,19 @@ class ReboundCastSpellFromExileEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
ExileZone zone = game.getExile().getExileZone(source.getSourceId());
if (zone == null || zone.isEmpty()) {
if (zone == null
|| zone.isEmpty()) {
return false;
}
Card reboundCard = zone.get(source.getSourceId(), game);
Player player = game.getPlayer(source.getControllerId());
if (player != null && reboundCard != null) {
SpellAbility ability = reboundCard.getSpellAbility();
player.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game));
zone.remove(reboundCard.getId());
return true;
if (player != null
&& reboundCard != null) {
game.getState().setValue("PlayFromNotOwnHandZone" + reboundCard.getId(), Boolean.TRUE);
Boolean cardWasCast = player.cast(player.chooseAbilityForCast(reboundCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + reboundCard.getId(), null);
return cardWasCast;
}
return false;
}

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword;
import java.util.ArrayList;
@ -97,10 +96,9 @@ import mage.target.targetpointer.FixedTarget;
* has enough mana in their mana pool to pay the cost, that player must do so.
* If the player can't possibly pay the cost, the card remains removed from the
* game. However, if the player has the means to produce enough mana to pay the
* cost, then they have a choice: The player may play the spell, produce
* mana, and pay the cost. Or the player may choose to play no mana abilities,
* thus making the card impossible to play because the additional mana can't be
* paid.
* cost, then they have a choice: The player may play the spell, produce mana,
* and pay the cost. Or the player may choose to play no mana abilities, thus
* making the card impossible to play because the additional mana can't be paid.
*
* A creature played via suspend comes into play with haste. It still has haste
* after the first turn it's in play as long as the same player controls it. As
@ -140,15 +138,19 @@ public class SuspendAbility extends SpecialAction {
}
StringBuilder sb = new StringBuilder("Suspend ");
if (cost != null) {
sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append("&mdash;").append(cost.getText()).append(suspend == Integer.MAX_VALUE ? ". X can't be 0" : "");
sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append("&mdash;").append(cost.getText()).append(suspend
== Integer.MAX_VALUE ? ". X can't be 0" : "");
if (!shortRule) {
sb.append(" <i>(Rather than cast this card from your hand, pay ")
.append(cost.getText())
.append(" and exile it with ")
.append((suspend == 1 ? "a time counter" : (suspend == Integer.MAX_VALUE ? "X time counters" : suspend + " time counters")))
.append((suspend == 1 ? "a time counter" : (suspend == Integer.MAX_VALUE
? "X time counters" : suspend + " time counters")))
.append(" on it.")
.append(" At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost.")
.append(card.isCreature() ? " If you play it this way and it's a creature, it gains haste until you lose control of it." : "")
.append(" At the beginning of your upkeep, remove a time counter. "
+ "When the last is removed, cast it without paying its mana cost.")
.append(card.isCreature() ? " If you play it this way and it's a creature, "
+ "it gains haste until you lose control of it." : "")
.append(")</i>");
}
if (card.getManaCost().isEmpty()) {
@ -174,7 +176,8 @@ public class SuspendAbility extends SpecialAction {
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
SuspendBeginningOfUpkeepInterveningIfTriggeredAbility ability1 = new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility();
SuspendBeginningOfUpkeepInterveningIfTriggeredAbility ability1 =
new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility();
ability1.setSourceId(card.getId());
ability1.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability1);
@ -211,7 +214,8 @@ public class SuspendAbility extends SpecialAction {
MageObject object = game.getObject(sourceId);
return new ActivationStatus(object.isInstant()
|| object.hasAbility(FlashAbility.getInstance().getId(), game)
|| null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game)
|| null != game.getContinuousEffects().asThough(sourceId,
AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game)
|| game.canPlaySorcery(playerId), null);
}
@ -237,7 +241,8 @@ class SuspendExileEffect extends OneShotEffect {
public SuspendExileEffect(int suspend) {
super(Outcome.PutCardInPlay);
this.staticText = new StringBuilder("Suspend ").append(suspend == Integer.MAX_VALUE ? "X" : suspend).toString();
this.staticText = new StringBuilder("Suspend ").append(suspend
== Integer.MAX_VALUE ? "X" : suspend).toString();
this.suspend = suspend;
}
@ -257,7 +262,8 @@ class SuspendExileEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (card != null && controller != null) {
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of " + controller.getName(), source.getSourceId(), game, Zone.HAND, true)) {
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of "
+ controller.getName(), source.getSourceId(), game, Zone.HAND, true)) {
if (suspend == Integer.MAX_VALUE) {
suspend = source.getManaCostsToPay().getX();
}
@ -292,7 +298,8 @@ class SuspendPlayCardAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(getSourceId())) {
Card card = game.getCard(getSourceId());
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED
if (card != null
&& game.getState().getZone(card.getId()) == Zone.EXILED
&& card.getCounters(game).getCount(CounterType.TIME) == 0) {
return true;
}
@ -314,7 +321,7 @@ class SuspendPlayCardAbility extends TriggeredAbilityImpl {
class SuspendPlayCardEffect extends OneShotEffect {
public SuspendPlayCardEffect() {
super(Outcome.PutCardInPlay);
super(Outcome.PlayForFree);
this.staticText = "play it without paying its mana cost if able. If you can't, it remains removed from the game";
}
@ -343,7 +350,8 @@ class SuspendPlayCardEffect extends OneShotEffect {
}
if (!abilitiesToRemove.isEmpty()) {
for (Ability ability : card.getAbilities()) {
if (ability instanceof SuspendBeginningOfUpkeepInterveningIfTriggeredAbility || ability instanceof SuspendPlayCardAbility) {
if (ability instanceof SuspendBeginningOfUpkeepInterveningIfTriggeredAbility
|| ability instanceof SuspendPlayCardAbility) {
abilitiesToRemove.add(ability);
}
}
@ -351,7 +359,11 @@ class SuspendPlayCardEffect extends OneShotEffect {
card.getAbilities().removeAll(abilitiesToRemove);
}
// cast the card for free
if (player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = player.cast(player.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
if (card.isCreature()) {
ContinuousEffect effect = new GainHasteEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game) + 1));
@ -397,7 +409,8 @@ class GainHasteEffect extends ContinuousEffectImpl {
}
return true;
}
if (game.getState().getZoneChangeCounter(((FixedTarget) getTargetPointer()).getTarget()) >= ((FixedTarget) getTargetPointer()).getZoneChangeCounter()) {
if (game.getState().getZoneChangeCounter(((FixedTarget) getTargetPointer()).getTarget())
>= ((FixedTarget) getTargetPointer()).getZoneChangeCounter()) {
this.discard();
}
return false;
@ -408,7 +421,8 @@ class GainHasteEffect extends ContinuousEffectImpl {
class SuspendBeginningOfUpkeepInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility {
public SuspendBeginningOfUpkeepInterveningIfTriggeredAbility() {
super(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), TargetController.YOU, false),
super(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()),
TargetController.YOU, false),
SuspendedCondition.instance,
"At the beginning of your upkeep, if this card ({this}) is suspended, remove a time counter from it.");
this.setRuleVisible(false);