From 24e24a968e1e94beffd14fbb5d7296f2bdd99b4e Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 8 Feb 2019 17:25:28 -0600 Subject: [PATCH] - Added Phantasmal Sphere and Misfortune. --- Mage.Sets/src/mage/cards/m/Misfortune.java | 88 +++++++++++++ .../src/mage/cards/p/PhantasmalSphere.java | 121 ++++++++++++++++++ Mage.Sets/src/mage/sets/Alliances.java | 2 + .../SacrificeSourceUnlessPaysEffect.java | 18 ++- 4 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/m/Misfortune.java create mode 100644 Mage.Sets/src/mage/cards/p/PhantasmalSphere.java diff --git a/Mage.Sets/src/mage/cards/m/Misfortune.java b/Mage.Sets/src/mage/cards/m/Misfortune.java new file mode 100644 index 0000000000..c3e0b8ec8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Misfortune.java @@ -0,0 +1,88 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author jeffwadsworth + */ +public final class Misfortune extends CardImpl { + + public Misfortune(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{R}{G}"); + + // An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her. + this.getSpellAbility().addEffect(new MisfortuneEffect()); + this.getSpellAbility().addTarget(new TargetOpponent(true)); + } + + private Misfortune(final Misfortune card) { + super(card); + } + + @Override + public Misfortune copy() { + return new Misfortune(this); + } +} + +class MisfortuneEffect extends OneShotEffect { + + public MisfortuneEffect() { + super(Outcome.Neutral); + staticText = "An opponent chooses one - " + + "You put a +1/+1 counter on each creature you control and gain " + + "4 life; or you put a -1/-1 counter on each creature that player " + + "controls and Misfortune deals 4 damage to him or her"; + } + + public MisfortuneEffect(final MisfortuneEffect effect) { + super(effect); + } + + @Override + public MisfortuneEffect copy() { + return new MisfortuneEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player chosenOpponent = game.getPlayer(targetPointer.getFirst(game, source)); + if (controller != null + && chosenOpponent != null) { + if (chosenOpponent.chooseUse(Outcome.Neutral, "If you choose Yes, the controller puts a +1/+1 counter" + + "on each creature they control and they gain 4 life. If no, the controller puts a -1/-1 counter" + + "on each creature you control and {this} deals 4 damage to you.", source, game)) { + Effect putP1P1CounterOnEachControlledCreature = new AddCountersAllEffect( + CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()); + putP1P1CounterOnEachControlledCreature.apply(game, source); + controller.gainLife(4, game, source); + } else { + FilterCreaturePermanent filterOpponentCreatures = new FilterCreaturePermanent(); + filterOpponentCreatures.add(new ControllerIdPredicate(chosenOpponent.getId())); + Effect putM1M1CounterOnEachOpponentCreature = new AddCountersAllEffect( + CounterType.M1M1.createInstance(), filterOpponentCreatures); + putM1M1CounterOnEachOpponentCreature.apply(game, source); + chosenOpponent.damage(4, source.getSourceId(), game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PhantasmalSphere.java b/Mage.Sets/src/mage/cards/p/PhantasmalSphere.java new file mode 100644 index 0000000000..fb57f5e4ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PhantasmalSphere.java @@ -0,0 +1,121 @@ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.token.TokenImpl; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author jeffwadsworth + */ +public final class PhantasmalSphere extends CardImpl { + + public PhantasmalSphere(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // At the beginning of your upkeep, put a +1/+1 counter on Phantasmal Sphere, then sacrifice Phantasmal Sphere unless you pay {1} for each +1/+1 counter on it. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false); + Effect effect = new SacrificeSourceUnlessPaysEffect(new CountersSourceCount(CounterType.P1P1)); + effect.setText("then sacrifice {this} unless you pay {1} for each +1/+1 counter on it."); + ability.addEffect(effect); + this.addAbility(ability); + + // When Phantasmal Sphere leaves the battlefield, target opponent puts an X/X blue Orb creature token with flying onto the battlefield, where X is the number of +1/+1 counters on Phantasmal Sphere. + Ability ability2 = new LeavesBattlefieldTriggeredAbility(new PhantasmalSphereEffect(), false); + ability2.addTarget(new TargetOpponent()); + this.addAbility(ability2); + + } + + private PhantasmalSphere(final PhantasmalSphere card) { + super(card); + } + + @Override + public PhantasmalSphere copy() { + return new PhantasmalSphere(this); + } +} + +class PhantasmalSphereEffect extends OneShotEffect { + + public PhantasmalSphereEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "target opponent puts an X/X blue Orb creature token " + + "with flying onto the battlefield, where X is the number " + + "of +1/+1 counters on {this}"; + } + + public PhantasmalSphereEffect(final PhantasmalSphereEffect effect) { + super(effect); + } + + @Override + public PhantasmalSphereEffect copy() { + return new PhantasmalSphereEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetOpponent = game.getPlayer(source.getFirstTarget()); + if (controller != null + && targetOpponent != null) { + Effect effect = new CreateTokenTargetEffect(new PhantasmalSphereToken( + new CountersSourceCount(CounterType.P1P1).calculate( + game, source, null))); + effect.setTargetPointer(new FixedTarget(targetOpponent.getId())); + effect.apply(game, source); + } + return false; + } +} + +class PhantasmalSphereToken extends TokenImpl { + + public PhantasmalSphereToken(int xValue) { + super("Orb", "X/X blue Orb creature token with flying"); + cardType.add(CardType.CREATURE); + color.setBlue(true); + subtype.add(SubType.ORB); + power = new MageInt(xValue); + toughness = new MageInt(xValue); + addAbility(FlyingAbility.getInstance()); + } + + public PhantasmalSphereToken(final PhantasmalSphereToken token) { + super(token); + } + + public PhantasmalSphereToken copy() { + return new PhantasmalSphereToken(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 0ff5b4fa43..c8be8d1dfc 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -122,6 +122,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Lord of Tresserhorn", 112, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class)); cards.add(new SetCardInfo("Martyrdom", "10a", Rarity.COMMON, mage.cards.m.Martyrdom.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Martyrdom", "10b", Rarity.COMMON, mage.cards.m.Martyrdom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Misfortune", 113, Rarity.RARE, mage.cards.m.Misfortune.class)); cards.add(new SetCardInfo("Mishra's Groundbreaker", 123, Rarity.UNCOMMON, mage.cards.m.MishrasGroundbreaker.class)); cards.add(new SetCardInfo("Misinformation", 56, Rarity.UNCOMMON, mage.cards.m.Misinformation.class)); cards.add(new SetCardInfo("Mystic Compass", 124, Rarity.UNCOMMON, mage.cards.m.MysticCompass.class)); @@ -133,6 +134,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Omen of Fire", 75, Rarity.RARE, mage.cards.o.OmenOfFire.class)); cards.add(new SetCardInfo("Phantasmal Fiend", "57a", Rarity.COMMON, mage.cards.p.PhantasmalFiend.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phantasmal Fiend", "57b", Rarity.COMMON, mage.cards.p.PhantasmalFiend.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Phantasmal Sphere", 32, Rarity.RARE, mage.cards.p.PhantasmalSphere.class)); cards.add(new SetCardInfo("Phelddagrif", 115, Rarity.RARE, mage.cards.p.Phelddagrif.class)); cards.add(new SetCardInfo("Phyrexian Boon", "58a", Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Boon", "58b", Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java index 75cb98bcbb..bd4597a719 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java @@ -4,6 +4,8 @@ import java.util.Locale; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.constants.Zone; @@ -18,19 +20,33 @@ import mage.util.CardUtil; public class SacrificeSourceUnlessPaysEffect extends OneShotEffect { protected Cost cost; + protected DynamicValue genericMana; public SacrificeSourceUnlessPaysEffect(Cost cost) { super(Outcome.Sacrifice); this.cost = cost; } + public SacrificeSourceUnlessPaysEffect(DynamicValue genericMana) { + super(Outcome.Detriment); + this.genericMana = genericMana; + } + public SacrificeSourceUnlessPaysEffect(final SacrificeSourceUnlessPaysEffect effect) { super(effect); - this.cost = effect.cost.copy(); + if (effect.cost != null) { + this.cost = effect.cost.copy(); + } + if (effect.genericMana != null) { + this.genericMana = effect.genericMana.copy(); + } } @Override public boolean apply(Game game, Ability source) { + if (genericMana != null) { + cost = new GenericManaCost(genericMana.calculate(game, source, this)); + } Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) {