[FIN] Implement Summon: Brynhildr (#13699)

* [FIN] Implement Summon: Brynhildr

* cleanup of common classes and constructors

---------

Co-authored-by: xenohedron <12538125+xenohedron@users.noreply.github.com>
This commit is contained in:
Evan Kranzler 2025-09-12 18:28:09 -04:00 committed by GitHub
parent 6d0dc2f0df
commit 652ca6c9e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 288 additions and 167 deletions

View file

@ -1,8 +1,7 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.common.delayed.CastNextSpellDelayedTriggeredAbility;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
import mage.abilities.keyword.ConvokeAbility;
@ -10,11 +9,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
import java.util.UUID;
@ -40,10 +36,9 @@ public final class CompleteTheCircuit extends CardImpl {
// When you next cast an instant or sorcery spell this turn, copy that spell twice. You may choose new targets for the copies.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(
new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY,
new CompleteTheCircuitEffect(), "When you next cast an instant or sorcery spell " +
"this turn, copy that spell twice. You may choose new targets for the copies."
new CastNextSpellDelayedTriggeredAbility(
new CopyTargetStackObjectEffect(false, true, true, 2, null),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, true
)
).concatBy("<br>"));
}
@ -57,29 +52,3 @@ public final class CompleteTheCircuit extends CardImpl {
return new CompleteTheCircuit(this);
}
}
class CompleteTheCircuitEffect extends OneShotEffect {
CompleteTheCircuitEffect() {
super(Outcome.Benefit);
}
private CompleteTheCircuitEffect(final CompleteTheCircuitEffect effect) {
super(effect);
}
@Override
public CompleteTheCircuitEffect copy() {
return new CompleteTheCircuitEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = (Spell) getValue("spellCast");
if (spell != null) {
spell.createCopyOnStack(game, source, source.getControllerId(), true, 2);
return true;
}
return false;
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.common.delayed.CastNextSpellDelayedTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.keyword.SunburstAbility;
@ -26,9 +26,8 @@ public final class SolarArray extends CardImpl {
// {T}: Add one mana of any color. When you next cast an artifact spell this turn, that spell gains sunburst.
AnyColorManaAbility ability = new AnyColorManaAbility();
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_AN_ARTIFACT, new SolarArrayEffect(),
"When you next cast an artifact spell this turn, that spell gains sunburst."
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new CastNextSpellDelayedTriggeredAbility(
new SolarArrayEffect(), StaticFilters.FILTER_SPELL_AN_ARTIFACT, true
)));
ability.setUndoPossible(false);
this.addAbility(ability);

View file

@ -0,0 +1,194 @@
package mage.cards.s;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.delayed.CastNextSpellDelayedTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.HasteAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.*;
/**
* @author TheElk801
*/
public final class SummonBrynhildr extends CardImpl {
public SummonBrynhildr(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.SAGA);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I -- Chain -- Exile the top card of your library. During any turn you put a lore counter on this Saga, you may play that card.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> {
ability.addEffect(new SummonBrynhildrExileEffect());
ability.withFlavorWord("Chain");
});
// II, III -- Gestalt Mode -- When you next cast a creature spell this turn, it gains haste until end of turn.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_III, ability -> {
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(
new CastNextSpellDelayedTriggeredAbility(
new SummonBrynhildrHasteEffect(), StaticFilters.FILTER_SPELL_A_CREATURE, true
)
));
ability.withFlavorWord("Gestalt Mode");
});
this.addAbility(sagaAbility.addHint(SummonBrynhildrCondition.getHint()), new SummonBrynhildrWatcher());
}
private SummonBrynhildr(final SummonBrynhildr card) {
super(card);
}
@Override
public SummonBrynhildr copy() {
return new SummonBrynhildr(this);
}
}
class SummonBrynhildrExileEffect extends OneShotEffect {
SummonBrynhildrExileEffect() {
super(Outcome.Benefit);
staticText = "exile the top card of your library. During any turn you " +
"put a lore counter on this Saga, you may play that card";
}
private SummonBrynhildrExileEffect(final SummonBrynhildrExileEffect effect) {
super(effect);
}
@Override
public SummonBrynhildrExileEffect copy() {
return new SummonBrynhildrExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Card card = player.getLibrary().getFromTop(game);
if (card == null) {
return false;
}
player.moveCards(card, Zone.EXILED, source, game);
CardUtil.makeCardPlayable(
game, source, card, false, Duration.Custom, false,
source.getControllerId(), SummonBrynhildrCondition.instance
);
return true;
}
}
enum SummonBrynhildrCondition implements Condition {
instance;
private static final Hint hint = new ConditionHint(instance);
public static Hint getHint() {
return hint;
}
@Override
public boolean apply(Game game, Ability source) {
return SummonBrynhildrWatcher.check(game, source);
}
@Override
public String toString() {
return "You put a lore counter on this permanent this turn";
}
}
class SummonBrynhildrWatcher extends Watcher {
private final Map<MageObjectReference, Set<UUID>> map = new HashMap<>();
SummonBrynhildrWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.COUNTER_ADDED
|| !CounterType.STUN.getName().equals(event.getData())) {
return;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
map.computeIfAbsent(new MageObjectReference(permanent, game), x -> new HashSet<>())
.add(event.getPlayerId());
}
}
@Override
public void reset() {
super.reset();
map.clear();
}
static boolean check(Game game, Ability source) {
return game.getState()
.getWatcher(SummonBrynhildrWatcher.class)
.map
.getOrDefault(new MageObjectReference(
source.getSourceId(), source.getStackMomentSourceZCC(), game
), Collections.emptySet())
.contains(source.getControllerId());
}
}
class SummonBrynhildrHasteEffect extends OneShotEffect {
SummonBrynhildrHasteEffect() {
super(Outcome.Benefit);
staticText = "it gains haste until end of turn";
}
private SummonBrynhildrHasteEffect(final SummonBrynhildrHasteEffect effect) {
super(effect);
}
@Override
public SummonBrynhildrHasteEffect copy() {
return new SummonBrynhildrHasteEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = (Spell) getValue("spellCast");
if (spell != null) {
game.getState().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance())
.setTargetPointer(new FixedTarget(spell.getCard().getId())), source);
}
return true;
}
}

