mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
[WAR] added Spark Double
This commit is contained in:
parent
4c899a25bd
commit
db2a3b7ac4
4 changed files with 264 additions and 1 deletions
105
Mage.Sets/src/mage/cards/s/SparkDouble.java
Normal file
105
Mage.Sets/src/mage/cards/s/SparkDouble.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.CopyPermanentEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class SparkDouble extends CardImpl {
|
||||
|
||||
private static FilterPermanent filter = new FilterControlledPermanent("a creature or planeswalker you control");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
new CardTypePredicate(CardType.CREATURE),
|
||||
new CardTypePredicate(CardType.PLANESWALKER)));
|
||||
}
|
||||
|
||||
public SparkDouble(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
|
||||
this.subtype.add(SubType.ILLUSION);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
|
||||
// You may have Spark Double enter the battlefield as a copy of a creature or planeswalker you control,
|
||||
// except it enters with an additional +1/+1 counter on it if it’s a creature,
|
||||
// it enters with an additional loyalty counter on it if it’s a planeswalker, and it isn’t legendary if that permanent is legendary.
|
||||
Effect effect = new CopyPermanentEffect(filter, new SparkDoubleExceptEffectsApplyerToPermanent());
|
||||
effect.setText("as a copy of a creature or planeswalker you control, "
|
||||
+ "except it enters with an additional +1/+1 counter on it if it’s a creature, "
|
||||
+ "it enters with an additional loyalty counter on it if it’s a planeswalker, and it isn’t legendary if that permanent is legendary.");
|
||||
EntersBattlefieldAbility ability = new EntersBattlefieldAbility(effect, true);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public SparkDouble(final SparkDouble card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SparkDouble copy() {
|
||||
return new SparkDouble(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SparkDoubleExceptEffectsApplyerToPermanent extends ApplyToPermanent {
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Permanent copyFromBlueprint, Ability source, UUID copyToObjectId) {
|
||||
return apply(game, (MageObject) copyFromBlueprint, source, copyToObjectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject copyFromBlueprint, Ability source, UUID copyToObjectId) {
|
||||
Permanent destCard = game.getPermanentEntering(copyToObjectId);
|
||||
if (destCard == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// it isn’t legendary if that permanent is legendary
|
||||
copyFromBlueprint.getSuperType().remove(SuperType.LEGENDARY);
|
||||
|
||||
// TODO: Blood Moon problem, can't apply on type changing effects (same as TeferisTimeTwist)
|
||||
// see https://magic.wizards.com/en/articles/archive/feature/war-spark-release-notes-2019-04-19
|
||||
// If the copied permanent is affected by a type-changing effect, Spark Double may enter the battlefield with
|
||||
// different permanent types than the copied permanent currently has. Use the characteristics of Spark Double as
|
||||
// it enters the battlefield, not of the copied permanent, to determine whether it enters with an additional
|
||||
// counter on it. Notably, if Spark Double copies a Gideon planeswalker that's a creature because its loyalty
|
||||
// ability caused it to become a planeswalker creature, Spark Double enters as a noncreature planeswalker and
|
||||
// doesn't get a +1/+1 counter. On the other hand, if Spark Double copies Gideon Blackblade during your turn,
|
||||
// Spark Double enters as a planeswalker creature and gets both kinds of counters.
|
||||
|
||||
// enters with an additional +1/+1 counter on it if it’s a creature
|
||||
if (copyFromBlueprint.isCreature()) {
|
||||
destCard.addCounters(CounterType.P1P1.createInstance(), source, game);
|
||||
}
|
||||
|
||||
// enters with an additional loyalty counter on it if it’s a planeswalker
|
||||
if (copyFromBlueprint.isPlaneswalker()) {
|
||||
destCard.addCounters(CounterType.LOYALTY.createInstance(), source, game);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -113,7 +113,7 @@ class TeferisTimeTwistReturnEffect extends OneShotEffect {
|
|||
}
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null && permanent.isCreature()) {
|
||||
// This is technically wrong as it should enter with the counters,
|
||||
// TODO: This is technically wrong as it should enter with the counters,
|
||||
// however there's currently no way to know that for sure
|
||||
// this is similar to the blood moon issue
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
|
||||
|
|
|
@ -245,6 +245,7 @@ public final class WarOfTheSpark extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Sorin's Thirst", 104, Rarity.COMMON, mage.cards.s.SorinsThirst.class));
|
||||
cards.add(new SetCardInfo("Sorin, Vengeful Bloodlord", 217, Rarity.RARE, mage.cards.s.SorinVengefulBloodlord.class));
|
||||
cards.add(new SetCardInfo("Soul Diviner", 218, Rarity.RARE, mage.cards.s.SoulDiviner.class));
|
||||
cards.add(new SetCardInfo("Spark Double", 68, Rarity.RARE, mage.cards.s.SparkDouble.class));
|
||||
cards.add(new SetCardInfo("Spark Harvest", 105, Rarity.COMMON, mage.cards.s.SparkHarvest.class));
|
||||
cards.add(new SetCardInfo("Spark Reaper", 106, Rarity.COMMON, mage.cards.s.SparkReaper.class));
|
||||
cards.add(new SetCardInfo("Spellgorger Weird", 145, Rarity.COMMON, mage.cards.s.SpellgorgerWeird.class));
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
package org.mage.test.cards.copy;
|
||||
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class SparkDoubleTest extends CardTestPlayerBase {
|
||||
|
||||
private Permanent findDoubleSparkPermanent(Game game) {
|
||||
for (Permanent perm : game.getBattlefield().getAllActivePermanents()) {
|
||||
if (perm.isCopy()) {
|
||||
return perm;
|
||||
}
|
||||
}
|
||||
Assert.fail("spark must exist");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CopyCreatureAndGetOneCounter() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 1); // 2/2, fly, vig
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Abbey Griffin");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Abbey Griffin", 2);
|
||||
|
||||
Permanent spark = findDoubleSparkPermanent(currentGame);
|
||||
Assert.assertEquals("must add 1 counter", 1, spark.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
//
|
||||
Assert.assertEquals("must copy p/t", 3, spark.getPower().getValue());
|
||||
Assert.assertEquals("must copy p/t", 3, spark.getToughness().getValue());
|
||||
Assert.assertTrue("must copy ability", spark.getAbilities().contains(VigilanceAbility.getInstance()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CopyPlaneswalkerWithoutLegendaryWithOneCounter() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, the Greathearted", 1);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Ajani, the Greathearted");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Ajani, the Greathearted", 2);
|
||||
|
||||
Permanent spark = findDoubleSparkPermanent(currentGame);
|
||||
Assert.assertEquals("must add 1 loyalty", 5 + 1, spark.getCounters(currentGame).getCount(CounterType.LOYALTY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CopyCreatureAndGetDoubleCounter() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 1); // 2/2, fly, vig
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season", 1);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Abbey Griffin");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Abbey Griffin", 2);
|
||||
|
||||
Permanent spark = findDoubleSparkPermanent(currentGame);
|
||||
Assert.assertEquals("must add 2 counter", 2, spark.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CopyPlaneswalkerWithCreatureActivated() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Gideon, Ally of Zendikar", 1);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// activate creature ability
|
||||
checkType("planeswalker not creature", 1, PhaseStep.UPKEEP, playerA, "Gideon, Ally of Zendikar", CardType.CREATURE, false);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1:");
|
||||
checkType("planeswalker is creature", 1, PhaseStep.BEGIN_COMBAT, playerA, "Gideon, Ally of Zendikar", CardType.CREATURE, true);
|
||||
|
||||
// copy
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Spark Double");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Gideon, Ally of Zendikar");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Gideon, Ally of Zendikar", 2);
|
||||
|
||||
Permanent spark = findDoubleSparkPermanent(currentGame);
|
||||
Assert.assertEquals("must add 1 loyalty", 4 + 1, spark.getCounters(currentGame).getCount(CounterType.LOYALTY));
|
||||
Assert.assertEquals("must not add creature counter", 0, spark.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // TODO: enabled after Blood Moon type changing effect will be fixed
|
||||
public void test_CopyPlaneswalkerWithCreatureTypeChangedEffect() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Gideon Blackblade", 1);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// Gideon Blackblade is creature on your turn (by type changing effect)
|
||||
checkType("planeswalker is creature", 1, PhaseStep.UPKEEP, playerA, "Gideon Blackblade", CardType.CREATURE, true);
|
||||
|
||||
// copy
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Gideon Blackblade");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Gideon Blackblade", 2);
|
||||
|
||||
Permanent spark = findDoubleSparkPermanent(currentGame);
|
||||
Assert.assertEquals("must add 1 loyalty", 4 + 1, spark.getCounters(currentGame).getCount(CounterType.LOYALTY));
|
||||
Assert.assertEquals("must add 1 creature counter", 1, spark.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue