[SPM] Implement Unstable Experiment

This commit is contained in:
theelk801 2025-07-24 13:30:26 -04:00
parent 167a44399a
commit c28a678080
7 changed files with 93 additions and 88 deletions

View file

@ -2,7 +2,7 @@ package mage.cards.c;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect; import mage.abilities.effects.keyword.ConniveTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -30,6 +30,7 @@ public final class ChangeOfPlans extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{U}");
// Each of X target creatures you control connive. You may have any number of them phase out. // Each of X target creatures you control connive. You may have any number of them phase out.
this.getSpellAbility().addEffect(new ConniveTargetEffect().setText("each of X target creatures you control connive"));
this.getSpellAbility().addEffect(new ChangeOfPlansEffect()); this.getSpellAbility().addEffect(new ChangeOfPlansEffect());
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster());
@ -49,7 +50,7 @@ class ChangeOfPlansEffect extends OneShotEffect {
ChangeOfPlansEffect() { ChangeOfPlansEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "each of X target creatures you control connive. You may have any number of them phase out"; staticText = "You may have any number of them phase out";
} }
private ChangeOfPlansEffect(final ChangeOfPlansEffect effect) { private ChangeOfPlansEffect(final ChangeOfPlansEffect effect) {
@ -73,9 +74,6 @@ class ChangeOfPlansEffect extends OneShotEffect {
if (permanents.isEmpty()) { if (permanents.isEmpty()) {
return false; return false;
} }
for (Permanent permanent : permanents) {
ConniveSourceEffect.connive(permanent, 1, source, game);
}
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null) { if (player == null) {
return true; return true;

View file

@ -6,7 +6,7 @@ import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect; import mage.abilities.effects.keyword.ConniveTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.DoubleStrikeAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -39,7 +39,7 @@ public final class KamizObscuraOculus extends CardImpl {
// Whenever you attack, target attacking creature can't be blocked this turn. It connives. Then choose another attacking creature with lesser power. That creature gains double strike until end of turn. // Whenever you attack, target attacking creature can't be blocked this turn. It connives. Then choose another attacking creature with lesser power. That creature gains double strike until end of turn.
Ability ability = new AttacksWithCreaturesTriggeredAbility(new CantBeBlockedTargetEffect(), 1); Ability ability = new AttacksWithCreaturesTriggeredAbility(new CantBeBlockedTargetEffect(), 1);
ability.addEffect(new KamizConniveEffect()); ability.addEffect(new ConniveTargetEffect().setText("it connives"));
ability.addEffect(new KamizDoubleStrikeEffect().concatBy("Then")); ability.addEffect(new KamizDoubleStrikeEffect().concatBy("Then"));
ability.addTarget(new TargetAttackingCreature()); ability.addTarget(new TargetAttackingCreature());
this.addAbility(ability); this.addAbility(ability);
@ -55,29 +55,6 @@ public final class KamizObscuraOculus extends CardImpl {
} }
} }
class KamizConniveEffect extends OneShotEffect {
KamizConniveEffect() {
super(Outcome.Benefit);
staticText = "it connives";
}
private KamizConniveEffect(final KamizConniveEffect effect) {
super(effect);
}
@Override
public KamizConniveEffect copy() {
return new KamizConniveEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
return ConniveSourceEffect.connive(permanent, 1, source, game);
}
}
class KamizDoubleStrikeEffect extends OneShotEffect { class KamizDoubleStrikeEffect extends OneShotEffect {
KamizDoubleStrikeEffect() { KamizDoubleStrikeEffect() {
@ -109,8 +86,8 @@ class KamizDoubleStrikeEffect extends OneShotEffect {
if (target.choose(outcome, source.getControllerId(), source.getSourceId(), source, game)) { if (target.choose(outcome, source.getControllerId(), source.getSourceId(), source, game)) {
game.addEffect( game.addEffect(
new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance()) new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance())
.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)) .setTargetPointer(new FixedTarget(target.getFirstTarget(), game)), source
, source); );
} }
return true; return true;
} }

View file

@ -5,7 +5,7 @@ import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect; import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect; import mage.abilities.effects.keyword.ConniveTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -14,7 +14,6 @@ import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
@ -44,7 +43,7 @@ public final class ObscuraConfluence extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Target creature connives. // Target creature connives.
this.getSpellAbility().addMode(new Mode(new ObscuraConfluenceConniveEffect()).addTarget(new TargetCreaturePermanent())); this.getSpellAbility().addMode(new Mode(new ConniveTargetEffect()).addTarget(new TargetCreaturePermanent()));
// Target player returns a creature card from their graveyard to their hand. // Target player returns a creature card from their graveyard to their hand.
this.getSpellAbility().addMode(new Mode(new ObscuraConfluenceReturnEffect()).addTarget(new TargetPlayer())); this.getSpellAbility().addMode(new Mode(new ObscuraConfluenceReturnEffect()).addTarget(new TargetPlayer()));
@ -60,30 +59,6 @@ public final class ObscuraConfluence extends CardImpl {
} }
} }
class ObscuraConfluenceConniveEffect extends OneShotEffect {
ObscuraConfluenceConniveEffect() {
super(Outcome.Benefit);
staticText = "target creature connives. <i>(Draw a card, then discard a card. " +
"If you discarded a nonland card, put a +1/+1 counter on that creature.)</i>";
}
private ObscuraConfluenceConniveEffect(final ObscuraConfluenceConniveEffect effect) {
super(effect);
}
@Override
public ObscuraConfluenceConniveEffect copy() {
return new ObscuraConfluenceConniveEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
return ConniveSourceEffect.connive(permanent, 1, source, game);
}
}
class ObscuraConfluenceReturnEffect extends OneShotEffect { class ObscuraConfluenceReturnEffect extends OneShotEffect {
ObscuraConfluenceReturnEffect() { ObscuraConfluenceReturnEffect() {

View file

@ -2,17 +2,14 @@ package mage.cards.s;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.keyword.ConniveTargetEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.game.Game;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID; import java.util.UUID;
@ -36,7 +33,7 @@ public final class ScorpionSeethingStriker extends CardImpl {
this.addAbility(DeathtouchAbility.getInstance()); this.addAbility(DeathtouchAbility.getInstance());
// At the beginning of your end step, if a creature died this turn, target creature you control connives. // At the beginning of your end step, if a creature died this turn, target creature you control connives.
Ability ability = new BeginningOfEndStepTriggeredAbility(new ScorpionSeethingStrikerEffect()); Ability ability = new BeginningOfEndStepTriggeredAbility(new ConniveTargetEffect());
ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);
} }
@ -50,27 +47,3 @@ public final class ScorpionSeethingStriker extends CardImpl {
return new ScorpionSeethingStriker(this); return new ScorpionSeethingStriker(this);
} }
} }
class ScorpionSeethingStrikerEffect extends OneShotEffect {
ScorpionSeethingStrikerEffect() {
super(Outcome.Benefit);
staticText = "target creature you control connives";
}
private ScorpionSeethingStrikerEffect(final ScorpionSeethingStrikerEffect effect) {
super(effect);
}
@Override
public ScorpionSeethingStrikerEffect copy() {
return new ScorpionSeethingStrikerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return ConniveSourceEffect.connive(
game.getPermanent(getTargetPointer().getFirst(game, source)), 1, source, game
);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.u;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.abilities.effects.keyword.ConniveTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class UnstableExperiment extends CardImpl {
public UnstableExperiment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Target player draws a card, then up to one target creature you control connives.
this.getSpellAbility().addEffect(new DrawCardTargetEffect(1));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new ConniveTargetEffect().setTargetPointer(new SecondTargetPointer()).concatBy(", then"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 1));
}
private UnstableExperiment(final UnstableExperiment card) {
super(card);
}
@Override
public UnstableExperiment copy() {
return new UnstableExperiment(this);
}
}