View file

@ -1,21 +1,16 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
import java.util.UUID;
@ -47,9 +42,7 @@ public final class SummonGFCerberus extends CardImpl {
// III -- Triple -- When you next cast an instant or sorcery spell this turn, copy it twice. You may choose new targets for the copies.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> {
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, new SummonGFCerberusEffect(),
"When you next cast an instant or sorcery spell this turn, " +
"copy it twice. You may choose new targets for the copies."
StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, 2
)));
ability.withFlavorWord("Triple");
});
@ -65,29 +58,3 @@ public final class SummonGFCerberus extends CardImpl {
return new SummonGFCerberus(this);
}
}
class SummonGFCerberusEffect extends OneShotEffect {
SummonGFCerberusEffect() {
super(Outcome.Benefit);
}
private SummonGFCerberusEffect(final SummonGFCerberusEffect effect) {
super(effect);
}
@Override
public SummonGFCerberusEffect copy() {
return new SummonGFCerberusEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = (Spell) getValue("spellCast");
if (spell != null) {
spell.createCopyOnStack(game, source, source.getControllerId(), true, 2);
return true;
}
return false;
}
}

View file

@ -2,7 +2,7 @@ package mage.cards.t;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.common.delayed.CastNextSpellDelayedTriggeredAbility;
import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
@ -43,10 +43,10 @@ public final class TheCloneSaga extends CardImpl {
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new SurveilEffect(3));
// II -- When you next cast a creature spell this turn, copy it, except the copy isn't legendary.
DelayedTriggeredAbility ability = new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_A_CREATURE,
new CopyTargetStackObjectEffect(false, false, false, 1, new RemoveTypeCopyApplier(SuperType.LEGENDARY)),
"When you next cast a creature spell this turn, copy it, except the copy isn't legendary"
DelayedTriggeredAbility ability = new CastNextSpellDelayedTriggeredAbility(
new CopyTargetStackObjectEffect(false, true, false, 1, new RemoveTypeCopyApplier(SuperType.LEGENDARY))
.setText("copy it, except the copy isn't legendary"),
StaticFilters.FILTER_SPELL_A_CREATURE, true
);
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new CreateDelayedTriggeredAbilityEffect(ability));

