[SPE] Implement Sensational Spider-Man

This commit is contained in:
theelk801 2025-04-17 20:52:49 -04:00
parent f3c53b884a
commit 5e27be4dfa
5 changed files with 132 additions and 16 deletions

View file

@ -0,0 +1,114 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.DefendingPlayerControlsSourceAttackingPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetPermanentAmount;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SensationalSpiderMan extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature defending player controls");
static {
filter.add(DefendingPlayerControlsSourceAttackingPredicate.instance);
}
public SensationalSpiderMan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Sensational Spider-Man attacks, tap target creature defending player controls and put a stun counter on it. Then you may remove up to three stun counters from among all permanents. Draw cards equal to the number of stun counters removed this way.
Ability ability = new AttacksTriggeredAbility(new TapTargetEffect());
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).setText("and put a stun counter on it"));
ability.addEffect(new SensationalSpiderManEffect());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
private SensationalSpiderMan(final SensationalSpiderMan card) {
super(card);
}
@Override
public SensationalSpiderMan copy() {
return new SensationalSpiderMan(this);
}
}
class SensationalSpiderManEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterPermanent("permanents with stun counters on them");
static {
filter.add(CounterType.STUN.getPredicate());
}
SensationalSpiderManEffect() {
super(Outcome.Benefit);
staticText = "then you may remove up to three stun counters from among all permanents. " +
"Draw cards equal to the number of stun counters removed this way";
}
private SensationalSpiderManEffect(final SensationalSpiderManEffect effect) {
super(effect);
}
@Override
public SensationalSpiderManEffect copy() {
return new SensationalSpiderManEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
// TODO: this ideally would be able to prevent the player from choosing a number greater than the number of stun counters available to remove
TargetPermanentAmount target = new TargetPermanentAmount(3, 0, filter);
target.withNotTarget(true);
player.choose(outcome, target, source, game);
int amountRemoved = target
.getTargets()
.stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.mapToInt(permanent -> permanent.removeCounters(
CounterType.STUN.createInstance(target.getTargetAmount(permanent.getId())), source, game
))
.sum();
if (amountRemoved > 1) {
player.drawCards(amountRemoved, source, game);
return true;
}
return false;
}
}

View file

@ -24,6 +24,7 @@ public final class MarvelsSpiderManEternal extends ExpansionSet {
cards.add(new SetCardInfo("Grasping Tentacles", 21, Rarity.RARE, mage.cards.g.GraspingTentacles.class)); cards.add(new SetCardInfo("Grasping Tentacles", 21, Rarity.RARE, mage.cards.g.GraspingTentacles.class));
cards.add(new SetCardInfo("Green Goblin, Nemesis", 23, Rarity.RARE, mage.cards.g.GreenGoblinNemesis.class)); cards.add(new SetCardInfo("Green Goblin, Nemesis", 23, Rarity.RARE, mage.cards.g.GreenGoblinNemesis.class));
cards.add(new SetCardInfo("Pumpkin Bombs", 26, Rarity.RARE, mage.cards.p.PumpkinBombs.class)); cards.add(new SetCardInfo("Pumpkin Bombs", 26, Rarity.RARE, mage.cards.p.PumpkinBombs.class));
cards.add(new SetCardInfo("Sensational Spider-Man", 25, Rarity.RARE, mage.cards.s.SensationalSpiderMan.class));
cards.add(new SetCardInfo("Venom, Deadly Devourer", 22, Rarity.RARE, mage.cards.v.VenomDeadlyDevourer.class)); cards.add(new SetCardInfo("Venom, Deadly Devourer", 22, Rarity.RARE, mage.cards.v.VenomDeadlyDevourer.class));
} }
} }

View file

@ -181,19 +181,21 @@ public interface Card extends MageObject, Ownerable {
* Remove {@param amount} counters of the specified kind. * Remove {@param amount} counters of the specified kind.
* *
* @param isDamage if the counter removal is a result of being damaged (e.g. for Deification to work) * @param isDamage if the counter removal is a result of being damaged (e.g. for Deification to work)
* @return amount of counters removed
*/ */
void removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage); int removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage);
default void removeCounters(Counter counter, Ability source, Game game) { default int removeCounters(Counter counter, Ability source, Game game) {
removeCounters(counter, source, game, false); return removeCounters(counter, source, game, false);
} }
/** /**
* Remove all counters of any kind. * Remove all counters of any kind.
* *
* @param isDamage if the counter removal is a result of being damaged (e.g. for Deification to work) * @param isDamage if the counter removal is a result of being damaged (e.g. for Deification to work)
* @return amount of counters removed
*/ */
void removeCounters(Counter counter, Ability source, Game game, boolean isDamage); int removeCounters(Counter counter, Ability source, Game game, boolean isDamage);
/** /**
* Remove all counters of any kind. * Remove all counters of any kind.

View file

@ -819,19 +819,19 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
} }
@Override @Override
public void removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage) { public int removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage) {
if (amount <= 0) { if (amount <= 0) {
return; return 0;
} }
if (getCounters(game).getCount(counterName) <= 0) { if (getCounters(game).getCount(counterName) <= 0) {
return; return 0;
} }
GameEvent removeCountersEvent = new RemoveCountersEvent(counterName, this, source, amount, isDamage); GameEvent removeCountersEvent = new RemoveCountersEvent(counterName, this, source, amount, isDamage);
if (game.replaceEvent(removeCountersEvent)) { if (game.replaceEvent(removeCountersEvent)) {
return; return 0;
} }
int finalAmount = 0; int finalAmount = 0;
@ -854,13 +854,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
GameEvent event = new CountersRemovedEvent(counterName, this, source, finalAmount, isDamage); GameEvent event = new CountersRemovedEvent(counterName, this, source, finalAmount, isDamage);
game.fireEvent(event); game.fireEvent(event);
return finalAmount;
} }
@Override @Override
public void removeCounters(Counter counter, Ability source, Game game, boolean isDamage) { public int removeCounters(Counter counter, Ability source, Game game, boolean isDamage) {
if (counter != null) { return counter != null ? removeCounters(counter.getName(), counter.getCount(), source, game, isDamage) : 0;
removeCounters(counter.getName(), counter.getCount(), source, game, isDamage);
}
} }
@Override @Override

View file

@ -1093,13 +1093,13 @@ public class Spell extends StackObjectImpl implements Card {
} }
@Override @Override
public void removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage) { public int removeCounters(String counterName, int amount, Ability source, Game game, boolean isDamage) {
card.removeCounters(counterName, amount, source, game, isDamage); return card.removeCounters(counterName, amount, source, game, isDamage);
} }
@Override @Override
public void removeCounters(Counter counter, Ability source, Game game, boolean isDamage) { public int removeCounters(Counter counter, Ability source, Game game, boolean isDamage) {
card.removeCounters(counter, source, game, isDamage); return card.removeCounters(counter, source, game, isDamage);
} }
@Override @Override