View file

@ -62,6 +62,7 @@ public final class MarvelsSpiderMan extends ExpansionSet {
cards.add(new SetCardInfo("Taxi Driver", 97, Rarity.COMMON, mage.cards.t.TaxiDriver.class)); cards.add(new SetCardInfo("Taxi Driver", 97, Rarity.COMMON, mage.cards.t.TaxiDriver.class));
cards.add(new SetCardInfo("Thwip!", 20, Rarity.COMMON, mage.cards.t.Thwip.class)); cards.add(new SetCardInfo("Thwip!", 20, Rarity.COMMON, mage.cards.t.Thwip.class));
cards.add(new SetCardInfo("Tombstone, Career Criminal", 70, Rarity.UNCOMMON, mage.cards.t.TombstoneCareerCriminal.class)); cards.add(new SetCardInfo("Tombstone, Career Criminal", 70, Rarity.UNCOMMON, mage.cards.t.TombstoneCareerCriminal.class));
cards.add(new SetCardInfo("Unstable Experiment", 47, Rarity.COMMON, mage.cards.u.UnstableExperiment.class));
cards.add(new SetCardInfo("Venom's Hunger", 73, Rarity.COMMON, mage.cards.v.VenomsHunger.class)); cards.add(new SetCardInfo("Venom's Hunger", 73, Rarity.COMMON, mage.cards.v.VenomsHunger.class));
cards.add(new SetCardInfo("Venom, Evil Unleashed", 71, Rarity.COMMON, mage.cards.v.VenomEvilUnleashed.class)); cards.add(new SetCardInfo("Venom, Evil Unleashed", 71, Rarity.COMMON, mage.cards.v.VenomEvilUnleashed.class));
cards.add(new SetCardInfo("Web Up", 21, Rarity.COMMON, mage.cards.w.WebUp.class)); cards.add(new SetCardInfo("Web Up", 21, Rarity.COMMON, mage.cards.w.WebUp.class));

View file

@ -0,0 +1,44 @@
package mage.abilities.effects.keyword;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import java.util.UUID;
/**
* @author TheElk801
*/
public class ConniveTargetEffect extends OneShotEffect {
public ConniveTargetEffect() {
super(Outcome.Benefit);
}
private ConniveTargetEffect(final ConniveTargetEffect effect) {
super(effect);
}
@Override
public ConniveTargetEffect copy() {
return new ConniveTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
ConniveSourceEffect.connive(game.getPermanent(targetId), 1, source, game);
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return this.getTargetPointer().describeTargets(mode.getTargets(), "it") + " connives";
}
}