diff --git a/Mage.Sets/src/mage/cards/b/BlessedBreath.java b/Mage.Sets/src/mage/cards/b/BlessedBreath.java index 0743cf749b..e6541bc6df 100644 --- a/Mage.Sets/src/mage/cards/b/BlessedBreath.java +++ b/Mage.Sets/src/mage/cards/b/BlessedBreath.java @@ -1,9 +1,8 @@ - package mage.cards.b; import java.util.UUID; import mage.abilities.effects.common.continuous.GainProtectionFromColorTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,10 +23,10 @@ public final class BlessedBreath extends CardImpl { // Target creature you control gains protection from the color of your choice until end of turn. this.getSpellAbility().addEffect(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent().withChooseHint("gains protection")); // Splice onto Arcane {W} - this.addAbility(new SpliceOntoArcaneAbility("{W}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{W}")); } private BlessedBreath(final BlessedBreath card) { diff --git a/Mage.Sets/src/mage/cards/c/CandlesGlow.java b/Mage.Sets/src/mage/cards/c/CandlesGlow.java index f1c7ee76dc..659695e5c0 100644 --- a/Mage.Sets/src/mage/cards/c/CandlesGlow.java +++ b/Mage.Sets/src/mage/cards/c/CandlesGlow.java @@ -2,7 +2,7 @@ package mage.cards.c; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectImpl; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -30,9 +30,9 @@ public final class CandlesGlow extends CardImpl { // Prevent the next 3 damage that would be dealt to any target this turn. You gain life equal to the damage prevented this way. this.getSpellAbility().addEffect(new CandlesGlowPreventDamageTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().addTarget(new TargetAnyTarget().withChooseHint("prevent 3 damage")); // Splice onto Arcane {1}{W} - this.addAbility(new SpliceOntoArcaneAbility("{1}{W}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{W}")); } private CandlesGlow(final CandlesGlow card) { diff --git a/Mage.Sets/src/mage/cards/c/ConsumingVortex.java b/Mage.Sets/src/mage/cards/c/ConsumingVortex.java index 6937e1463c..f783bad1fc 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumingVortex.java +++ b/Mage.Sets/src/mage/cards/c/ConsumingVortex.java @@ -1,9 +1,8 @@ - package mage.cards.c; import java.util.UUID; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -23,9 +22,9 @@ public final class ConsumingVortex extends CardImpl { // Return target creature to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("return to hand")); // Splice onto Arcane {3}{U} - this.addAbility(new SpliceOntoArcaneAbility("{3}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{3}{U}")); } private ConsumingVortex(final ConsumingVortex card) { diff --git a/Mage.Sets/src/mage/cards/d/DampenThought.java b/Mage.Sets/src/mage/cards/d/DampenThought.java index aaa0340f4f..bdc12e9ad7 100644 --- a/Mage.Sets/src/mage/cards/d/DampenThought.java +++ b/Mage.Sets/src/mage/cards/d/DampenThought.java @@ -1,9 +1,8 @@ - package mage.cards.d; import java.util.UUID; -import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.effects.common.MillCardsTargetEffect; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -21,11 +20,11 @@ public final class DampenThought extends CardImpl { this.subtype.add(SubType.ARCANE); - // Target player puts the top four cards of their library into their graveyard. - this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(4)); - this.getSpellAbility().addTarget(new TargetPlayer()); + // Target player mills 4 cards. + this.getSpellAbility().addEffect(new MillCardsTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetPlayer().withChooseHint("mills 4 cards")); // Splice onto Arcane {1}{U} - this.addAbility(new SpliceOntoArcaneAbility("{1}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{U}")); } private DampenThought(final DampenThought card) { diff --git a/Mage.Sets/src/mage/cards/d/DesperateRitual.java b/Mage.Sets/src/mage/cards/d/DesperateRitual.java index 44225f3c34..035715d595 100644 --- a/Mage.Sets/src/mage/cards/d/DesperateRitual.java +++ b/Mage.Sets/src/mage/cards/d/DesperateRitual.java @@ -4,7 +4,7 @@ package mage.cards.d; import java.util.UUID; import mage.Mana; import mage.abilities.effects.mana.BasicManaEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,11 +20,10 @@ public final class DesperateRitual extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); this.subtype.add(SubType.ARCANE); - // Add {R}{R}{R}. this.getSpellAbility().addEffect(new BasicManaEffect(Mana.RedMana(3))); // Splice onto Arcane {1}{R} - this.addAbility(new SpliceOntoArcaneAbility("{1}{R}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{R}")); } private DesperateRitual(final DesperateRitual card) { diff --git a/Mage.Sets/src/mage/cards/e/Everdream.java b/Mage.Sets/src/mage/cards/e/Everdream.java index a5ca5ef6de..b21ea39695 100644 --- a/Mage.Sets/src/mage/cards/e/Everdream.java +++ b/Mage.Sets/src/mage/cards/e/Everdream.java @@ -1,7 +1,7 @@ package mage.cards.e; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.SpliceOntoInstantOrSorceryAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,7 +20,7 @@ public final class Everdream extends CardImpl { this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); // Splice onto instant or sorcery {2}{U} - this.addAbility(new SpliceOntoInstantOrSorceryAbility("{2}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.INSTANT_OR_SORCERY, "{2}{U}")); } private Everdream(final Everdream card) { diff --git a/Mage.Sets/src/mage/cards/e/Evermind.java b/Mage.Sets/src/mage/cards/e/Evermind.java index 09d4c3e7d9..53e6f6a9a8 100644 --- a/Mage.Sets/src/mage/cards/e/Evermind.java +++ b/Mage.Sets/src/mage/cards/e/Evermind.java @@ -1,11 +1,10 @@ - package mage.cards.e; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.InfoEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -35,7 +34,7 @@ public final class Evermind extends CardImpl { this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); // Splice onto Arcane {1}{U} - this.addAbility(new SpliceOntoArcaneAbility("{1}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{U}")); } private Evermind(final Evermind card) { diff --git a/Mage.Sets/src/mage/cards/g/GlacialRay.java b/Mage.Sets/src/mage/cards/g/GlacialRay.java index 10fb8e7468..494dfd18b0 100644 --- a/Mage.Sets/src/mage/cards/g/GlacialRay.java +++ b/Mage.Sets/src/mage/cards/g/GlacialRay.java @@ -1,8 +1,7 @@ - package mage.cards.g; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,9 +23,9 @@ public final class GlacialRay extends CardImpl { // Glacial Ray deals 2 damage to any target. this.getSpellAbility().addEffect(new DamageTargetEffect(2)); - this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().addTarget(new TargetAnyTarget().withChooseHint("2 damage")); // Splice onto Arcane {1}{R} - this.addAbility(new SpliceOntoArcaneAbility("{1}{R}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{R}")); } private GlacialRay(final GlacialRay card) { diff --git a/Mage.Sets/src/mage/cards/g/GoryosVengeance.java b/Mage.Sets/src/mage/cards/g/GoryosVengeance.java index 3a8621868a..1e6fd5d655 100644 --- a/Mage.Sets/src/mage/cards/g/GoryosVengeance.java +++ b/Mage.Sets/src/mage/cards/g/GoryosVengeance.java @@ -9,7 +9,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -41,10 +41,10 @@ public final class GoryosVengeance extends CardImpl { // Return target legendary creature card from your graveyard to the battlefield. That creature gains haste. Exile it at the beginning of the next end step. this.getSpellAbility().addEffect(new GoryosVengeanceEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter).withChooseHint("return to battlefield")); // Splice onto Arcane {2}{B} - this.addAbility(new SpliceOntoArcaneAbility("{2}{B}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{2}{B}")); } private GoryosVengeance(final GoryosVengeance card) { diff --git a/Mage.Sets/src/mage/cards/h/HideousLaughter.java b/Mage.Sets/src/mage/cards/h/HideousLaughter.java index acd7873069..7792ce5aa7 100644 --- a/Mage.Sets/src/mage/cards/h/HideousLaughter.java +++ b/Mage.Sets/src/mage/cards/h/HideousLaughter.java @@ -1,9 +1,8 @@ - package mage.cards.h; import java.util.UUID; import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,11 +19,10 @@ public final class HideousLaughter extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}{B}"); this.subtype.add(SubType.ARCANE); - // All creatures get -2/-2 until end of turn. this.getSpellAbility().addEffect(new BoostAllEffect(-2,-2, Duration.EndOfTurn)); // Splice onto Arcane {3}{B}{B} - this.addAbility(new SpliceOntoArcaneAbility("{3}{B}{B}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{3}{B}{B}")); } private HideousLaughter(final HideousLaughter card) { diff --git a/Mage.Sets/src/mage/cards/h/HorobisWhisper.java b/Mage.Sets/src/mage/cards/h/HorobisWhisper.java index 854e92037b..f26312d400 100644 --- a/Mage.Sets/src/mage/cards/h/HorobisWhisper.java +++ b/Mage.Sets/src/mage/cards/h/HorobisWhisper.java @@ -4,7 +4,7 @@ import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.costs.common.ExileFromGraveCost; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -36,10 +36,10 @@ public final class HorobisWhisper extends CardImpl { // If you control a Swamp, destroy target nonblack creature. this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DestroyTargetEffect(), new PermanentsOnTheBattlefieldCondition(filterCondition),"If you control a Swamp, destroy target nonblack creature")); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE_NON_BLACK)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE_NON_BLACK).withChooseHint("destroy if you control a Swamp")); // Splice onto Arcane-Exile four cards from your graveyard. - this.addAbility(new SpliceOntoArcaneAbility(new ExileFromGraveCost(new TargetCardInYourGraveyard(4,4, new FilterCard("cards"))))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new ExileFromGraveCost(new TargetCardInYourGraveyard(4,4, new FilterCard("cards"))))); } diff --git a/Mage.Sets/src/mage/cards/h/HundredTalonStrike.java b/Mage.Sets/src/mage/cards/h/HundredTalonStrike.java index c756439f73..2868cdbf4c 100644 --- a/Mage.Sets/src/mage/cards/h/HundredTalonStrike.java +++ b/Mage.Sets/src/mage/cards/h/HundredTalonStrike.java @@ -1,4 +1,3 @@ - package mage.cards.h; import mage.ObjectColor; @@ -7,7 +6,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -45,9 +44,9 @@ public final class HundredTalonStrike extends CardImpl { effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains first strike until end of turn"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("+1/+0 and first strike")); // Splice onto Arcane-Tap an untapped white creature you control. - this.addAbility(new SpliceOntoArcaneAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1,1,filter,false)))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new TapTargetCost(new TargetControlledCreaturePermanent(1,1,filter,false)))); } private HundredTalonStrike(final HundredTalonStrike card) { diff --git a/Mage.Sets/src/mage/cards/i/IntoTheFray.java b/Mage.Sets/src/mage/cards/i/IntoTheFray.java index 748a25c20d..137350a87b 100644 --- a/Mage.Sets/src/mage/cards/i/IntoTheFray.java +++ b/Mage.Sets/src/mage/cards/i/IntoTheFray.java @@ -1,8 +1,7 @@ - package mage.cards.i; import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -22,13 +21,12 @@ public final class IntoTheFray extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}"); this.subtype.add(SubType.ARCANE); - // Target creature attacks this turn if able. this.getSpellAbility().addEffect(new AttacksIfAbleTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("attacks this turn if able")); + // Splice onto Arcane {R} - this.addAbility(new SpliceOntoArcaneAbility("{R}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{R}")); } private IntoTheFray(final IntoTheFray card) { diff --git a/Mage.Sets/src/mage/cards/k/KodamasMight.java b/Mage.Sets/src/mage/cards/k/KodamasMight.java index e7b6e4aef5..f43b934037 100644 --- a/Mage.Sets/src/mage/cards/k/KodamasMight.java +++ b/Mage.Sets/src/mage/cards/k/KodamasMight.java @@ -1,9 +1,8 @@ - package mage.cards.k; import java.util.UUID; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,9 +23,9 @@ public final class KodamasMight extends CardImpl { // Target creature gets +2/+2 until end of turn. this.getSpellAbility().addEffect(new BoostTargetEffect(2,2, Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("gets +2/+2")); // Splice onto Arcane {G} - this.addAbility(new SpliceOntoArcaneAbility("{G}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{G}")); } private KodamasMight(final KodamasMight card) { diff --git a/Mage.Sets/src/mage/cards/l/LiftedByClouds.java b/Mage.Sets/src/mage/cards/l/LiftedByClouds.java index 1dec28b715..4762b30cd6 100644 --- a/Mage.Sets/src/mage/cards/l/LiftedByClouds.java +++ b/Mage.Sets/src/mage/cards/l/LiftedByClouds.java @@ -1,9 +1,8 @@ - package mage.cards.l; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -26,9 +25,9 @@ public final class LiftedByClouds extends CardImpl { // Target creature gains flying until end of turn. this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("gains flying")); // Splice onto Arcane {1}{U} - this.addAbility(new SpliceOntoArcaneAbility("{1}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{U}")); } private LiftedByClouds(final LiftedByClouds card) { diff --git a/Mage.Sets/src/mage/cards/o/Overblaze.java b/Mage.Sets/src/mage/cards/o/Overblaze.java index 09f45adf68..d6059b3b89 100644 --- a/Mage.Sets/src/mage/cards/o/Overblaze.java +++ b/Mage.Sets/src/mage/cards/o/Overblaze.java @@ -1,10 +1,9 @@ - package mage.cards.o; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -28,9 +27,9 @@ public final class Overblaze extends CardImpl { // Each time target permanent would deal damage to a creature or player this turn, it deals double that damage to that creature or player instead. this.getSpellAbility().addEffect(new OverblazeEffect()); - this.getSpellAbility().addTarget(new TargetPermanent()); + this.getSpellAbility().addTarget(new TargetPermanent().withChooseHint("deals double damage")); // Splice onto Arcane {2}{R}{R} - this.addAbility(new SpliceOntoArcaneAbility("{2}{R}{R}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{2}{R}{R}")); } private Overblaze(final Overblaze card) { diff --git a/Mage.Sets/src/mage/cards/p/PsychicPuppetry.java b/Mage.Sets/src/mage/cards/p/PsychicPuppetry.java index 6bbf01cfed..d04907f629 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicPuppetry.java +++ b/Mage.Sets/src/mage/cards/p/PsychicPuppetry.java @@ -1,8 +1,7 @@ - package mage.cards.p; import mage.abilities.effects.common.MayTapOrUntapTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,9 +23,9 @@ public final class PsychicPuppetry extends CardImpl { // You may tap or untap target permanent. this.getSpellAbility().addEffect(new MayTapOrUntapTargetEffect()); - this.getSpellAbility().addTarget(new TargetPermanent()); + this.getSpellAbility().addTarget(new TargetPermanent().withChooseHint("tap or untap")); // Splice onto Arcane {U} - this.addAbility(new SpliceOntoArcaneAbility("{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{U}")); } private PsychicPuppetry(final PsychicPuppetry card) { diff --git a/Mage.Sets/src/mage/cards/r/Reweave.java b/Mage.Sets/src/mage/cards/r/Reweave.java index 445a40bef6..ad619a733e 100644 --- a/Mage.Sets/src/mage/cards/r/Reweave.java +++ b/Mage.Sets/src/mage/cards/r/Reweave.java @@ -1,11 +1,10 @@ - package mage.cards.r; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; @@ -31,11 +30,11 @@ public final class Reweave extends CardImpl { // Target permanent's controller sacrifices it. If they do, that player reveals cards from the top of their library until they reveal a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles their library. this.getSpellAbility().addEffect(new ReweaveEffect()); - Target target = new TargetPermanent(); + Target target = new TargetPermanent().withChooseHint("Reweave"); this.getSpellAbility().addTarget(target); // Splice onto Arcane {2}{U}{U} - this.addAbility(new SpliceOntoArcaneAbility("{2}{U}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{2}{U}{U}")); } private Reweave(final Reweave card) { diff --git a/Mage.Sets/src/mage/cards/r/RoarOfJukai.java b/Mage.Sets/src/mage/cards/r/RoarOfJukai.java index cb80d2e199..f6b5b38cdf 100644 --- a/Mage.Sets/src/mage/cards/r/RoarOfJukai.java +++ b/Mage.Sets/src/mage/cards/r/RoarOfJukai.java @@ -1,4 +1,3 @@ - package mage.cards.r; import mage.abilities.Ability; @@ -7,7 +6,7 @@ import mage.abilities.costs.common.GainLifeOpponentCost; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -33,12 +32,11 @@ public final class RoarOfJukai extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); this.subtype.add(SubType.ARCANE); - // If you control a Forest, each blocked creature gets +2/+2 until end of turn. this.getSpellAbility().addEffect(new RoarOfJukaiEffect()); // Splice onto Arcane-An opponent gains 5 life. - this.addAbility(new SpliceOntoArcaneAbility(new GainLifeOpponentCost(5))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new GainLifeOpponentCost(5))); } private RoarOfJukai(final RoarOfJukai card) { diff --git a/Mage.Sets/src/mage/cards/s/ShiftingBorders.java b/Mage.Sets/src/mage/cards/s/ShiftingBorders.java index b3fc4b5d4d..553ec5d373 100644 --- a/Mage.Sets/src/mage/cards/s/ShiftingBorders.java +++ b/Mage.Sets/src/mage/cards/s/ShiftingBorders.java @@ -1,8 +1,7 @@ - package mage.cards.s; import mage.abilities.effects.common.continuous.ExchangeControlTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,10 +23,10 @@ public final class ShiftingBorders extends CardImpl { // Exchange control of two target lands. this.getSpellAbility().addEffect(new ExchangeControlTargetEffect(Duration.EndOfGame, "Exchange control of two target lands")); - this.getSpellAbility().addTarget(new TargetLandPermanent(2)); + this.getSpellAbility().addTarget(new TargetLandPermanent(2).withChooseHint("exchange control")); // Splice onto Arcane {3}{U} - this.addAbility(new SpliceOntoArcaneAbility("{3}{U}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{3}{U}")); } private ShiftingBorders(final ShiftingBorders card) { diff --git a/Mage.Sets/src/mage/cards/s/SoullessRevival.java b/Mage.Sets/src/mage/cards/s/SoullessRevival.java index f94a239f8e..acff0fe0db 100644 --- a/Mage.Sets/src/mage/cards/s/SoullessRevival.java +++ b/Mage.Sets/src/mage/cards/s/SoullessRevival.java @@ -1,9 +1,8 @@ - package mage.cards.s; import java.util.UUID; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -23,9 +22,9 @@ public final class SoullessRevival extends CardImpl { // Return target creature card from your graveyard to your hand. this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD).withChooseHint("return to hand")); // Splice onto Arcane {1}{B} - this.addAbility(new SpliceOntoArcaneAbility("{1}{B}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{B}")); } private SoullessRevival(final SoullessRevival card) { diff --git a/Mage.Sets/src/mage/cards/s/SpiritualVisit.java b/Mage.Sets/src/mage/cards/s/SpiritualVisit.java index df62ec1fd0..88e242b382 100644 --- a/Mage.Sets/src/mage/cards/s/SpiritualVisit.java +++ b/Mage.Sets/src/mage/cards/s/SpiritualVisit.java @@ -1,8 +1,7 @@ - package mage.cards.s; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -25,7 +24,7 @@ public final class SpiritualVisit extends CardImpl { this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritToken())); // Splice onto Arcane {W} - this.addAbility(new SpliceOntoArcaneAbility("{W}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{W}")); } private SpiritualVisit(final SpiritualVisit card) { diff --git a/Mage.Sets/src/mage/cards/s/SplicersSkill.java b/Mage.Sets/src/mage/cards/s/SplicersSkill.java index 4b6076ff24..cdbcde0437 100644 --- a/Mage.Sets/src/mage/cards/s/SplicersSkill.java +++ b/Mage.Sets/src/mage/cards/s/SplicersSkill.java @@ -1,7 +1,7 @@ package mage.cards.s; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.SpliceOntoInstantOrSorceryAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -21,7 +21,7 @@ public final class SplicersSkill extends CardImpl { this.getSpellAbility().addEffect(new CreateTokenEffect(new PhyrexianGolemToken())); // Splice onto instant or sorcery {3}{W} - this.addAbility(new SpliceOntoInstantOrSorceryAbility("{3}{W}")); + this.addAbility(new SpliceAbility(SpliceAbility.INSTANT_OR_SORCERY, "{3}{W}")); } private SplicersSkill(final SplicersSkill card) { diff --git a/Mage.Sets/src/mage/cards/s/StrangeInversion.java b/Mage.Sets/src/mage/cards/s/StrangeInversion.java index 6f719e019d..7acf886c35 100644 --- a/Mage.Sets/src/mage/cards/s/StrangeInversion.java +++ b/Mage.Sets/src/mage/cards/s/StrangeInversion.java @@ -1,8 +1,7 @@ - package mage.cards.s; import mage.abilities.effects.common.continuous.SwitchPowerToughnessTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -25,9 +24,9 @@ public final class StrangeInversion extends CardImpl { // Switch target creature's power and toughness until end of turn. this.getSpellAbility().addEffect(new SwitchPowerToughnessTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("switch power and toughness")); // Splice onto Arcane {1}{R} - this.addAbility(new SpliceOntoArcaneAbility("{1}{R}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{R}")); } private StrangeInversion(final StrangeInversion card) { diff --git a/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java b/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java index acf7a860ad..6ef52c4a9e 100644 --- a/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java +++ b/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java @@ -10,7 +10,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -39,7 +39,7 @@ public final class ThroughTheBreach extends CardImpl { // You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice that creature at the beginning of the next end step. this.getSpellAbility().addEffect(new ThroughTheBreachEffect()); // Splice onto Arcane {2}{R}{R} - this.addAbility(new SpliceOntoArcaneAbility(new ManaCostsImpl<>("{2}{R}{R}"))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new ManaCostsImpl<>("{2}{R}{R}"))); } private ThroughTheBreach(final ThroughTheBreach card) { diff --git a/Mage.Sets/src/mage/cards/t/TorrentOfStone.java b/Mage.Sets/src/mage/cards/t/TorrentOfStone.java index e6af263c81..5580152f32 100644 --- a/Mage.Sets/src/mage/cards/t/TorrentOfStone.java +++ b/Mage.Sets/src/mage/cards/t/TorrentOfStone.java @@ -1,10 +1,9 @@ - package mage.cards.t; import java.util.UUID; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -28,12 +27,11 @@ public final class TorrentOfStone extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}"); this.subtype.add(SubType.ARCANE); - // Torrent of Stone deals 4 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("4 damage")); // Splice onto Arcane-Sacrifice two Mountains. - this.addAbility(new SpliceOntoArcaneAbility(new SacrificeTargetCost(new TargetControlledPermanent(2,2, filterSacrifice, false)))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new SacrificeTargetCost(new TargetControlledPermanent(2,2, filterSacrifice, false)))); } private TorrentOfStone(final TorrentOfStone card) { diff --git a/Mage.Sets/src/mage/cards/v/VeilOfSecrecy.java b/Mage.Sets/src/mage/cards/v/VeilOfSecrecy.java index f6da55aab8..c4829438b5 100644 --- a/Mage.Sets/src/mage/cards/v/VeilOfSecrecy.java +++ b/Mage.Sets/src/mage/cards/v/VeilOfSecrecy.java @@ -1,4 +1,3 @@ - package mage.cards.v; import mage.ObjectColor; @@ -7,7 +6,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.ShroudAbility; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -36,9 +35,9 @@ public final class VeilOfSecrecy extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); this.subtype.add(SubType.ARCANE); - // Target creature gains shroud until end of turn and is can't be blocked this turn. + // Target creature gains shroud until end of turn and can't be blocked this turn. Effect effect = new GainAbilityTargetEffect(ShroudAbility.getInstance(), Duration.EndOfTurn); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("gains shroud and can't be blocked")); effect.setText("Target creature gains shroud until end of turn"); this.getSpellAbility().addEffect(effect); effect = new CantBeBlockedTargetEffect(); @@ -46,7 +45,7 @@ public final class VeilOfSecrecy extends CardImpl { this.getSpellAbility().addEffect(effect); // Splice onto Arcane-Return a blue creature you control to its owner's hand. - this.addAbility(new SpliceOntoArcaneAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledCreaturePermanent(filter)))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new ReturnToHandChosenControlledPermanentCost(new TargetControlledCreaturePermanent(filter)))); } private VeilOfSecrecy(final VeilOfSecrecy card) { diff --git a/Mage.Sets/src/mage/cards/v/VitalSurge.java b/Mage.Sets/src/mage/cards/v/VitalSurge.java index 9f1ed4a15b..0682777d49 100644 --- a/Mage.Sets/src/mage/cards/v/VitalSurge.java +++ b/Mage.Sets/src/mage/cards/v/VitalSurge.java @@ -1,8 +1,7 @@ - package mage.cards.v; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -24,7 +23,7 @@ public final class VitalSurge extends CardImpl { // You gain 3 life. this.getSpellAbility().addEffect(new GainLifeEffect(3)); // Splice onto Arcane {1}{G} - this.addAbility(new SpliceOntoArcaneAbility("{1}{G}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{1}{G}")); } private VitalSurge(final VitalSurge card) { diff --git a/Mage.Sets/src/mage/cards/w/WearAway.java b/Mage.Sets/src/mage/cards/w/WearAway.java index a665502e3d..57548c458f 100644 --- a/Mage.Sets/src/mage/cards/w/WearAway.java +++ b/Mage.Sets/src/mage/cards/w/WearAway.java @@ -1,8 +1,7 @@ - package mage.cards.w; import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.abilities.keyword.SpliceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -25,10 +24,10 @@ public final class WearAway extends CardImpl { // Destroy target artifact or enchantment. this.getSpellAbility().addEffect(new DestroyTargetEffect()); - Target target = new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT); + Target target = new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT).withChooseHint("destroy"); this.getSpellAbility().addTarget(target); // Splice onto Arcane {3}{G} - this.addAbility(new SpliceOntoArcaneAbility("{3}{G}")); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, "{3}{G}")); } private WearAway(final WearAway card) { diff --git a/Mage/src/main/java/mage/abilities/effects/SpliceCardEffect.java b/Mage/src/main/java/mage/abilities/effects/SpliceCardEffect.java index 7cb998867c..dcec902ae6 100644 --- a/Mage/src/main/java/mage/abilities/effects/SpliceCardEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/SpliceCardEffect.java @@ -1,5 +1,3 @@ - - package mage.abilities.effects; import mage.abilities.Ability; diff --git a/Mage/src/main/java/mage/abilities/effects/SpliceCardEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/SpliceCardEffectImpl.java deleted file mode 100644 index 6a016d3364..0000000000 --- a/Mage/src/main/java/mage/abilities/effects/SpliceCardEffectImpl.java +++ /dev/null @@ -1,40 +0,0 @@ - - -package mage.abilities.effects; - -import mage.abilities.Ability; -import mage.constants.Duration; -import mage.constants.EffectType; -import mage.constants.Outcome; -import mage.game.Game; - - -/** - * Simple implementation of a {@link SpliceCardEffect} offering simplified - * construction to setup the object for use by the mage framework. - - * @author LevelX2 - */ -public abstract class SpliceCardEffectImpl extends ContinuousEffectImpl implements SpliceCardEffect { - - public SpliceCardEffectImpl ( Duration duration, Outcome outcome ) { - super(duration, outcome); - this.effectType = EffectType.SPLICE; - } - - public SpliceCardEffectImpl(final SpliceCardEffectImpl effect) { - super(effect); - } - - /** - * Overridden and 'no-op' implementation put in place. - * - * @see #apply(mage.game.Game, mage.abilities.Ability, mage.abilities.Ability) - * - * @param game - * @param source - * @return - */ - @Override - public final boolean apply ( Game game, Ability source ) { return false; } -} diff --git a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpliceAbility.java similarity index 71% rename from Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java rename to Mage/src/main/java/mage/abilities/keyword/SpliceAbility.java index 9e95938301..4cf224c77d 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SpliceAbility.java @@ -10,9 +10,12 @@ import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.SpliceCardEffectImpl; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.SpliceCardEffect; import mage.cards.Card; import mage.constants.*; +import mage.filter.FilterObject; +import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; @@ -75,64 +78,87 @@ import mage.players.Player; * when the spell resolves. A spell is countered on resolution only if *all* of * its targets are illegal (or the spell is countered by an effect). * - * @author LevelX2 + * @author LevelX2, awjackson */ -public class SpliceOntoArcaneAbility extends SimpleStaticAbility { +public class SpliceAbility extends SimpleStaticAbility { - private static final String KEYWORD_TEXT = "Splice onto Arcane"; - private Costs spliceCosts = new CostsImpl<>(); - private boolean nonManaCosts = false; + public static final FilterObject ARCANE = new FilterObject("Arcane"); + public static final FilterObject INSTANT_OR_SORCERY = new FilterObject("instant or sorcery"); - public SpliceOntoArcaneAbility(String manaString) { - super(Zone.HAND, new SpliceOntoArcaneEffect()); + static { + ARCANE.add(SubType.ARCANE.getPredicate()); + ARCANE.setLockedFilter(true); + INSTANT_OR_SORCERY.add(Predicates.or( + CardType.INSTANT.getPredicate(), + CardType.SORCERY.getPredicate() + )); + INSTANT_OR_SORCERY.setLockedFilter(true); + } + + private final Costs spliceCosts = new CostsImpl<>(); + private final String rule; + + public SpliceAbility(FilterObject filter, String manaString) { + super(Zone.HAND, new SpliceCardEffectImpl(filter)); spliceCosts.add(new ManaCostsImpl<>(manaString)); + rule = "Splice onto " + filter.getMessage() + ' ' + spliceCosts.getText() + getReminder(filter); } - public SpliceOntoArcaneAbility(Cost cost) { - super(Zone.HAND, new SpliceOntoArcaneEffect()); + public SpliceAbility(FilterObject filter, Cost cost) { + super(Zone.HAND, new SpliceCardEffectImpl(filter)); spliceCosts.add(cost); - nonManaCosts = true; + rule = "Splice onto " + filter.getMessage() + "—" + spliceCosts.getText() + '.' + getReminder(filter); } - public SpliceOntoArcaneAbility(final SpliceOntoArcaneAbility ability) { + private SpliceAbility(final SpliceAbility ability) { super(ability); - this.spliceCosts = ability.spliceCosts.copy(); - this.nonManaCosts = ability.nonManaCosts; + this.spliceCosts.addAll(ability.spliceCosts); + this.rule = ability.rule; } @Override public SimpleStaticAbility copy() { - return new SpliceOntoArcaneAbility(this); + return new SpliceAbility(this); } public Costs getSpliceCosts() { return spliceCosts; } + private static String getReminder(FilterObject filter) { + return " (As you cast an " + filter.getMessage() + " spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)"; + } + @Override public String getRule() { - StringBuilder sb = new StringBuilder(); - sb.append(KEYWORD_TEXT).append(nonManaCosts ? "—" : " "); - sb.append(spliceCosts.getText()).append(nonManaCosts ? ". " : " "); - sb.append("(As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)"); - return sb.toString(); + return rule; } } -class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { +class SpliceCardEffectImpl extends ContinuousEffectImpl implements SpliceCardEffect { - public SpliceOntoArcaneEffect() { + private final FilterObject filter; + + public SpliceCardEffectImpl(FilterObject filter) { super(Duration.WhileOnBattlefield, Outcome.Copy); - staticText = "Splice onto Arcane"; + this.effectType = EffectType.SPLICE; + this.filter = filter; + staticText = "Splice onto " + filter; } - public SpliceOntoArcaneEffect(final SpliceOntoArcaneEffect effect) { + private SpliceCardEffectImpl(final SpliceCardEffectImpl effect) { super(effect); + this.filter = effect.filter; } @Override - public SpliceOntoArcaneEffect copy() { - return new SpliceOntoArcaneEffect(this); + public SpliceCardEffectImpl copy() { + return new SpliceCardEffectImpl(this); + } + + @Override + public final boolean apply(Game game, Ability source) { + return false; } @Override @@ -146,7 +172,7 @@ class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { splicedAbility.setSpellAbilityType(SpellAbilityType.SPLICE); splicedAbility.setSourceId(abilityToModify.getSourceId()); spell.addSpellAbility(splicedAbility); - for (Iterator it = ((SpliceOntoArcaneAbility) source).getSpliceCosts().iterator(); it.hasNext();) { + for (Iterator it = ((SpliceAbility) source).getSpliceCosts().iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); if (cost instanceof ManaCost) { spell.getSpellAbility().getManaCostsToPay().add((ManaCost) cost.copy()); @@ -163,7 +189,7 @@ class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { MageObject object = game.getObject(abilityToModify.getSourceId()); - if (object != null && object.hasSubtype(SubType.ARCANE, game)) { + if (object != null && filter.match(object, game)) { return spliceSpellCanBeActivated(source, game); } return false; diff --git a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java deleted file mode 100644 index 7afa8e282d..0000000000 --- a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoInstantOrSorceryAbility.java +++ /dev/null @@ -1,188 +0,0 @@ -package mage.abilities.keyword; - -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.Costs; -import mage.abilities.costs.CostsImpl; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.SpliceCardEffectImpl; -import mage.cards.Card; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SpellAbilityType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.stack.Spell; -import mage.players.Player; - -import java.util.Iterator; - -/** - * 702.45. Splice - *

- * 702.45a Splice is a static ability that functions while a card is in your - * hand. "Splice onto [subtype] [cost]" means "You may reveal this card from - * your hand as you cast a [subtype] spell. If you do, copy this card's text box - * onto that spell and pay [cost] as an additional cost to cast that spell." - * Paying a card's splice cost follows the rules for paying additional costs in - * rules 601.2b and 601.2e-g. - *

- * Example: Since the card with splice remains in the player's hand, it can - * later be cast normally or spliced onto another spell. It can even be - * discarded to pay a "discard a card" cost of the spell it's spliced onto. - *

- * 702.45b You can't choose to use a splice ability if you can't make the - * required choices (targets, etc.) for that card's instructions. You can't - * splice any one card onto the same spell more than once. If you're splicing - * more than one card onto a spell, reveal them all at once and choose the order - * in which their instructions will be followed. The instructions on the main - * spell have to be followed first. - *

- * 702.45c The spell has the characteristics of the main spell, plus the text - * boxes of each of the spliced cards. The spell doesn't gain any other - * characteristics (name, mana cost, color, supertypes, card types, subtypes, - * etc.) of the spliced cards. Text copied onto the spell that refers to a card - * by name refers to the spell on the stack, not the card from which the text - * was copied. - *

- * Example: Glacial Ray is a red card with splice onto Arcane that reads, - * "Glacial Ray deals 2 damage to any target." Suppose Glacial Ray is spliced - * onto Reach Through Mists, a blue spell. The spell is still blue, and Reach - * Through Mists deals the damage. This means that the ability can target a - * creature with protection from red and deal 2 damage to that creature. - *

- * 702.45d Choose targets for the added text normally (see rule 601.2c). Note - * that a spell with one or more targets will be countered if all of its targets - * are illegal on resolution. - *

- * 702.45e The spell loses any splice changes once it leaves the stack (for - * example, when it's countered, it's exiled, or it resolves). - *

- * Rulings - *

- * You must reveal all of the cards you intend to splice at the same time. Each - * individual card can only be spliced once onto a spell. If you have more than - * one card with the same name in your hand, you may splice both of them onto - * the spell. A card with a splice ability can't be spliced onto itself because - * the spell is on the stack (and not in your hand) when you reveal the cards - * you want to splice onto it. The target for a card that's spliced onto a spell - * may be the same as the target chosen for the original spell or for another - * spliced-on card. (A recent change to the targeting rules allows this, but - * most other cards are unaffected by the change.) If you splice a targeted card - * onto an untargeted spell, the entire spell will be countered if the target - * isn't legal when the spell resolves. If you splice an untargeted card onto a - * targeted spell, the entire spell will be countered if the target isn't legal - * when the spell resolves. A spell is countered on resolution only if *all* of - * its targets are illegal (or the spell is countered by an effect). - * - * @author LevelX2 - */ -public class SpliceOntoInstantOrSorceryAbility extends SimpleStaticAbility { - - private static final String KEYWORD_TEXT = "Splice onto instant or sorcery"; - private Costs spliceCosts = new CostsImpl<>(); - private boolean nonManaCosts = false; - - public SpliceOntoInstantOrSorceryAbility(String manaString) { - super(Zone.HAND, new SpliceOntoInstantOrSorceryEffect()); - spliceCosts.add(new ManaCostsImpl<>(manaString)); - } - - public SpliceOntoInstantOrSorceryAbility(Cost cost) { - super(Zone.HAND, new SpliceOntoInstantOrSorceryEffect()); - spliceCosts.add(cost); - nonManaCosts = true; - } - - private SpliceOntoInstantOrSorceryAbility(final SpliceOntoInstantOrSorceryAbility ability) { - super(ability); - this.spliceCosts = ability.spliceCosts.copy(); - this.nonManaCosts = ability.nonManaCosts; - } - - @Override - public SimpleStaticAbility copy() { - return new SpliceOntoInstantOrSorceryAbility(this); - } - - Costs getSpliceCosts() { - return spliceCosts; - } - - @Override - public String getRule() { - StringBuilder sb = new StringBuilder(); - sb.append(KEYWORD_TEXT).append(nonManaCosts ? "—" : " "); - sb.append(spliceCosts.getText()).append(nonManaCosts ? ". " : " "); - sb.append("(As you cast an instant or sorcery spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)"); - return sb.toString(); - } -} - -class SpliceOntoInstantOrSorceryEffect extends SpliceCardEffectImpl { - - SpliceOntoInstantOrSorceryEffect() { - super(Duration.WhileOnBattlefield, Outcome.Copy); - staticText = "Splice onto Instant or Sorcery"; - } - - private SpliceOntoInstantOrSorceryEffect(final SpliceOntoInstantOrSorceryEffect effect) { - super(effect); - } - - @Override - public SpliceOntoInstantOrSorceryEffect copy() { - return new SpliceOntoInstantOrSorceryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source, Ability abilityToModify) { - Player controller = game.getPlayer(source.getControllerId()); - Card spliceCard = game.getCard(source.getSourceId()); - if (spliceCard != null && controller != null) { - Spell spell = game.getStack().getSpell(abilityToModify.getId()); - if (spell != null) { - SpellAbility splicedAbility = spliceCard.getSpellAbility().copy(); - splicedAbility.setSpellAbilityType(SpellAbilityType.SPLICE); - splicedAbility.setSourceId(abilityToModify.getSourceId()); - spell.addSpellAbility(splicedAbility); - for (Iterator it = ((SpliceOntoInstantOrSorceryAbility) source).getSpliceCosts().iterator(); it.hasNext(); ) { - Cost cost = (Cost) it.next(); - if (cost instanceof ManaCost) { - spell.getSpellAbility().getManaCostsToPay().add((ManaCost) cost.copy()); - } else { - spell.getSpellAbility().getCosts().add(cost.copy()); - } - } - } - return true; - } - return false; - } - - @Override - public boolean applies(Ability abilityToModify, Ability source, Game game) { - MageObject object = game.getObject(abilityToModify.getSourceId()); - if (object != null && object.isInstantOrSorcery(game)) { - return spliceSpellCanBeActivated(source, game); - } - return false; - } - - private boolean spliceSpellCanBeActivated(Ability source, Game game) { - // check if spell can be activated (protection problem not solved because effect will be used from the base spell?) - Card card = game.getCard(source.getSourceId()); - if (card != null) { - if (card.getManaCost().isEmpty()) { // e.g. Evermind - return card.getSpellAbility().spellCanBeActivatedRegularlyNow(source.getControllerId(), game); - } else { - return card.getSpellAbility().canActivate(source.getControllerId(), game).canActivate(); - } - } - return false; - } -}