View file

@ -4,7 +4,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.common.delayed.CastNextSpellDelayedTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.CommanderCastFromCommandZoneValue;
@ -49,15 +49,9 @@ public final class ThunderclapDrake extends CardImpl {
// {2}{U}, Sacrifice Thunderclap Drake: When you cast your next instant or sorcery spell this turn, copy it for each time you've cast your commander from the command zone this game. You may choose new targets for the copies.
Ability ability = new SimpleActivatedAbility(
new CreateDelayedTriggeredAbilityEffect(
new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY,
new ThunderclapDrakeEffect(),
"When you next cast an instant or sorcery spell this turn, "
+ "copy it for each time you've cast your commander from the command zone this game. "
+ "You may choose new targets for the copies."
)
),
new CreateDelayedTriggeredAbilityEffect(new CastNextSpellDelayedTriggeredAbility(
new ThunderclapDrakeEffect(), StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, true
)),
new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new SacrificeSourceCost());

View file

@ -512,6 +512,8 @@ public final class FinalFantasy extends ExpansionSet {
cards.add(new SetCardInfo("Summon: Anima", 364, Rarity.UNCOMMON, mage.cards.s.SummonAnima.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Bahamut", 1, Rarity.MYTHIC, mage.cards.s.SummonBahamut.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Bahamut", 356, Rarity.MYTHIC, mage.cards.s.SummonBahamut.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Brynhildr", 160, Rarity.RARE, mage.cards.s.SummonBrynhildr.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Brynhildr", 366, Rarity.RARE, mage.cards.s.SummonBrynhildr.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Choco/Mog", 35, Rarity.COMMON, mage.cards.s.SummonChocoMog.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Choco/Mog", 358, Rarity.COMMON, mage.cards.s.SummonChocoMog.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Summon: Esper Maduin", 185, Rarity.RARE, mage.cards.s.SummonEsperMaduin.class, NON_FULL_USE_VARIOUS));

View file

@ -1,7 +1,6 @@
package mage.abilities.common.delayed;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
@ -18,9 +17,7 @@ import mage.util.CardUtil;
/**
* @author TheElk801
*/
public class AddCounterNextSpellDelayedTriggeredAbility extends DelayedTriggeredAbility {
private final FilterSpell filter;
public class AddCounterNextSpellDelayedTriggeredAbility extends CastNextSpellDelayedTriggeredAbility {
public AddCounterNextSpellDelayedTriggeredAbility() {
this(StaticFilters.FILTER_SPELL_A_CREATURE);
@ -31,38 +28,17 @@ public class AddCounterNextSpellDelayedTriggeredAbility extends DelayedTriggered
}
public AddCounterNextSpellDelayedTriggeredAbility(int amount, FilterSpell filter) {
super(new AddCounterNextSpellEffect(amount), Duration.EndOfTurn, true, false);
this.filter = filter;
this.setTriggerPhrase("When you next cast " + filter.getMessage() + " this turn, ");
super(new AddCounterNextSpellEffect(amount), filter, false);
}
private AddCounterNextSpellDelayedTriggeredAbility(final AddCounterNextSpellDelayedTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
}
@Override
public AddCounterNextSpellDelayedTriggeredAbility copy() {
return new AddCounterNextSpellDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Spell spell = game.getSpell(event.getTargetId());
if (spell == null || !filter.match(spell, getControllerId(), this, game)) {
return false;
}
this.getEffects().setValue("spellCast", spell);
return true;
}
}
class AddCounterNextSpellEffect extends ReplacementEffectImpl {
@ -72,7 +48,8 @@ class AddCounterNextSpellEffect extends ReplacementEffectImpl {
AddCounterNextSpellEffect(int amount) {
super(Duration.EndOfStep, Outcome.BoostCreature);
this.amount = amount;
staticText = "that creature enters with " + CardUtil.numberToText(amount, "an") + " additional +1/+1 counter" + (amount > 1 ? "s" : "") + " on it";
staticText = "that creature enters with " + CardUtil.numberToText(amount, "an") +
" additional +1/+1 counter" + (amount > 1 ? "s" : "") + " on it";
}
private AddCounterNextSpellEffect(AddCounterNextSpellEffect effect) {

View file

@ -0,0 +1,59 @@
package mage.abilities.common.delayed;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.constants.Duration;
import mage.filter.FilterSpell;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget;
/**
* @author TheElk801
*/
public class CastNextSpellDelayedTriggeredAbility extends DelayedTriggeredAbility {
private final FilterSpell filter;
private final boolean setTargetPointer;
public CastNextSpellDelayedTriggeredAbility(Effect effect, FilterSpell filter, boolean setTargetPointer) {
super(effect, Duration.EndOfTurn, true, false);
this.filter = filter;
this.setTriggerPhrase("When you next cast " + filter.getMessage() + " this turn, ");
this.setTargetPointer = setTargetPointer;
}
protected CastNextSpellDelayedTriggeredAbility(final CastNextSpellDelayedTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.setTargetPointer = ability.setTargetPointer;
}
@Override
public CastNextSpellDelayedTriggeredAbility copy() {
return new CastNextSpellDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Spell spell = game.getSpell(event.getTargetId());
if (spell == null || !filter.match(spell, getControllerId(), this, game)) {
return false;
}
this.getEffects().setValue("spellCast", spell);
if (setTargetPointer) {
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
}
return true;
}
}

View file

@ -1,75 +1,32 @@
package mage.abilities.common.delayed;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.constants.Duration;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
* @author TheElk801
*/
public class CopyNextSpellDelayedTriggeredAbility extends DelayedTriggeredAbility {
private final FilterSpell filter;
private final String rule;
public class CopyNextSpellDelayedTriggeredAbility extends CastNextSpellDelayedTriggeredAbility {
public CopyNextSpellDelayedTriggeredAbility() {
this(StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY);
}
public CopyNextSpellDelayedTriggeredAbility(FilterSpell filter) {
this(filter, new CopyTargetStackObjectEffect(true), null);
this(filter, 1);
}
public CopyNextSpellDelayedTriggeredAbility(FilterSpell filter, Effect effect, String rule) {
super(effect, Duration.EndOfTurn);
this.filter = filter;
this.rule = rule;
public CopyNextSpellDelayedTriggeredAbility(FilterSpell filter, int amount) {
super(new CopyTargetStackObjectEffect(false, true, true, amount, null), filter, true);
}
protected CopyNextSpellDelayedTriggeredAbility(final CopyNextSpellDelayedTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.rule = ability.rule;
}
@Override
public CopyNextSpellDelayedTriggeredAbility copy() {
return new CopyNextSpellDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell == null || !filter.match(spell, getControllerId(), this, game)) {
return false;
}
this.getEffects().setValue("spellCast", spell);
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
return true;
}
@Override
public String getRule() {
if (rule != null && !rule.isEmpty()) {
return rule;
}
return "When you next cast " + CardUtil.addArticle(filter.getMessage()) + " this turn, "
+ "copy that spell. You may choose new targets for the copy.";
}
}

View file

@ -7,6 +7,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.StackObject;
import mage.util.CardUtil;
import mage.util.functions.StackObjectCopyApplier;
/**
@ -96,8 +97,10 @@ public class CopyTargetStackObjectEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return "copy " +
getTargetPointer().describeTargets(mode.getTargets(), objectName) +
(chooseTargets ? ". You may choose new targets for the copy" : "");
String amountText = (amount == 1) ? "" : ((amount == 2) ? " twice" : " " + CardUtil.numberToText(amount) + " times");
String chooseText = chooseTargets ? ". You may choose new targets for the cop" + ((amount == 1) ? "y" : "ies") : "";
return "copy "
+ getTargetPointer().describeTargets(mode.getTargets(), objectName)
+ amountText + chooseText;
}
}