forked from External/mage
Merge pull request #2948 from ImperatorPrime/phyrexian-mana-fix
Phyrexian mana now correctly a payment choice.
This commit is contained in:
commit
ef29fab8ea
47 changed files with 234 additions and 222 deletions
|
|
@ -148,7 +148,6 @@ public final class UI {
|
|||
}
|
||||
|
||||
public static String getDisplayManaCost (String manaCost) {
|
||||
manaCost = manaCost.replace("/", "");
|
||||
// A pipe in the cost means "process left of the pipe as the card color, but display right of the pipe as the cost".
|
||||
int pipePosition = manaCost.indexOf("{|}");
|
||||
if (pipePosition != -1) {
|
||||
|
|
|
|||
|
|
@ -823,9 +823,6 @@ public class HumanPlayer extends PlayerImpl {
|
|||
protected boolean playManaHandling(Ability abilityToCast, ManaCost unpaid, String promptText, Game game) {
|
||||
updateGameStatePriority("playMana", game);
|
||||
Map<String, Serializable> options = new HashMap<>();
|
||||
if (unpaid.getText().contains("P}")) {
|
||||
options.put(Constants.Option.SPECIAL_BUTTON, (Serializable) "Pay 2 life");
|
||||
}
|
||||
game.firePlayManaEvent(playerId, "Pay " + promptText, options);
|
||||
waitForResponse(game);
|
||||
if (!this.canRespond()) {
|
||||
|
|
@ -838,18 +835,6 @@ public class HumanPlayer extends PlayerImpl {
|
|||
} else if (response.getString() != null && response.getString().equals("special")) {
|
||||
if (unpaid instanceof ManaCostsImpl) {
|
||||
specialManaAction(unpaid, game);
|
||||
// TODO: delve or convoke cards with PhyrexianManaCost won't work together (this combinaton does not exist yet)
|
||||
@SuppressWarnings("unchecked")
|
||||
ManaCostsImpl<ManaCost> costs = (ManaCostsImpl<ManaCost>) unpaid;
|
||||
for (ManaCost cost : costs.getUnpaid()) {
|
||||
if (cost instanceof PhyrexianManaCost) {
|
||||
PhyrexianManaCost ph = (PhyrexianManaCost) cost;
|
||||
if (ph.canPay(null, null, playerId, game)) {
|
||||
((PhyrexianManaCost) cost).pay(null, game, null, playerId, false, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (response.getManaType() != null) {
|
||||
// this mana type can be paid once from pool
|
||||
|
|
@ -907,7 +892,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
Spell spell = game.getStack().getSpell(abilityToCast.getSourceId());
|
||||
if (spell != null && spell.isDoneActivatingManaAbilities()) {
|
||||
game.informPlayer(this, "You can't no longer use activated mana abilities to pay for the current spell. Cancel and recast the spell and activate mana abilities first.");
|
||||
game.informPlayer(this, "You can no longer use activated mana abilities to pay for the current spell. Cancel and recast the spell and activate mana abilities first.");
|
||||
return;
|
||||
}
|
||||
Zone zone = game.getState().getZone(object.getId());
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class ActOfAggression extends CardImpl {
|
|||
}
|
||||
|
||||
public ActOfAggression(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{RP}{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R/P}{R/P}");
|
||||
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
|
||||
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn));
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ public class ApostlesBlessing extends CardImpl {
|
|||
}
|
||||
|
||||
public ApostlesBlessing(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{WP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W/P}");
|
||||
|
||||
// ({WP} can be paid with either {W} or 2 life.)
|
||||
// ({W/P} can be paid with either {W} or 2 life.)
|
||||
// Target artifact or creature you control gains protection from artifacts or from the color of your choice until end of turn.
|
||||
this.getSpellAbility().addEffect(new ApostlesBlessingEffect());
|
||||
this.getSpellAbility().addTarget(new TargetControlledPermanent(filter));
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
|||
public class BirthingPod extends CardImpl {
|
||||
|
||||
public BirthingPod(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}{GP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}{G/P}");
|
||||
|
||||
// {1}{GP}, {tap}, Sacrifice a creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost,
|
||||
// {1}{G/P}, {tap}, Sacrifice a creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost,
|
||||
// put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery.
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl("{1}{GP}"));
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl("{1}{G/P}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class BlindingSouleater extends CardImpl {
|
|||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// {WP},{T}: Tap target creature. ( can be paid with either or 2 life.)
|
||||
// {W/P},{T}: Tap target creature. ( can be paid with either or 2 life.)
|
||||
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
|
||||
new TapTargetEffect(),
|
||||
new PhyrexianManaCost(ColoredManaSymbol.W));
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ import java.util.UUID;
|
|||
public class CathedralMembrane extends CardImpl {
|
||||
|
||||
public CathedralMembrane(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{WP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{W/P}");
|
||||
this.subtype.add("Wall");
|
||||
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// <i>({WP} can be paid with either {W} or 2 life.)</i>
|
||||
// <i>({W/P} can be paid with either {W} or 2 life.)</i>
|
||||
this.addAbility(DefenderAbility.getInstance());
|
||||
|
||||
// When Cathedral Membrane dies during combat, it deals 6 damage to each creature it blocked this combat.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class CorrosiveGale extends CardImpl {
|
|||
}
|
||||
|
||||
public CorrosiveGale(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{GP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{G/P}");
|
||||
|
||||
|
||||
this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filter));
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class Dismember extends CardImpl {
|
||||
|
||||
public Dismember (UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{BP}{BP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{B/P}{B/P}");
|
||||
|
||||
|
||||
// Target creature gets -5/-5 until end of turn.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import mage.target.TargetPlayer;
|
|||
public class GitaxianProbe extends CardImpl {
|
||||
|
||||
public GitaxianProbe(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{UP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U/P}");
|
||||
|
||||
// Look at target player's hand.
|
||||
this.getSpellAbility().addEffect(new LookAtTargetPlayerHandEffect());
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.target.common.TargetCreatureOrPlayer;
|
|||
public class GutShot extends CardImpl {
|
||||
|
||||
public GutShot(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R/P}");
|
||||
|
||||
this.getSpellAbility().addEffect(new DamageTargetEffect(1));
|
||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ public class HexParasite extends CardImpl {
|
|||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// {X}{BP}: Remove up to X counters from target permanent. For each counter removed this way, Hex Parasite gets +1/+0 until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HexParasiteEffect(), new ManaCostsImpl("{X}{BP}"));
|
||||
// {X}{B/P}: Remove up to X counters from target permanent. For each counter removed this way, Hex Parasite gets +1/+0 until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HexParasiteEffect(), new ManaCostsImpl("{X}{B/P}"));
|
||||
ability.addTarget(new TargetPermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public class Lashwrithe extends CardImpl {
|
|||
this.addAbility(new LivingWeaponAbility());
|
||||
PermanentsOnBattlefieldCount value = new PermanentsOnBattlefieldCount(filter);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(value, value)));
|
||||
this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{BP}{BP}")));
|
||||
this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{B/P}{B/P}")));
|
||||
}
|
||||
|
||||
public Lashwrithe(final Lashwrithe card) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.filter.common.FilterAttackingCreature;
|
|||
public class MarrowShards extends CardImpl {
|
||||
|
||||
public MarrowShards(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{WP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W/P}");
|
||||
|
||||
|
||||
this.getSpellAbility().addEffect(new DamageAllEffect(1, new FilterAttackingCreature()));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class MentalMisstep extends CardImpl {
|
|||
}
|
||||
|
||||
public MentalMisstep(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{UP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U/P}");
|
||||
|
||||
// Counter target spell with converted mana cost 1.
|
||||
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import mage.constants.Zone;
|
|||
public class MoltensteelDragon extends CardImpl {
|
||||
|
||||
public MoltensteelDragon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{RP}{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{R/P}{R/P}");
|
||||
this.subtype.add("Dragon");
|
||||
|
||||
this.power = new MageInt(4);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class MutagenicGrowth extends CardImpl {
|
||||
|
||||
public MutagenicGrowth (UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{GP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G/P}");
|
||||
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ import mage.constants.Zone;
|
|||
public class NornsAnnex extends CardImpl {
|
||||
|
||||
public NornsAnnex(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}{WP}{WP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}{W/P}{W/P}");
|
||||
|
||||
// {WP} ({WP} can be paid with either or 2 life.)
|
||||
// Creatures can't attack you or a planeswalker you control unless their controller pays {WP} for each of those creatures.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl<>("{WP}"), true)));
|
||||
// {W/P} ({W/P} can be paid with either or 2 life.)
|
||||
// Creatures can't attack you or a planeswalker you control unless their controller pays {W/P} for each of those creatures.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl<>("{W/P}"), true)));
|
||||
}
|
||||
|
||||
public NornsAnnex(final NornsAnnex card) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import mage.target.common.TargetCardInGraveyard;
|
|||
public class NoxiousRevival extends CardImpl {
|
||||
|
||||
public NoxiousRevival (UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{GP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G/P}");
|
||||
|
||||
this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard());
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class PhyrexianMetamorph extends CardImpl {
|
|||
}
|
||||
|
||||
public PhyrexianMetamorph(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{UP}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{U/P}");
|
||||
this.subtype.add("Shapeshifter");
|
||||
|
||||
this.power = new MageInt(0);
|
||||
|
|
@ -83,7 +83,7 @@ public class PhyrexianMetamorph extends CardImpl {
|
|||
|
||||
};
|
||||
|
||||
// {UP} ( can be paid with either {U} or 2 life.)
|
||||
// {U/P} ( can be paid with either {U} or 2 life.)
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
Effect effect = new CopyPermanentEffect(filter, phyrexianMetamorphApplier);
|
||||
effect.setText("You may have {this} enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types");
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class PithDriller extends CardImpl {
|
||||
|
||||
public PithDriller(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{BP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{B/P}");
|
||||
this.subtype.add("Horror");
|
||||
|
||||
this.power = new MageInt(2);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.cards.CardSetInfo;
|
|||
public class PorcelainLegionnaire extends CardImpl {
|
||||
|
||||
public PorcelainLegionnaire(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{WP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{W/P}");
|
||||
this.subtype.add("Soldier");
|
||||
|
||||
this.power = new MageInt(3);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public class PostmortemLunge extends CardImpl {
|
||||
|
||||
public PostmortemLunge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{BP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B/P}");
|
||||
|
||||
// Return target creature card with converted mana cost X from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step.
|
||||
this.getSpellAbility().addEffect(new PostmortemLungeEffect());
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import mage.target.common.TargetCreatureOrPlayer;
|
|||
public class RageExtractor extends CardImpl {
|
||||
|
||||
public RageExtractor(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}{R/P}");
|
||||
|
||||
|
||||
this.addAbility(new RageExtractorTriggeredAbility());
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import mage.game.permanent.Permanent;
|
|||
public class RuthlessInvasion extends CardImpl {
|
||||
|
||||
public RuthlessInvasion (UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R/P}");
|
||||
|
||||
this.getSpellAbility().addEffect(new RuthlessInvasionEffect());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.cards.CardSetInfo;
|
|||
public class SlashPanther extends CardImpl {
|
||||
|
||||
public SlashPanther(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{RP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{R/P}");
|
||||
this.subtype.add("Cat");
|
||||
|
||||
this.power = new MageInt(4);
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ public class Spellskite extends CardImpl {
|
|||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// {UP}: Change a target of target spell or ability to Spellskite.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SpellskiteEffect(), new ManaCostsImpl("{UP}"));
|
||||
// {U/P}: Change a target of target spell or ability to Spellskite.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SpellskiteEffect(), new ManaCostsImpl("{U/P}"));
|
||||
ability.addTarget(new TargetStackObject());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.cards.CardSetInfo;
|
|||
public class SpinedThopter extends CardImpl {
|
||||
|
||||
public SpinedThopter(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{UP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{U/P}");
|
||||
this.subtype.add("Thopter");
|
||||
|
||||
this.power = new MageInt(2);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class SurgicalExtraction extends CardImpl {
|
|||
}
|
||||
|
||||
public SurgicalExtraction(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{BP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B/P}");
|
||||
|
||||
// Choose target card in a graveyard other than a basic land card. Search its owner's graveyard,
|
||||
// hand, and library for any number of cards with the same name as that card and exile them.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.cards.CardSetInfo;
|
|||
public class TezzeretsGambit extends CardImpl {
|
||||
|
||||
public TezzeretsGambit(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{UP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U/P}");
|
||||
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
|
||||
this.getSpellAbility().addEffect(new ProliferateEffect());
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import mage.cards.CardSetInfo;
|
|||
public class ThunderingTanadon extends CardImpl {
|
||||
|
||||
public ThunderingTanadon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{GP}{GP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{G/P}{G/P}");
|
||||
this.subtype.add("Beast");
|
||||
|
||||
this.power = new MageInt(5);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class TrespassingSouleater extends CardImpl {
|
|||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// {UP}: Trespassing Souleater can't be blocked this turn.
|
||||
// {U/P}: Trespassing Souleater can't be blocked this turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
|
||||
new CantBeBlockedSourceEffect(Duration.EndOfTurn),
|
||||
new PhyrexianManaCost(ColoredManaSymbol.U)));
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import mage.cards.CardSetInfo;
|
|||
public class VaultSkirge extends CardImpl {
|
||||
|
||||
public VaultSkirge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{BP}");
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{B/P}");
|
||||
this.subtype.add("Imp");
|
||||
|
||||
this.power = new MageInt(1);
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ public class HideousEndTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Copper Myr");
|
||||
// Target artifact or creature you control gains protection from artifacts or from the color of your choice until end of turn.
|
||||
addCard(Zone.HAND, playerB, "Apostle's Blessing");
|
||||
addCard(Zone.HAND, playerB, "Blessed Breath");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hideous End", "Copper Myr");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Apostle's Blessing", "Copper Myr");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Blessed Breath", "Copper Myr");
|
||||
setChoice(playerB, "Black");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class MimicVatTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph", 1);// Creature {3}{UP}
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph", 1);// Creature {3}{U/P}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
|
||||
addCard(Zone.HAND, playerA, "Cloudshift");
|
||||
|
||||
//Flying
|
||||
|
|
@ -64,7 +64,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
|||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerA, 22);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertGraveyardCount(playerA, "Cloudshift", 1);
|
||||
|
|
@ -87,7 +87,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
|
||||
|
||||
// Flying
|
||||
// When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
|
||||
|
|
@ -109,7 +109,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
|||
setStopAt(3, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerA, 18);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
assertPermanentCount(playerA, "Ponyback Brigade", 1);
|
||||
|
|
@ -128,7 +128,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Alloy Myr", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Kitesail", 1);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class CostModificationTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
// Look at target player's hand.
|
||||
// Draw a card.
|
||||
addCard(Zone.HAND, playerB, "Gitaxian Probe"); // Sorcery {UP}
|
||||
addCard(Zone.HAND, playerB, "Gitaxian Probe"); // Sorcery {U/P}
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Gitaxian Probe", playerA);
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
package org.mage.test.cards.single;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Created by goesta on 12/02/2017. Modified by jeffwadsworth
|
||||
*/
|
||||
public class SpellskiteTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testThatSpellSkiteCantBeTargetedTwiceOrMore() {
|
||||
/* According to rules, the same object can be a legal target only
|
||||
once for each instances of the word “target” in the text
|
||||
of a spell or ability. In this case, the target can't be changed
|
||||
due to Spellskite already being a target.
|
||||
*/
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
|
||||
addTarget(playerA, "Scute Mob");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Spellskite");
|
||||
setChoice(playerA, "X=4");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 2);
|
||||
}
|
||||
|
||||
public void testThatSplitDamageCanGetRedirected() {
|
||||
/* Standard redirect test
|
||||
The Spellskite should die from the 5 damage that was redirected to it
|
||||
*/
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob"); // 1/1 creauture
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Scute Mob");
|
||||
setChoice(playerA, "X=5");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 1);
|
||||
assertPermanentCount(playerB, "Scute Mob", 1);
|
||||
}
|
||||
|
||||
public void testThatSplitDamageGetsRedirectedFromTheCorrectChoice() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Memnite"); // 1/1 creauture
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Royal Assassin");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Memnite");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Royal Assassin");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Blinking Spirit");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Pearled Unicorn");
|
||||
setChoice(playerA, "X=2");//the unicorn deserves it
|
||||
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "Yes"); //of course
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 3);
|
||||
assertPermanentCount(playerB, "Pearled Unicorn", 1);//it lives on
|
||||
assertPowerToughness(playerB, "Spellskite", 0, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,13 +52,13 @@ public class BecomesTheTargetTest extends CardTestPlayerBase {
|
|||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{WP},{T}: Tap target creature", "Silvercoat Lion");
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P},{T}: Tap target creature", "Silvercoat Lion");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 0);
|
||||
assertTapped("Silvercoat Lion", true);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public class SacredGroundTest extends CardTestPlayerBase {
|
|||
// Choose target card in a graveyard other than a basic land card. Search its owner's graveyard,
|
||||
// hand, and library for any number of cards with the same name as that card and exile them.
|
||||
// Then that player shuffles his or her library.
|
||||
addCard(Zone.HAND, playerA, "Surgical Extraction"); // Instant {BP}
|
||||
addCard(Zone.HAND, playerA, "Surgical Extraction"); // Instant {B/P}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Caves of Koilos", 1);
|
||||
/**
|
||||
|
|
@ -177,7 +177,7 @@ public class SacredGroundTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Surgical Extraction", 1);
|
||||
assertExileCount("Caves of Koilos", 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerA, 18);
|
||||
assertLife(playerB, 18);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{UP}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U/P}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -60,7 +60,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
assertPermanentCount(playerA, "Spellskite", 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerA, 18);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPowerToughness(playerA, "Spellskite", 3, 7);
|
||||
|
|
@ -90,7 +90,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Vedalken Shackles", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 6);
|
||||
// {UP}: Change a target of target spell or ability to Spellskite.
|
||||
// {U/P}: Change a target of target spell or ability to Spellskite.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite", 1);
|
||||
// {4}{U}{U}
|
||||
// Whenever Frost Titan becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays 2.
|
||||
|
|
@ -102,7 +102,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frost Titan");
|
||||
addTarget(playerB, "Silvercoat Lion");
|
||||
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{UP}: Change a target", "stack ability (Whenever {this} enters ");
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{U/P}: Change a target", "stack ability (Whenever {this} enters ");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -141,7 +141,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
setModeChoice(playerA, "1"); // Counter target spell
|
||||
setModeChoice(playerA, "2"); // return target permanent to its owner's hand
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Cryptic Command", "Cryptic Command");
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Cryptic Command", "Cryptic Command");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -154,7 +154,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
setModeChoice(playerA, "2"); // return target permanent to its owner's hand
|
||||
setModeChoice(playerA, "3"); // tap all creatures your opponents control
|
||||
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Cryptic Command");
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Cryptic Command");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -194,7 +194,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
assertTapped("Silvercoat Lion", true);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -222,7 +222,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -250,4 +250,102 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerB, "Spellskite", 3, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatSpellSkiteCantBeTargetedTwiceOrMore() {
|
||||
/* According to rules, the same object can be a legal target only
|
||||
once for each instances of the word “target” in the text
|
||||
of a spell or ability. In this case, the target can't be changed
|
||||
due to Spellskite already being a target.
|
||||
*/
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
|
||||
addTarget(playerA, "Scute Mob");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Spellskite");
|
||||
setChoice(playerA, "X=4");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 2);
|
||||
}
|
||||
|
||||
public void testThatSplitDamageCanGetRedirected() {
|
||||
/* Standard redirect test
|
||||
The Spellskite should die from the 5 damage that was redirected to it
|
||||
*/
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob"); // 1/1 creauture
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Scute Mob");
|
||||
setChoice(playerA, "X=5");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 1);
|
||||
assertPermanentCount(playerB, "Scute Mob", 1);
|
||||
}
|
||||
|
||||
public void testThatSplitDamageGetsRedirectedFromTheCorrectChoice() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Memnite"); // 1/1 creauture
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Royal Assassin");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Memnite");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Royal Assassin");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Blinking Spirit");
|
||||
setChoice(playerA, "X=1");
|
||||
addTarget(playerA, "Pearled Unicorn");
|
||||
setChoice(playerA, "X=2");//the unicorn deserves it
|
||||
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "No");
|
||||
setChoice(playerA, "Yes"); //of course
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, 3);
|
||||
assertPermanentCount(playerB, "Pearled Unicorn", 1);//it lives on
|
||||
assertPowerToughness(playerB, "Spellskite", 0, 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class PostMortemLungeTest extends CardTestPlayerBase {
|
|||
public void testExilesCreatureAtEndStep() {
|
||||
|
||||
/*
|
||||
{P}{X} - Sorcery
|
||||
{X}{B/P} - Sorcery
|
||||
Return target creature card with converted mana cost X from your graveyard to the battlefield.
|
||||
It gains haste. Exile it at the beginning of the next end step.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
|
|||
|
||||
/**
|
||||
* Test if a Thragtusk is copied by a PhyrexianMetamorph that both triggers
|
||||
* cotrrect work
|
||||
* correct work
|
||||
*/
|
||||
@Test
|
||||
public void testPhyrexianMetamorph() {
|
||||
|
|
@ -69,7 +69,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Phyrexian Metamorph", 1);
|
||||
assertGraveyardCount(playerB, "Public Execution", 1);
|
||||
|
||||
assertLife(playerA, 25);
|
||||
assertLife(playerA, 23);
|
||||
assertLife(playerB, 20); // Thragtusk ETB ability does not trigger if set to battlefield on test game start
|
||||
|
||||
assertPermanentCount(playerA, "Beast", 1);
|
||||
|
|
@ -116,7 +116,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Phyrexian Metamorph", 1);
|
||||
assertGraveyardCount(playerB, "Public Execution", 1);
|
||||
|
||||
assertLife(playerA, 25);
|
||||
assertLife(playerA, 23);
|
||||
assertLife(playerB, 20); // Thragtusk ETB ability does not trigger if set to battlefield on test game start
|
||||
|
||||
assertPermanentCount(playerA, "Beast", 0);
|
||||
|
|
|
|||
|
|
@ -31,11 +31,9 @@ import mage.MageObject;
|
|||
import mage.MageObjectReference;
|
||||
import mage.Mana;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.costs.mana.*;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
|
|
@ -62,6 +60,7 @@ import mage.watchers.Watcher;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -298,6 +297,9 @@ public abstract class AbilityImpl implements Ability {
|
|||
&& game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, getId(), getSourceId(), getControllerId()), this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
handlePhyrexianManaCosts(game, sourceId, controller);
|
||||
|
||||
for (UUID modeId : this.getModes().getSelectedModes()) {
|
||||
this.getModes().setActiveMode(modeId);
|
||||
//20121001 - 601.2c
|
||||
|
|
@ -503,6 +505,27 @@ public abstract class AbilityImpl implements Ability {
|
|||
return announceString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 601.2b
|
||||
* If a cost that will be paid as the spell is being cast includes Phyrexian mana symbols,
|
||||
* the player announces whether he or she intends to pay 2 life or the corresponding colored mana cost for each of those symbols.
|
||||
*/
|
||||
private void handlePhyrexianManaCosts(Game game, UUID sourceId, Player controller) {
|
||||
Iterator<ManaCost> costIterator = manaCostsToPay.iterator();
|
||||
while(costIterator.hasNext()) {
|
||||
ManaCost cost = costIterator.next();
|
||||
if(cost instanceof PhyrexianManaCost) {
|
||||
PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost)cost;
|
||||
PayLifeCost payLifeCost = new PayLifeCost(2);
|
||||
if(payLifeCost.canPay(this, sourceId, controller.getId(), game) &&
|
||||
controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + "?", this, game)) {
|
||||
costIterator.remove();
|
||||
costs.add(payLifeCost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles X mana costs and sets manaCostsToPay.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -50,34 +50,20 @@ public class PhyrexianManaCost extends ColoredManaCost {
|
|||
super(manaCost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignPayment(Game game, Ability ability, ManaPool pool, Cost costToPay) {
|
||||
assignColored(ability, game, pool, this.mana, costToPay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return '{' + mana.toString() + "P}";
|
||||
return '{' + mana.toString() + "/P}";
|
||||
}
|
||||
|
||||
public String getBaseText() {
|
||||
return super.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhyrexianManaCost getUnpaid() {
|
||||
return this;
|
||||
public ColoredManaCost getUnpaid() {
|
||||
return new ColoredManaCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
|
||||
if (!game.getPlayer(controllerId).isLifeTotalCanChange()) {
|
||||
return false;
|
||||
}
|
||||
return game.getPlayer(controllerId).getLife() >= 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
this.paid = game.getPlayer(controllerId).loseLife(2, game, false) == 2;
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhyrexianManaCost copy() {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,13 @@ package mage.abilities.effects;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.PhyrexianManaCost;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
|
|
@ -38,6 +43,9 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -141,6 +149,7 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm
|
|||
attackBlockManaTax.clearPaid();
|
||||
if (attackBlockManaTax.canPay(source, source.getSourceId(), player.getId(), game)
|
||||
&& player.chooseUse(Outcome.Neutral, chooseText, source, game)) {
|
||||
handlePhyrexianManaCosts(manaCosts, player, source, game);
|
||||
if (attackBlockManaTax instanceof ManaCostsImpl) {
|
||||
if (attackBlockManaTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) {
|
||||
return false;
|
||||
|
|
@ -152,6 +161,27 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm
|
|||
return false;
|
||||
}
|
||||
|
||||
private void handlePhyrexianManaCosts(ManaCosts<ManaCost> manaCosts, Player player, Ability source, Game game) {
|
||||
Iterator<ManaCost> manaCostIterator = manaCosts.iterator();
|
||||
Costs<PayLifeCost> costs = new CostsImpl<>();
|
||||
|
||||
while(manaCostIterator.hasNext()) {
|
||||
ManaCost manaCost = manaCostIterator.next();
|
||||
if(manaCost instanceof PhyrexianManaCost) {
|
||||
PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost)manaCost;
|
||||
PayLifeCost payLifeCost = new PayLifeCost(2);
|
||||
if(payLifeCost.canPay(source, source.getSourceId(), player.getId(), game) &&
|
||||
player.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + "?", source, game)) {
|
||||
manaCostIterator.remove();
|
||||
costs.add(payLifeCost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
costs.pay(source, game, source.getSourceId(), player.getId(), false, null);
|
||||
}
|
||||
|
||||
|
||||
private boolean handleOtherCosts(Cost attackBlockOtherTax, GameEvent event, Ability source, Game game) {
|
||||
Player player = game.getPlayer(event.getPlayerId());
|
||||
if (player != null) {
|
||||
|
|
|
|||
|
|
@ -2438,7 +2438,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (!copy.canActivate(playerId, game)) {
|
||||
return false;
|
||||
}
|
||||
game.getContinuousEffects().costModification(copy, game);
|
||||
if(available != null) {
|
||||
game.getContinuousEffects().costModification(copy, game);
|
||||
}
|
||||
|
||||
Card card = game.getCard(ability.getSourceId());
|
||||
if (card != null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue