Merge pull request 'master' (#30) from External/mage:master into master
Some checks failed
/ build_release (push) Failing after 14m42s

Reviewed-on: #30
This commit is contained in:
Failure 2025-07-24 12:41:41 -07:00
commit 72d0a56c31
100 changed files with 3197 additions and 400 deletions

View file

@ -591,6 +591,7 @@ public class ScryfallImageSupportCards {
add("EOE"); // Edge of Eternities add("EOE"); // Edge of Eternities
add("EOC"); // Edge of Eternities Commander add("EOC"); // Edge of Eternities Commander
add("EOS"); // Edge of Eternities: Stellar Sights add("EOS"); // Edge of Eternities: Stellar Sights
add("SPM"); // Marvel's Spider-Man
add("SPE"); // Marvel's Spider-Man Eternal add("SPE"); // Marvel's Spider-Man Eternal
add("TLA"); // Avatar: The Last Airbender add("TLA"); // Avatar: The Last Airbender

View file

@ -10,6 +10,7 @@ public class DuelCommander extends Commander {
banned.add("Ancestral Recall"); banned.add("Ancestral Recall");
banned.add("Ancient Tomb"); banned.add("Ancient Tomb");
banned.add("Back to Basics"); banned.add("Back to Basics");
banned.add("Balance");
banned.add("Bazaar of Baghdad"); banned.add("Bazaar of Baghdad");
banned.add("Black Lotus"); banned.add("Black Lotus");
banned.add("Capture of Jingzhou"); banned.add("Capture of Jingzhou");
@ -32,9 +33,9 @@ public class DuelCommander extends Commander {
banned.add("Gifts Ungiven"); banned.add("Gifts Ungiven");
banned.add("Grim Monolith"); banned.add("Grim Monolith");
banned.add("Hermit Druid"); banned.add("Hermit Druid");
banned.add("Hogaak, Arisen Necropolis");
banned.add("Humility"); banned.add("Humility");
banned.add("Imperial Seal"); banned.add("Imperial Seal");
banned.add("Invert Polarity");
banned.add("Jeweled Lotus"); banned.add("Jeweled Lotus");
banned.add("Karakas"); banned.add("Karakas");
banned.add("Library of Alexandria"); banned.add("Library of Alexandria");
@ -63,6 +64,7 @@ public class DuelCommander extends Commander {
banned.add("Protean Hulk"); banned.add("Protean Hulk");
banned.add("Ragavan, Nimble Pilferer"); banned.add("Ragavan, Nimble Pilferer");
banned.add("Rain of Filth"); banned.add("Rain of Filth");
banned.add("Reanimate");
banned.add("Scapeshift"); banned.add("Scapeshift");
banned.add("Sensei's Divining Top"); banned.add("Sensei's Divining Top");
banned.add("Serra's Sanctum"); banned.add("Serra's Sanctum");
@ -78,13 +80,14 @@ public class DuelCommander extends Commander {
banned.add("Time Warp"); banned.add("Time Warp");
banned.add("Tinker"); banned.add("Tinker");
banned.add("Tolarian Academy"); banned.add("Tolarian Academy");
banned.add("Trazyn The Infinite");
banned.add("Treasure Cruise"); banned.add("Treasure Cruise");
banned.add("Uro, Titan of Nature's Wrath"); banned.add("Uro, Titan of Nature's Wrath");
banned.add("Vampiric Tutor"); banned.add("Vampiric Tutor");
banned.add("Wasteland"); banned.add("Wasteland");
banned.add("White Plume Adventurer");
bannedCommander.add("Ajani, Nacatl Pariah"); bannedCommander.add("Ajani, Nacatl Pariah");
bannedCommander.add("Akiri, Line-Slinger");
bannedCommander.add("Arahbo, Roar of the World"); bannedCommander.add("Arahbo, Roar of the World");
bannedCommander.add("Asmoranomardicadaistinaculdacar"); bannedCommander.add("Asmoranomardicadaistinaculdacar");
bannedCommander.add("Baral, Chief of Compliance"); bannedCommander.add("Baral, Chief of Compliance");
@ -96,14 +99,16 @@ public class DuelCommander extends Commander {
bannedCommander.add("Emry, Lurker of the Loch"); bannedCommander.add("Emry, Lurker of the Loch");
bannedCommander.add("Eris, Roar of the Storm"); bannedCommander.add("Eris, Roar of the Storm");
bannedCommander.add("Esior, Wardwing Familiar"); bannedCommander.add("Esior, Wardwing Familiar");
bannedCommander.add("Ezio Auditore da Firenze");
bannedCommander.add("Geist of Saint Traft"); bannedCommander.add("Geist of Saint Traft");
bannedCommander.add("Inalla, Archmage Ritualist"); bannedCommander.add("Inalla, Archmage Ritualist");
bannedCommander.add("Hogaak, Arisen Necropolis");
bannedCommander.add("Krark, the Thumbless"); bannedCommander.add("Krark, the Thumbless");
bannedCommander.add("Minsc & Boo, Timeless Heroes"); bannedCommander.add("Minsc & Boo, Timeless Heroes");
bannedCommander.add("Nadu, Winged Wisdom"); bannedCommander.add("Nadu, Winged Wisdom");
bannedCommander.add("Najeela, the Blade-Blossom"); bannedCommander.add("Najeela, the Blade-Blossom");
bannedCommander.add("Oloro, Ageless Ascetic");
bannedCommander.add("Old Stickfingers"); bannedCommander.add("Old Stickfingers");
bannedCommander.add("Oloro, Ageless Ascetic");
bannedCommander.add("Omnath, Locus of Creation"); bannedCommander.add("Omnath, Locus of Creation");
bannedCommander.add("Prime Speaker Vannifar"); bannedCommander.add("Prime Speaker Vannifar");
bannedCommander.add("Raffine, Scheming Seer"); bannedCommander.add("Raffine, Scheming Seer");
@ -115,6 +120,5 @@ public class DuelCommander extends Commander {
bannedCommander.add("Vial Smasher the Fierce"); bannedCommander.add("Vial Smasher the Fierce");
bannedCommander.add("Winota, Joiner of Forces"); bannedCommander.add("Winota, Joiner of Forces");
bannedCommander.add("Yuriko, the Tiger's Shadow"); bannedCommander.add("Yuriko, the Tiger's Shadow");
bannedCommander.add("Zurgo Bellstriker");
} }
} }

View file

@ -1,16 +1,12 @@
package mage.cards.a; package mage.cards.a;
import mage.abilities.Ability; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.Mode;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.cards.Cards;
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.PutCards; import mage.constants.PutCards;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID; import java.util.UUID;
@ -24,7 +20,9 @@ public final class AdventureAwaits extends CardImpl {
// Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand.
// Put the rest on the bottom of your library in a random order. If you don't put a card into your hand this way, draw a card. // Put the rest on the bottom of your library in a random order. If you don't put a card into your hand this way, draw a card.
this.getSpellAbility().addEffect(new AdventureAwaitsEffect()); this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM
).withOtherwiseEffect(new DrawCardSourceControllerEffect(1)));
} }
private AdventureAwaits(final AdventureAwaits card) { private AdventureAwaits(final AdventureAwaits card) {
@ -36,33 +34,3 @@ public final class AdventureAwaits extends CardImpl {
return new AdventureAwaits(this); return new AdventureAwaits(this);
} }
} }
class AdventureAwaitsEffect extends LookLibraryAndPickControllerEffect {
AdventureAwaitsEffect() {
super(5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM);
}
private AdventureAwaitsEffect(final AdventureAwaitsEffect effect) {
super(effect);
}
@Override
public AdventureAwaitsEffect copy() {
return new AdventureAwaitsEffect(this);
}
@Override
public boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
if (pickedCards.isEmpty()) {
player.drawCards(1, source, game);
}
return true;
}
@Override
public String getText(Mode mode) {
return super.getText(mode).concat(". If you didn't put a card into your hand this way, draw a card");
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
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.SubType;
import mage.counters.CounterType;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AlchemaxSlayerBots extends CardImpl {
public AlchemaxSlayerBots(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.ROBOT);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When this creature enters, tap target creature an opponent controls and put a stun counter on it.
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect());
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).setText("and put a stun counter on it"));
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
private AlchemaxSlayerBots(final AlchemaxSlayerBots card) {
super(card);
}
@Override
public AlchemaxSlayerBots copy() {
return new AlchemaxSlayerBots(this);
}
}

View file

@ -0,0 +1,38 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AmateurHero extends CardImpl {
public AmateurHero(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When this creature enters, you gain 2 life.
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2)));
}
private AmateurHero(final AmateurHero card) {
super(card);
}
@Override
public AmateurHero copy() {
return new AmateurHero(this);
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AngryRabble extends CardImpl {
public AngryRabble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CITIZEN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever you cast a spell with mana value 4 or greater, this creature deals 1 damage to each opponent.
this.addAbility(new SpellCastControllerTriggeredAbility(
new DamagePlayersEffect(1, TargetController.OPPONENT),
StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false
));
// {5}{R}: Put two +1/+1 counters on this creature. Activate only as a sorcery.
this.addAbility(new ActivateAsSorceryActivatedAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{5}{R}")
));
}
private AngryRabble(final AngryRabble card) {
super(card);
}
@Override
public AngryRabble copy() {
return new AngryRabble(this);
}
}

View file

@ -1,33 +1,31 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.constants.ComparisonType;
import mage.constants.SubType;
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.ComparisonType;
import mage.constants.SubType;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.FilterSpell; import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import java.util.UUID;
/** /**
*
* @author weirddan455 * @author weirddan455
*/ */
public final class AscendantPackleader extends CardImpl { public final class AscendantPackleader extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("a permanent with mana value 4 or greater"); private static final FilterPermanent filter = new FilterPermanent("a permanent with mana value 4 or greater");
private static final FilterSpell filter2 = new FilterSpell("a spell with mana value 4 or greater");
static { static {
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3)); filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
filter2.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
} }
public AscendantPackleader(UUID ownerId, CardSetInfo setInfo) { public AscendantPackleader(UUID ownerId, CardSetInfo setInfo) {
@ -48,8 +46,7 @@ public final class AscendantPackleader extends CardImpl {
// Whenever you cast a spell with mana value 4 or greater, put a +1/+1 counter on Ascendant Packleader. // Whenever you cast a spell with mana value 4 or greater, put a +1/+1 counter on Ascendant Packleader.
this.addAbility(new SpellCastControllerTriggeredAbility( this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
filter2, StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false
false
)); ));
} }

View file

@ -0,0 +1,77 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AuntMay extends CardImpl {
public AuntMay(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CITIZEN);
this.power = new MageInt(0);
this.toughness = new MageInt(2);
// Whenever another creature you control enters, you gain 1 life. If it's a Spider, put a +1/+1 counter on it.
Ability ability = new EntersBattlefieldControlledTriggeredAbility(
Zone.BATTLEFIELD, new GainLifeEffect(1),
StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL,
false, SetTargetPointer.PERMANENT
);
ability.addEffect(new AuntMayEffect());
this.addAbility(ability);
}
private AuntMay(final AuntMay card) {
super(card);
}
@Override
public AuntMay copy() {
return new AuntMay(this);
}
}
class AuntMayEffect extends OneShotEffect {
AuntMayEffect() {
super(Outcome.Benefit);
staticText = "If it's a Spider, put a +1/+1 counter on it";
}
private AuntMayEffect(final AuntMayEffect effect) {
super(effect);
}
@Override
public AuntMayEffect copy() {
return new AuntMayEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return Optional
.ofNullable(getTargetPointer().getFirst(game, source))
.map(game::getPermanent)
.filter(permanent -> permanent.hasSubtype(SubType.SPIDER, game))
.filter(permanent -> permanent.addCounters(CounterType.P1P1.createInstance(), source, game))
.isPresent();
}
}

View file

@ -28,7 +28,7 @@ public final class AuxiliaryBoosters extends CardImpl {
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// When this Equipment enters, create a 2/2 colorless Robot artifact creature token and attach this Equipment to it. // When this Equipment enters, create a 2/2 colorless Robot artifact creature token and attach this Equipment to it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenAttachSourceEffect(new RobotToken()))); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenAttachSourceEffect(new RobotToken(), " and")));
// Equipped creature gets +1/+2 and has flying. // Equipped creature gets +1/+2 and has flying.
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 2)); Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 2));

View file

@ -0,0 +1,59 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.ExileSourceFromGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BeetleLegacyCriminal extends CardImpl {
public BeetleLegacyCriminal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// {1}{U}, Exile this card from your graveyard: Put a +1/+1 counter on target creature. It gains flying until end of turn. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
Zone.GRAVEYARD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{1}{U}")
);
ability.addCost(new ExileSourceFromGraveCost());
ability.addTarget(new TargetCreaturePermanent());
ability.addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance())
.setText("Put a +1/+1 counter on target creature"));
this.addAbility(ability);
}
private BeetleLegacyCriminal(final BeetleLegacyCriminal card) {
super(card);
}
@Override
public BeetleLegacyCriminal copy() {
return new BeetleLegacyCriminal(this);
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.abilities.condition.common.KickedCondition; import mage.abilities.condition.common.KickedCondition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@ -13,8 +10,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.target.common.TargetNonlandPermanent; import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/** /**
*
* @author JRHerlehy * @author JRHerlehy
*/ */
public final class BlinkOfAnEye extends CardImpl { public final class BlinkOfAnEye extends CardImpl {
@ -26,10 +24,12 @@ public final class BlinkOfAnEye extends CardImpl {
this.addAbility(new KickerAbility("{1}{U}")); this.addAbility(new KickerAbility("{1}{U}"));
// Return target nonland permanent to its owner's hand. If this spell was kicked, draw a card. // Return target nonland permanent to its owner's hand. If this spell was kicked, draw a card.
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DrawCardSourceControllerEffect(1), KickedCondition.ONCE, this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
"If this spell was kicked, draw a card")); new DrawCardSourceControllerEffect(1),
KickedCondition.ONCE, "if this spell was kicked, draw a card"
));
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
} }
private BlinkOfAnEye(final BlinkOfAnEye card) { private BlinkOfAnEye(final BlinkOfAnEye card) {

View file

@ -1,12 +1,10 @@
package mage.cards.b; package mage.cards.b;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.keyword.ReachAbility; import mage.abilities.keyword.ReachAbility;
import mage.cards.Cards;
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,8 +12,6 @@ import mage.constants.PutCards;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID; import java.util.UUID;
@ -24,6 +20,15 @@ import java.util.UUID;
*/ */
public final class BlossomPrancer extends CardImpl { public final class BlossomPrancer extends CardImpl {
private static final FilterCard filter = new FilterCard("creature or enchantment card");
static {
filter.add(Predicates.or(
CardType.CREATURE.getPredicate(),
CardType.ENCHANTMENT.getPredicate()
));
}
public BlossomPrancer(UUID ownerId, CardSetInfo setInfo) { public BlossomPrancer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
@ -38,7 +43,9 @@ public final class BlossomPrancer extends CardImpl {
// You may reveal a creature or enchantment card from among them and put it into your hand. // You may reveal a creature or enchantment card from among them and put it into your hand.
// Put the rest on the bottom of your library in a random order. // Put the rest on the bottom of your library in a random order.
// If you didn't put a card into your hand this way, you gain 4 life. // If you didn't put a card into your hand this way, you gain 4 life.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BlossomPrancerEffect())); this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM
).withOtherwiseEffect(new GainLifeEffect(4))));
} }
private BlossomPrancer(final BlossomPrancer card) { private BlossomPrancer(final BlossomPrancer card) {
@ -50,42 +57,3 @@ public final class BlossomPrancer extends CardImpl {
return new BlossomPrancer(this); return new BlossomPrancer(this);
} }
} }
class BlossomPrancerEffect extends LookLibraryAndPickControllerEffect {
private static final FilterCard filter = new FilterCard("creature or enchantment card");
static {
filter.add(Predicates.or(
CardType.CREATURE.getPredicate(),
CardType.ENCHANTMENT.getPredicate()
));
}
BlossomPrancerEffect() {
super(5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM);
}
private BlossomPrancerEffect(final BlossomPrancerEffect effect) {
super(effect);
}
@Override
public BlossomPrancerEffect copy() {
return new BlossomPrancerEffect(this);
}
@Override
public boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
if (pickedCards.isEmpty()) {
player.gainLife(4, game, source);
}
return true;
}
@Override
public String getText(Mode mode) {
return super.getText(mode).concat(". If you didn't put a card into your hand this way, you gain 4 life");
}
}

View file

@ -1,20 +1,15 @@
package mage.cards.c; package mage.cards.c;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.counter.ProliferateEffect; import mage.abilities.effects.common.counter.ProliferateEffect;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.PutCards;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID; import java.util.UUID;
@ -33,7 +28,9 @@ public final class ContagiousVorrac extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// When Contagious Vorrac enters the battlefield, look at the top four cards of your library. You may reveal a land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, proliferate. // When Contagious Vorrac enters the battlefield, look at the top four cards of your library. You may reveal a land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, proliferate.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ContagiousVorracEffect())); this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
4, 1, StaticFilters.FILTER_CARD_LAND_A, PutCards.HAND, PutCards.BOTTOM_RANDOM
).withOtherwiseEffect(new ProliferateEffect())));
} }
private ContagiousVorrac(final ContagiousVorrac card) { private ContagiousVorrac(final ContagiousVorrac card) {
@ -45,42 +42,3 @@ public final class ContagiousVorrac extends CardImpl {
return new ContagiousVorrac(this); return new ContagiousVorrac(this);
} }
} }
class ContagiousVorracEffect extends OneShotEffect {
ContagiousVorracEffect() {
super(Outcome.Benefit);
staticText = "look at the top four cards of your library. You may reveal a land card from among them " +
"and put it into your hand. Put the rest on the bottom of your library in a random order. " +
"If you didn't put a card into your hand this way, proliferate. " +
"<i>(Choose any number of permanents and/or players, then give each another counter of each kind already there.)</i>";
}
private ContagiousVorracEffect(final ContagiousVorracEffect effect) {
super(effect);
}
@Override
public ContagiousVorracEffect copy() {
return new ContagiousVorracEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
TargetCard target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_LAND);
player.choose(Outcome.DrawCard, cards, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
player.revealCards(source, new CardsImpl(card), game);
player.moveCards(card, Zone.HAND, source, game);
}
cards.retainZone(Zone.LIBRARY, game);
player.putCardsOnBottomOfLibrary(cards, game, source, false);
return card != null || new ProliferateEffect().apply(game, source);
}
}

View file

@ -0,0 +1,63 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DailyBugleReporters extends CardImpl {
private static final FilterCard filter = new FilterCreatureCard("creature card with mana value 2 or less");
static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3));
}
public DailyBugleReporters(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CITIZEN);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// When this creature enters, choose one --
// * Puff Piece -- Put a +1/+1 counter on each of up to two target creatures.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetCreaturePermanent(0, 2));
ability.withFirstModeFlavorWord("Puff Piece");
// * Investigative Journalism -- Return target creature card with mana value 2 or less from your graveyard to your hand.
ability.addMode(new Mode(new ReturnFromGraveyardToHandTargetEffect())
.addTarget(new TargetCardInYourGraveyard(filter))
.withFlavorWord("Investigative Journalism"));
this.addAbility(ability);
}
private DailyBugleReporters(final DailyBugleReporters card) {
super(card);
}
@Override
public DailyBugleReporters copy() {
return new DailyBugleReporters(this);
}
}

View file

@ -7,7 +7,7 @@ import mage.abilities.keyword.VigilanceAbility;
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.target.common.TargetCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID; import java.util.UUID;
@ -20,11 +20,12 @@ public final class DiplomaticRelations extends CardImpl {
public DiplomaticRelations(UUID ownerId, CardSetInfo setInfo) { public DiplomaticRelations(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Target creature gets +1/+0 and gains vigilance until end of turn. It deals damage equal to its power to target creature an opponent controls. // Target creature you control gets +1/+0 and gains vigilance until end of turn. It deals damage equal to its power to target creature an opponent controls.
this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0)); this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0)
.setText("target creature you control gets +1/+0"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance()) this.getSpellAbility().addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance())
.setText("and gains vigilance until end of turn")); .setText("and gains vigilance until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("it")); this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("it"));
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent()); this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent());
} }

View file

@ -1,34 +1,25 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID;
import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.effects.common.CounterTargetEffect;
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.ComparisonType; import mage.filter.StaticFilters;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.TargetSpell; import mage.target.TargetSpell;
import java.util.UUID;
/** /**
*
* @author emerald000 * @author emerald000
*/ */
public final class DisdainfulStroke extends CardImpl { public final class DisdainfulStroke extends CardImpl {
private static final FilterSpell filter = new FilterSpell("spell with mana value 4 or greater");
static {
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
}
public DisdainfulStroke(UUID ownerId, CardSetInfo setInfo) { public DisdainfulStroke(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Counter target spell with converted mana cost 4 or greater. // Counter target spell with converted mana cost 4 or greater.
this.getSpellAbility().addEffect(new CounterTargetEffect()); this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell(filter)); this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_MV_4_OR_GREATER));
} }
private DisdainfulStroke(final DisdainfulStroke card) { private DisdainfulStroke(final DisdainfulStroke card) {

View file

@ -0,0 +1,42 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.keyword.ConniveSourceEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DocOcksHenchmen extends CardImpl {
public DocOcksHenchmen(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Flash
this.addAbility(FlashAbility.getInstance());
// Whenever this creature attacks, it connives.
this.addAbility(new AttacksTriggeredAbility(new ConniveSourceEffect()));
}
private DocOcksHenchmen(final DocOcksHenchmen card) {
super(card);
}
@Override
public DocOcksHenchmen copy() {
return new DocOcksHenchmen(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.MillThenPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class EerieGravestone extends CardImpl {
public EerieGravestone(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// When this artifact enters, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
// {1}{B}, Sacrifice this artifact: Mill four cards. You may put a creature card from among them into your hand.
Ability ability = new SimpleActivatedAbility(
new MillThenPutInHandEffect(4, StaticFilters.FILTER_CARD_CREATURE), new ManaCostsImpl<>("{1}{B}")
);
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
private EerieGravestone(final EerieGravestone card) {
super(card);
}
@Override
public EerieGravestone copy() {
return new EerieGravestone(this);
}
}

View file

@ -6,10 +6,8 @@ import mage.abilities.effects.common.CreateTokenEffect;
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.ComparisonType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.FilterSpell; import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.permanent.token.ThopterColorlessToken; import mage.game.permanent.token.ThopterColorlessToken;
import java.util.UUID; import java.util.UUID;
@ -19,12 +17,6 @@ import java.util.UUID;
*/ */
public final class EtheriumSpinner extends CardImpl { public final class EtheriumSpinner extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a spell with mana value 4 or greater");
static {
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
}
public EtheriumSpinner(UUID ownerId, CardSetInfo setInfo) { public EtheriumSpinner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}");
@ -35,7 +27,8 @@ public final class EtheriumSpinner extends CardImpl {
// Whenever you cast a spell with mana value 4 or greater, create a 1/1 colorless Thopter artifact creature token with flying. // Whenever you cast a spell with mana value 4 or greater, create a 1/1 colorless Thopter artifact creature token with flying.
this.addAbility(new SpellCastControllerTriggeredAbility( this.addAbility(new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new ThopterColorlessToken()), filter, false new CreateTokenEffect(new ThopterColorlessToken()),
StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false
)); ));
} }

View file

@ -0,0 +1,54 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FlyingOctobot extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.VILLAIN, "another Villain you control");
static {
filter.add(AnotherPredicate.instance);
}
public FlyingOctobot(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.ROBOT);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever another Villain you control enters, put a +1/+1 counter on this creature. This ability triggers only once each turn.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter
).setTriggersLimitEachTurn(1));
}
private FlyingOctobot(final FlyingOctobot card) {
super(card);
}
@Override
public FlyingOctobot copy() {
return new FlyingOctobot(this);
}
}

View file

@ -1,6 +1,5 @@
package mage.cards.f; package mage.cards.f;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect;
@ -17,7 +16,6 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
/** /**
@ -63,11 +61,7 @@ class FullBoreEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null if (permanent == null || !WarpAbility.checkIfPermanentWarped(permanent, game)) {
|| !game
.getPermanentCostsTags()
.getOrDefault(new MageObjectReference(permanent, game, -1), Collections.emptyMap())
.containsKey(WarpAbility.WARP_ACTIVATION_VALUE_KEY)) {
return false; return false;
} }
game.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()) game.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance())

View file

@ -0,0 +1,58 @@
package mage.cards.f;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FutureFlight extends CardImpl {
public FutureFlight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget));
// When this Aura enters, draw two cards.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(2)));
// Enchanted creature gets +2/+0 and has flying.
Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 0));
ability.addEffect(new GainAbilityAttachedEffect(
FlyingAbility.getInstance(), AttachmentType.AURA
).setText("and has flying"));
this.addAbility(ability);
}
private FutureFlight(final FutureFlight card) {
super(card);
}
@Override
public FutureFlight copy() {
return new FutureFlight(this);
}
}

View file

@ -82,7 +82,7 @@ class GemstoneCavernsAbility extends StaticAbility implements OpeningHandAction
@Override @Override
public String getRule() { public String getRule() {
return "If {this} is in your opening hand and you're not the starting player, you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand."; return "If this card is in your opening hand and you're not the starting player, you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand.";
} }
@Override @Override

View file

@ -0,0 +1,44 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GrendelSpawnOfKnull extends CardImpl {
public GrendelSpawnOfKnull(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SYMBIOTE);
this.subtype.add(SubType.DRAGON);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
}
private GrendelSpawnOfKnull(final GrendelSpawnOfKnull card) {
super(card);
}
@Override
public GrendelSpawnOfKnull copy() {
return new GrendelSpawnOfKnull(this);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GuyInTheChair extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.SPIDER, "Spider");
public GuyInTheChair(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// {T}: Add one mana of any color.
this.addAbility(new AnyColorManaAbility());
// Web Support -- {2}{G}, {T}: Put a +1/+1 counter on target Spider. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{2}{G}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability.withFlavorWord("Web Support"));
}
private GuyInTheChair(final GuyInTheChair card) {
super(card);
}
@Override
public GuyInTheChair copy() {
return new GuyInTheChair(this);
}
}

View file

@ -21,7 +21,7 @@ import java.util.UUID;
public final class IllvoiLightJammer extends CardImpl { public final class IllvoiLightJammer extends CardImpl {
public IllvoiLightJammer(UUID ownerId, CardSetInfo setInfo) { public IllvoiLightJammer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{R}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{U}");
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);

View file

@ -1,8 +1,5 @@
package mage.cards.i; package mage.cards.i;
import java.util.UUID;
import mage.abilities.condition.common.KickedCondition; import mage.abilities.condition.common.KickedCondition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@ -13,15 +10,15 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.target.common.TargetNonlandPermanent; import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/** /**
*
* @author Viserion * @author Viserion
*/ */
public final class IntoTheRoil extends CardImpl { public final class IntoTheRoil extends CardImpl {
public IntoTheRoil(UUID ownerId, CardSetInfo setInfo) { public IntoTheRoil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Kicker {1}{U} (You may pay an additional {1}{U} as you cast this spell.) // Kicker {1}{U} (You may pay an additional {1}{U} as you cast this spell.)
this.addAbility(new KickerAbility("{1}{U}")); this.addAbility(new KickerAbility("{1}{U}"));
@ -30,8 +27,8 @@ public final class IntoTheRoil extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),
KickedCondition.ONCE, KickedCondition.ONCE, "if this spell was kicked, draw a card"
"if this spell was kicked, draw a card")); ));
this.getSpellAbility().addTarget(new TargetNonlandPermanent()); this.getSpellAbility().addTarget(new TargetNonlandPermanent());
} }

View file

@ -0,0 +1,37 @@
package mage.cards.k;
import mage.abilities.effects.common.FightTargetsEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Kapow extends CardImpl {
public Kapow(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
// Put a +1/+1 counter on target creature you control. It fights target creature an opponent controls.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
this.getSpellAbility().addEffect(new FightTargetsEffect().setText("It fights target creature an opponent controls"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent());
}
private Kapow(final Kapow card) {
super(card);
}
@Override
public Kapow copy() {
return new Kapow(this);
}
}

View file

@ -32,7 +32,7 @@ public final class KavaronTurbodrone extends CardImpl {
// {T}: Target creature you control gets +1/+1 and gains haste until end of turn. Activate only as a sorcery. // {T}: Target creature you control gets +1/+1 and gains haste until end of turn. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility( Ability ability = new ActivateAsSorceryActivatedAbility(
new BoostTargetEffect(1, 1, Duration.EndOfTurn) new BoostTargetEffect(1, 1, Duration.EndOfTurn)
.setText("Target creature gets +1/+1"), .setText("Target creature you control gets +1/+1"),
new TapSourceCost() new TapSourceCost()
); );
ability.addEffect(new GainAbilityTargetEffect( ability.addEffect(new GainAbilityTargetEffect(

View file

@ -0,0 +1,42 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KravensCats extends CardImpl {
public KravensCats(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.CAT);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {2}{G}: This creature gets +2/+2 until end of turn. Activate only once each turn.
this.addAbility(new LimitedTimesPerTurnActivatedAbility(
new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{G}")
));
}
private KravensCats(final KravensCats card) {
super(card);
}
@Override
public KravensCats copy() {
return new KravensCats(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.l;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class LurkingLizards extends CardImpl {
public LurkingLizards(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.LIZARD);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever you cast a spell with mana value 4 or greater, put a +1/+1 counter on this creature.
this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false
));
}
private LurkingLizards(final LurkingLizards card) {
super(card);
}
@Override
public LurkingLizards copy() {
return new LurkingLizards(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.l;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DrawCardControllerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
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.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class LylaHolographicAssistant extends CardImpl {
public LylaHolographicAssistant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ILLUSION);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever you draw a card, put a +1/+1 counter on target creature.
Ability ability = new DrawCardControllerTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private LylaHolographicAssistant(final LylaHolographicAssistant card) {
super(card);
}
@Override
public LylaHolographicAssistant copy() {
return new LylaHolographicAssistant(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
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 java.util.UUID;
/**
* @author TheElk801
*/
public final class MJRisingStar extends CardImpl {
public MJRisingStar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.PERFORMER);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever you gain life, put a +1/+1 counter on MJ.
this.addAbility(new GainLifeControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
}
private MJRisingStar(final MJRisingStar card) {
super(card);
}
@Override
public MJRisingStar copy() {
return new MJRisingStar(this);
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MaskedMeower extends CardImpl {
public MaskedMeower(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.CAT);
this.subtype.add(SubType.HERO);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Haste
this.addAbility(HasteAbility.getInstance());
// Discard a card, Sacrifice this creature: Draw a card.
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new DiscardCardCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
private MaskedMeower(final MaskedMeower card) {
super(card);
}
@Override
public MaskedMeower copy() {
return new MaskedMeower(this);
}
}

View file

@ -37,7 +37,7 @@ public final class MechanShieldmate extends CardImpl {
new ConditionalAsThoughEffect( new ConditionalAsThoughEffect(
new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield), new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield),
ArtifactEnteredUnderYourControlCondition.instance ArtifactEnteredUnderYourControlCondition.instance
).setText("As long as an artifact entered the battlefield under your control this turn," ).setText("As long as an artifact entered the battlefield under your control this turn, "
+ "this creature can attack as though it didn't have defender") + "this creature can attack as though it didn't have defender")
).addHint(new ConditionHint(ArtifactEnteredUnderYourControlCondition.instance)), ).addHint(new ConditionHint(ArtifactEnteredUnderYourControlCondition.instance)),
new ArtifactEnteredControllerWatcher() new ArtifactEnteredControllerWatcher()

View file

@ -21,7 +21,7 @@ import java.util.UUID;
public final class MentalModulation extends CardImpl { public final class MentalModulation extends CardImpl {
public MentalModulation(UUID ownerId, CardSetInfo setInfo) { public MentalModulation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}{B}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// This spell costs {1} less to cast during your turn. // This spell costs {1} less to cast during your turn.
Ability ability = new SimpleStaticAbility( Ability ability = new SimpleStaticAbility(
@ -46,4 +46,4 @@ public final class MentalModulation extends CardImpl {
public MentalModulation copy() { public MentalModulation copy() {
return new MentalModulation(this); return new MentalModulation(this);
} }
} }

View file

@ -0,0 +1,47 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MercilessEnforcers extends CardImpl {
public MercilessEnforcers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MERCENARY);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// {3}{B}: This creature deals 1 damage to each opponent.
this.addAbility(new SimpleActivatedAbility(
new DamagePlayersEffect(1, TargetController.OPPONENT), new ManaCostsImpl<>("{3}{B}")
));
}
private MercilessEnforcers(final MercilessEnforcers card) {
super(card);
}
@Override
public MercilessEnforcers copy() {
return new MercilessEnforcers(this);
}
}

View file

@ -0,0 +1,168 @@
package mage.cards.m;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MonstrousEmergence extends CardImpl {
public MonstrousEmergence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
// As an additional cost to cast this spell, choose a creature you control or reveal a creature card from your hand.
this.getSpellAbility().addCost(new MonstrousEmergenceCost());
// Monstrous Emergence deals damage equal to the power of the creature you chose or the card you revealed to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(MonstrousEmergenceValue.instance)
.setText("{this} deals damage equal to the power of the creature you chose or the card you revealed to target creature"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private MonstrousEmergence(final MonstrousEmergence card) {
super(card);
}
@Override
public MonstrousEmergence copy() {
return new MonstrousEmergence(this);
}
}
enum MonstrousEmergenceValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return Optional
.ofNullable((Card) effect.getValue("monstrousEmergenceCost"))
.map(MageObject::getPower)
.map(MageInt::getValue)
.orElse(0);
}
@Override
public MonstrousEmergenceValue copy() {
return this;
}
@Override
public String getMessage() {
return "power of the creature you chose or the card you revealed";
}
@Override
public String toString() {
return "1";
}
}
class MonstrousEmergenceCost extends CostImpl {
public MonstrousEmergenceCost() {
super();
this.text = "choose a creature you control or reveal a creature card from your hand";
}
private MonstrousEmergenceCost(final MonstrousEmergenceCost cost) {
super(cost);
}
@Override
public MonstrousEmergenceCost copy() {
return new MonstrousEmergenceCost(this);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return Optional
.ofNullable(source)
.map(Controllable::getControllerId)
.map(game::getPlayer)
.map(Player::getHand)
.filter(hand -> hand.count(StaticFilters.FILTER_CARD_CREATURE, game) > 0)
.isPresent()
|| game
.getBattlefield()
.contains(StaticFilters.FILTER_CONTROLLED_CREATURE, controllerId, source, game, 1);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player player = game.getPlayer(controllerId);
if (player == null) {
paid = false;
return paid;
}
boolean hasPermanent = game
.getBattlefield()
.contains(StaticFilters.FILTER_CONTROLLED_CREATURE, controllerId, source, game, 1);
boolean hasHand = player.getHand().count(StaticFilters.FILTER_CARD_CREATURE, game) > 0;
boolean usePermanent;
if (hasPermanent && hasHand) {
usePermanent = player.chooseUse(
Outcome.Neutral, "Choose a creature you control or reveal a creature card from your hand?",
null, "Choose controlled", "Reveal from hand", source, game
);
} else if (hasPermanent) {
usePermanent = true;
} else if (hasHand) {
usePermanent = false;
} else {
paid = false;
return paid;
}
if (usePermanent) {
TargetPermanent target = new TargetControlledCreaturePermanent();
target.withNotTarget(true);
player.choose(Outcome.Neutral, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
paid = false;
return paid;
}
game.informPlayers(player.getLogName() + " chooses " + permanent.getLogName() + " on the battlefield");
source.getEffects().setValue("monstrousEmergenceCost", permanent);
paid = true;
return true;
}
TargetCard target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
player.choose(Outcome.Neutral, player.getHand(), target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
paid = false;
return paid;
}
player.revealCards(source, new CardsImpl(card), game);
game.informPlayers(player.getLogName() + " reveals " + card.getLogName() + " from their hand");
source.getEffects().setValue("monstrousEmergenceCost", card);
paid = true;
return paid;
}
}

View file

@ -43,7 +43,7 @@ class OrbitalPlungeEffect extends OneShotEffect {
OrbitalPlungeEffect() { OrbitalPlungeEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "{this} deals 6 damage to target creature. " + staticText = "{this} deals 6 damage to target creature. " +
"If excess damage was dealt to a permanent this way, create a Lander token."; "If excess damage was dealt this way, create a Lander token.";
} }
private OrbitalPlungeEffect(final OrbitalPlungeEffect effect) { private OrbitalPlungeEffect(final OrbitalPlungeEffect effect) {

View file

@ -0,0 +1,93 @@
package mage.cards.o;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.Spider21Token;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OriginOfSpiderMan extends CardImpl {
public OriginOfSpiderMan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
this.subtype.add(SubType.SAGA);
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I -- Create a 2/1 green Spider creature token with reach.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new CreateTokenEffect(new Spider21Token()));
// II -- Put a +1/+1 counter on target creature you control. It becomes a legendary Spider Hero in addition to its other types.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_II,
new Effects(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new OriginOfSpiderManEffect()
), new TargetControlledCreaturePermanent()
);
// III -- Target creature you control gains double strike until end of turn.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III,
new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance()),
new TargetControlledCreaturePermanent()
);
this.addAbility(sagaAbility);
}
private OriginOfSpiderMan(final OriginOfSpiderMan card) {
super(card);
}
@Override
public OriginOfSpiderMan copy() {
return new OriginOfSpiderMan(this);
}
}
class OriginOfSpiderManEffect extends ContinuousEffectImpl {
OriginOfSpiderManEffect() {
super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "It becomes a legendary Spider Hero in addition to its other types";
}
private OriginOfSpiderManEffect(final OriginOfSpiderManEffect effect) {
super(effect);
}
@Override
public OriginOfSpiderManEffect copy() {
return new OriginOfSpiderManEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
discard();
return false;
}
permanent.addSuperType(game, SuperType.LEGENDARY);
permanent.addSubType(game, SubType.SPIDER);
permanent.addSubType(game, SubType.HERO);
return true;
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OscorpResearchTeam extends CardImpl {
public OscorpResearchTeam(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCIENTIST);
this.power = new MageInt(1);
this.toughness = new MageInt(5);
// {6}{U}: Draw two cards.
this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(2), new ManaCostsImpl<>("{6}{U}")));
}
private OscorpResearchTeam(final OscorpResearchTeam card) {
super(card);
}
@Override
public OscorpResearchTeam copy() {
return new OscorpResearchTeam(this);
}
}

View file

@ -9,9 +9,9 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterAnyTarget;
import mage.filter.common.FilterPermanentOrPlayer; import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.permanent.AnotherEnchantedPredicate;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
@ -26,10 +26,10 @@ import java.util.UUID;
*/ */
public final class PainForAll extends CardImpl { public final class PainForAll extends CardImpl {
private static final FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("any other target"); private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any other target");
static { static {
filter.getPermanentFilter().add(PainForAllPredicate.instance); filter.getPermanentFilter().add(AnotherEnchantedPredicate.instance);
} }
public PainForAll(UUID ownerId, CardSetInfo setInfo) { public PainForAll(UUID ownerId, CardSetInfo setInfo) {
@ -64,21 +64,6 @@ public final class PainForAll extends CardImpl {
} }
} }
enum PainForAllPredicate implements ObjectSourcePlayerPredicate<Permanent> {
instance;
@Override
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
return Optional
.ofNullable(input)
.map(ObjectSourcePlayer::getSource)
.map(source -> source.getSourcePermanentOrLKI(game))
.map(Permanent::getAttachedTo)
.filter(permanentId -> !permanentId.equals(input.getObject().getId()))
.isPresent();
}
}
class PainForAllFirstEffect extends OneShotEffect { class PainForAllFirstEffect extends OneShotEffect {
PainForAllFirstEffect() { PainForAllFirstEffect() {

View file

@ -32,7 +32,7 @@ public final class PerigeeBeckoner extends CardImpl {
// When this creature enters, until end of turn, another target creature you control gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control." // When this creature enters, until end of turn, another target creature you control gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control."
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0) Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0)
.setText("another target creature you control gets +2/+0")); .setText("until end of turn, another target creature you control gets +2/+0"));
ability.addEffect(new GainAbilityTargetEffect(new DiesSourceTriggeredAbility( ability.addEffect(new GainAbilityTargetEffect(new DiesSourceTriggeredAbility(
new ReturnSourceFromGraveyardToBattlefieldEffect(true, true), false new ReturnSourceFromGraveyardToBattlefieldEffect(true, true), false
), Duration.EndOfTurn, "and gains \"When this creature dies, " + ), Duration.EndOfTurn, "and gains \"When this creature dies, " +

View file

@ -104,7 +104,7 @@ class PinnacleStarcageTokenEffect extends OneShotEffect {
PinnacleStarcageTokenEffect() { PinnacleStarcageTokenEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "put each card exiled with this artifact into its owner's graveyard, " + staticText = "put each card exiled with this artifact into its owner's graveyard, " +
"then create a 2/2 colorless Robot artifact token for each card put into a graveyard this way"; "then create a 2/2 colorless Robot artifact creature token for each card put into a graveyard this way";
} }
private PinnacleStarcageTokenEffect(final PinnacleStarcageTokenEffect effect) { private PinnacleStarcageTokenEffect(final PinnacleStarcageTokenEffect effect) {

View file

@ -0,0 +1,51 @@
package mage.cards.p;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.DauntAbility;
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.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ProwlerMisguidedMentor extends CardImpl {
public ProwlerMisguidedMentor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Prowler can't be blocked by creatures with power 2 or less.
this.addAbility(new DauntAbility());
// Whenever Prowler deals combat damage to a player, put a +1/+1 counter on another target creature you control.
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL));
this.addAbility(ability);
}
private ProwlerMisguidedMentor(final ProwlerMisguidedMentor card) {
super(card);
}
@Override
public ProwlerMisguidedMentor copy() {
return new ProwlerMisguidedMentor(this);
}
}

View file

@ -1,23 +1,18 @@
package mage.cards.p; package mage.cards.p;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.cards.*; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.PutCards;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.common.FilterBySubtypeCard; import mage.filter.common.FilterBySubtypeCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@ -25,6 +20,8 @@ import java.util.UUID;
*/ */
public final class PulsarSquadronAce extends CardImpl { public final class PulsarSquadronAce extends CardImpl {
private static final FilterCard filter = new FilterBySubtypeCard(SubType.SPACECRAFT);
public PulsarSquadronAce(UUID ownerId, CardSetInfo setInfo) { public PulsarSquadronAce(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
@ -34,7 +31,9 @@ public final class PulsarSquadronAce extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// When this creature enters, look at the top five cards of your library. You may reveal a Spacecraft card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, put a +1/+1 counter on this creature. // When this creature enters, look at the top five cards of your library. You may reveal a Spacecraft card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, put a +1/+1 counter on this creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new PulsarSquadronAceEffect())); this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM
).withOtherwiseEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))));
} }
private PulsarSquadronAce(final PulsarSquadronAce card) { private PulsarSquadronAce(final PulsarSquadronAce card) {
@ -46,48 +45,3 @@ public final class PulsarSquadronAce extends CardImpl {
return new PulsarSquadronAce(this); return new PulsarSquadronAce(this);
} }
} }
class PulsarSquadronAceEffect extends OneShotEffect {
private static final FilterCard filter = new FilterBySubtypeCard(SubType.SPACECRAFT);
PulsarSquadronAceEffect() {
super(Outcome.Benefit);
staticText = "look at the top five cards of your library. You may reveal a Spacecraft card from among them " +
"and put it into your hand. Put the rest on the bottom of your library in a random order. " +
"If you didn't put a card into your hand this way, put a +1/+1 counter on {this}";
}
private PulsarSquadronAceEffect(final PulsarSquadronAceEffect effect) {
super(effect);
}
@Override
public PulsarSquadronAceEffect copy() {
return new PulsarSquadronAceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 5));
TargetCard target = new TargetCardInLibrary(0, 1, filter);
player.choose(outcome, cards, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
player.putCardsOnBottomOfLibrary(cards, game, source, false);
Optional.ofNullable(source.getSourcePermanentIfItStillExists(game))
.filter(permanent -> permanent.addCounters(CounterType.P1P1.createInstance(), source, game))
.isPresent();
return true;
}
player.revealCards(source, new CardsImpl(card), game);
player.moveCards(card, Zone.HAND, source, game);
cards.retainZone(Zone.LIBRARY, game);
player.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
}

View file

@ -13,6 +13,7 @@ import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.effects.common.UntapSourceEffect;
import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect; import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.token.FoodAbility; import mage.abilities.token.FoodAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -59,7 +60,7 @@ public final class RagostDeftGastronaut extends CardImpl {
// At the beginning of each end step, if you gained life this turn, untap Ragost. // At the beginning of each end step, if you gained life this turn, untap Ragost.
this.addAbility(new BeginningOfEndStepTriggeredAbility( this.addAbility(new BeginningOfEndStepTriggeredAbility(
TargetController.ANY, new UntapSourceEffect(), false, condition TargetController.ANY, new UntapSourceEffect(), false, condition
)); ).addHint(new ConditionHint(condition)));
} }
private RagostDeftGastronaut(final RagostDeftGastronaut card) { private RagostDeftGastronaut(final RagostDeftGastronaut card) {

View file

@ -7,7 +7,6 @@ import mage.abilities.keyword.ReachAbility;
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.Duration;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
@ -21,12 +20,12 @@ public final class RigForWar extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// Target creature gets +3/+0 and gains first strike and reach until end of turn. // Target creature gets +3/+0 and gains first strike and reach until end of turn.
getSpellAbility().addEffect(new BoostTargetEffect(3, 0, Duration.EndOfTurn) getSpellAbility().addEffect(new BoostTargetEffect(3, 0)
.setText("target creature gets +3/+0")); .setText("target creature gets +3/+0"));
getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn) getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance())
.setText("and gains first strike")); .setText("and gains first strike"));
getSpellAbility().addEffect(new GainAbilityTargetEffect(ReachAbility.getInstance(), Duration.EndOfTurn) getSpellAbility().addEffect(new GainAbilityTargetEffect(ReachAbility.getInstance())
.setText("and first reach until end of turn")); .setText("and reach until end of turn"));
getSpellAbility().addTarget(new TargetCreaturePermanent()); getSpellAbility().addTarget(new TargetCreaturePermanent());
} }

View file

@ -0,0 +1,34 @@
package mage.cards.r;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RiskyResearch extends CardImpl {
public RiskyResearch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Surveil 2, then draw two cards. You lose 2 life.
this.getSpellAbility().addEffect(new SurveilEffect(2, false));
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then"));
this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(2));
}
private RiskyResearch(final RiskyResearch card) {
super(card);
}
@Override
public RiskyResearch copy() {
return new RiskyResearch(this);
}
}

View file

@ -0,0 +1,32 @@
package mage.cards.r;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RomanticRendezvous extends CardImpl {
public RomanticRendezvous(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
// Discard a card, then draw two cards.
this.getSpellAbility().addEffect(new DiscardControllerEffect(1));
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then"));
}
private RomanticRendezvous(final RomanticRendezvous card) {
super(card);
}
@Override
public RomanticRendezvous copy() {
return new RomanticRendezvous(this);
}
}

View file

@ -1,24 +1,18 @@
package mage.cards.r; package mage.cards.r;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.PutCards; import mage.constants.PutCards;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID; import java.util.UUID;
@ -27,6 +21,15 @@ import java.util.UUID;
*/ */
public final class RosecotKnight extends CardImpl { public final class RosecotKnight extends CardImpl {
private static final FilterCard filter = new FilterCard("artifact or enchantment card");
static {
filter.add(Predicates.or(
CardType.ARTIFACT.getPredicate(),
CardType.ENCHANTMENT.getPredicate()
));
}
public RosecotKnight(UUID ownerId, CardSetInfo setInfo) { public RosecotKnight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
@ -39,7 +42,9 @@ public final class RosecotKnight extends CardImpl {
this.addAbility(VigilanceAbility.getInstance()); this.addAbility(VigilanceAbility.getInstance());
// When Rosecot Knight enters the battlefield, look at the top six cards of your library. You may reveal an artifact or enchantment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, put a +1/+1 counter on Rosecot Knight. // When Rosecot Knight enters the battlefield, look at the top six cards of your library. You may reveal an artifact or enchantment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you didn't put a card into your hand this way, put a +1/+1 counter on Rosecot Knight.
this.addAbility(new EntersBattlefieldTriggeredAbility(new RosecotKnightEffect())); this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
6, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM
).withOtherwiseEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))));
} }
private RosecotKnight(final RosecotKnight card) { private RosecotKnight(final RosecotKnight card) {
@ -51,41 +56,3 @@ public final class RosecotKnight extends CardImpl {
return new RosecotKnight(this); return new RosecotKnight(this);
} }
} }
class RosecotKnightEffect extends LookLibraryAndPickControllerEffect {
private static final FilterCard filter = new FilterCard("artifact or enchantment card");
static {
filter.add(Predicates.or(CardType.ARTIFACT.getPredicate(), CardType.ENCHANTMENT.getPredicate()));
}
RosecotKnightEffect() {
super(6, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM);
}
private RosecotKnightEffect(final RosecotKnightEffect effect) {
super(effect);
}
@Override
public RosecotKnightEffect copy() {
return new RosecotKnightEffect(this);
}
@Override
protected boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
game.processAction();
pickedCards.retainZone(Zone.HAND, game);
if (pickedCards.isEmpty()) {
new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source);
}
return true;
}
@Override
public String getText(Mode mode) {
return super.getText(mode).concat(". If you didn't put a card into your hand this way, put a +1/+1 counter on {this}");
}
}

View file

@ -0,0 +1,76 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
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.game.Game;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ScorpionSeethingStriker extends CardImpl {
public ScorpionSeethingStriker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SCORPION);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// 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.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private ScorpionSeethingStriker(final ScorpionSeethingStriker card) {
super(card);
}
@Override
public ScorpionSeethingStriker copy() {
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,32 @@
package mage.cards.s;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ScorpionsSting extends CardImpl {
public ScorpionsSting(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}");
// Target creature gets -3/-3 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(-3, -3));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private ScorpionsSting(final ScorpionsSting card) {
super(card);
}
@Override
public ScorpionsSting copy() {
return new ScorpionsSting(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.s;
import mage.abilities.Mode;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.MillThenPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ScoutTheCity extends CardImpl {
public ScoutTheCity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
// Choose one --
// * Look Around -- Mill three cards. You may put a permanent card from among them into your hand. You gain 3 life.
this.getSpellAbility().addEffect(new MillThenPutInHandEffect(3, StaticFilters.FILTER_CARD_PERMANENT));
this.getSpellAbility().addEffect(new GainLifeEffect(3));
this.getSpellAbility().withFirstModeFlavorWord("Look Around");
// * Bring Down -- Destroy target creature with flying.
this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect())
.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_FLYING))
.withFlavorWord("Bring Down"));
}
private ScoutTheCity(final ScoutTheCity card) {
super(card);
}
@Override
public ScoutTheCity copy() {
return new ScoutTheCity(this);
}
}

View file

@ -32,7 +32,7 @@ public final class SelfcraftMechan extends CardImpl {
// When this creature enters, you may sacrifice an artifact. When you do, put a +1/+1 counter on target creature and draw a card. // When this creature enters, you may sacrifice an artifact. When you do, put a +1/+1 counter on target creature and draw a card.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false); ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false);
ability.addEffect(new DrawCardSourceControllerEffect(1)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN), ability, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN),

View file

@ -0,0 +1,51 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.PutSourceCountersOnTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SelflessPoliceCaptain extends CardImpl {
public SelflessPoliceCaptain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DETECTIVE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// This creature enters with a +1/+1 counter on it.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
"with a +1/+1 counter on it"
));
// When this creature leaves the battlefield, put its +1/+1 counters on target creature you control.
Ability ability = new DiesSourceTriggeredAbility(new PutSourceCountersOnTargetEffect(CounterType.P1P1));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private SelflessPoliceCaptain(final SelflessPoliceCaptain card) {
super(card);
}
@Override
public SelflessPoliceCaptain copy() {
return new SelflessPoliceCaptain(this);
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ShockerUnshakable extends CardImpl {
public ShockerUnshakable(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// During your turn, Shocker has first strike.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield),
MyTurnCondition.instance, "During your turn, {this} has first strike."
)));
// Vibro-Shock Gauntlets -- When Shocker enters, he deals 2 damage to target creature and 2 damage to that creature's controller.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "he"));
ability.addEffect(new DamageTargetControllerEffect(2).setText("and 2 damage to that creature's controller"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability.withFlavorWord("Vibro-Shock Gauntlets"));
}
private ShockerUnshakable(final ShockerUnshakable card) {
super(card);
}
@Override
public ShockerUnshakable copy() {
return new ShockerUnshakable(this);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.s;
import mage.abilities.Mode;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpectacularTactics extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature with power 4 or greater");
static {
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
}
public SpectacularTactics(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Choose one --
// * Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HexproofAbility.getInstance()).setText("It gains hexproof until end of turn"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
// * Destroy target creature with power 4 or greater.
this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect()).addTarget(new TargetPermanent(filter)));
}
private SpectacularTactics(final SpectacularTactics card) {
super(card);
}
@Override
public SpectacularTactics copy() {
return new SpectacularTactics(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderBot extends CardImpl {
public SpiderBot(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.ROBOT);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Reach
this.addAbility(ReachAbility.getInstance());
// When this creature enters, you may search your library for a basic land card, reveal it, then shuffle and put that card on top.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutOnLibraryEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
), true));
}
private SpiderBot(final SpiderBot card) {
super(card);
}
@Override
public SpiderBot copy() {
return new SpiderBot(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderByteWebWarden extends CardImpl {
public SpiderByteWebWarden(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.HERO);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Spider-Byte enters, return up to one target nonland permanent to its owner's hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect());
ability.addTarget(new TargetNonlandPermanent(0, 1));
this.addAbility(ability);
}
private SpiderByteWebWarden(final SpiderByteWebWarden card) {
super(card);
}
@Override
public SpiderByteWebWarden copy() {
return new SpiderByteWebWarden(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.BecomesTappedSourceTriggeredAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderGwenFreeSpirit extends CardImpl {
public SpiderGwenFreeSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Reach
this.addAbility(ReachAbility.getInstance());
// Whenever Spider-Gwen becomes tapped, you may discard a card. If you do, draw a card.
this.addAbility(new BecomesTappedSourceTriggeredAbility(
new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost())
));
}
private SpiderGwenFreeSpirit(final SpiderGwenFreeSpirit card) {
super(card);
}
@Override
public SpiderGwenFreeSpirit copy() {
return new SpiderGwenFreeSpirit(this);
}
}

View file

@ -0,0 +1,81 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.game.permanent.token.FoodToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderHamPeterPorker extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(
"Spiders, Boars, Bats, Bears, Birds, Cats, Dogs, Frogs, Jackals, Lizards, " +
"Mice, Otters, Rabbits, Raccoons, Rats, Squirrels, Turtles, and Wolves"
);
static {
filter.add(Predicates.or(
SubType.SPIDER.getPredicate(),
SubType.BOAR.getPredicate(),
SubType.BAT.getPredicate(),
SubType.BEAR.getPredicate(),
SubType.BIRD.getPredicate(),
SubType.CAT.getPredicate(),
SubType.DOG.getPredicate(),
SubType.FROG.getPredicate(),
SubType.JACKAL.getPredicate(),
SubType.LIZARD.getPredicate(),
SubType.MOUSE.getPredicate(),
SubType.OTTER.getPredicate(),
SubType.RABBIT.getPredicate(),
SubType.RACCOON.getPredicate(),
SubType.RAT.getPredicate(),
SubType.SQUIRREL.getPredicate(),
SubType.TURTLE.getPredicate(),
SubType.WOLF.getPredicate()
));
}
public SpiderHamPeterPorker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.BOAR);
this.subtype.add(SubType.HERO);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Spider-Ham enters, create a Food token.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
// Animal May-Ham -- Other Spiders, Boars, Bats, Bears, Birds, Cats, Dogs, Frogs, Jackals, Lizards, Mice, Otters, Rabbits, Raccoons, Rats, Squirrels, Turtles, and Wolves you control get +1/+1.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
1, 1, Duration.WhileOnBattlefield, filter, true
)).withFlavorWord("Animal May-Ham"));
}
private SpiderHamPeterPorker(final SpiderHamPeterPorker card) {
super(card);
}
@Override
public SpiderHamPeterPorker copy() {
return new SpiderHamPeterPorker(this);
}
}
// it CAN get weirder!

View file

@ -0,0 +1,49 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.keyword.WebSlingingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderManBrooklynVisionary extends CardImpl {
public SpiderManBrooklynVisionary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Web-slinging {2}{G}
this.addAbility(new WebSlingingAbility(this, "{2}{G}"));
// When Spider-Man enters, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
)));
}
private SpiderManBrooklynVisionary(final SpiderManBrooklynVisionary card) {
super(card);
}
@Override
public SpiderManBrooklynVisionary copy() {
return new SpiderManBrooklynVisionary(this);
}
}

View file

@ -0,0 +1,61 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderManMilesMorales extends CardImpl {
public SpiderManMilesMorales(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Spider-Man enters or attacks, put a +1/+1 counter on each other creature you control. Those creatures gain trample until end of turn.
Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE
));
ability.addEffect(new GainAbilityAllEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE
).setText("Those creatures gain trample until end of turn"));
this.addAbility(ability);
}
private SpiderManMilesMorales(final SpiderManMilesMorales card) {
super(card);
}
@Override
public SpiderManMilesMorales copy() {
return new SpiderManMilesMorales(this);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.IndestructibleAbility;
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.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderManPeterParker extends CardImpl {
public SpiderManPeterParker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you gain life, put a +1/+1 counter on target creature you control. It gains indestructible until end of turn.
Ability ability = new GainLifeControllerTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addEffect(new GainAbilityTargetEffect(IndestructibleAbility.getInstance()).setText("It gains indestructible until end of turn"));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private SpiderManPeterParker(final SpiderManPeterParker card) {
super(card);
}
@Override
public SpiderManPeterParker copy() {
return new SpiderManPeterParker(this);
}
}

View file

@ -0,0 +1,40 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.keyword.WebSlingingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderManWebSlinger extends CardImpl {
public SpiderManWebSlinger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
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);
// Web-slinging {W}
this.addAbility(new WebSlingingAbility(this, "{W}"));
}
private SpiderManWebSlinger(final SpiderManWebSlinger card) {
super(card);
}
@Override
public SpiderManWebSlinger copy() {
return new SpiderManWebSlinger(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.WardAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SpiderRexDaringDino extends CardImpl {
public SpiderRexDaringDino(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.DINOSAUR);
this.subtype.add(SubType.HERO);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Reach
this.addAbility(ReachAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Ward {2}
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}")));
}
private SpiderRexDaringDino(final SpiderRexDaringDino card) {
super(card);
}
@Override
public SpiderRexDaringDino copy() {
return new SpiderRexDaringDino(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class StarlingAerialAlly extends CardImpl {
public StarlingAerialAlly(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HERO);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Starling enters, another target creature you control gains flying until end of turn.
Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance()));
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL));
this.addAbility(ability);
}
private StarlingAerialAlly(final StarlingAerialAlly card) {
super(card);
}
@Override
public StarlingAerialAlly copy() {
return new StarlingAerialAlly(this);
}
}

View file

@ -17,7 +17,9 @@ import mage.constants.*;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherPredicate; import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -121,6 +123,11 @@ class SummonGoodKingMogXIIEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterControlledPermanent("non-Saga token you control"); private static final FilterPermanent filter = new FilterControlledPermanent("non-Saga token you control");
static {
filter.add(Predicates.not(SubType.SAGA.getPredicate()));
filter.add(TokenPredicate.TRUE);
}
SummonGoodKingMogXIIEffect() { SummonGoodKingMogXIIEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "create a token that's a copy of a non-Saga token you control"; staticText = "create a token that's a copy of a non-Saga token you control";

View file

@ -0,0 +1,42 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SymbioteSpawn extends CardImpl {
public SymbioteSpawn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.SYMBIOTE);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// When this creature dies, each opponent loses 2 life and you gain 2 life.
Ability ability = new DiesSourceTriggeredAbility(new LoseLifeOpponentsEffect(2));
ability.addEffect(new GainLifeEffect(2).concatBy("and"));
this.addAbility(ability);
}
private SymbioteSpawn(final SymbioteSpawn card) {
super(card);
}
@Override
public SymbioteSpawn copy() {
return new SymbioteSpawn(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TaxiDriver extends CardImpl {
public TaxiDriver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.PILOT);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// {1}, {T}: Target creature gains haste until end of turn.
Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect(HasteAbility.getInstance()), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private TaxiDriver(final TaxiDriver card) {
super(card);
}
@Override
public TaxiDriver copy() {
return new TaxiDriver(this);
}
}

View file

@ -0,0 +1,79 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Thwip extends CardImpl {
public Thwip(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// Target creature gets +2/+2 and gains flying until end of turn. If it's a Spider, you gain 2 life.
this.getSpellAbility().addEffect(new BoostTargetEffect(
2, 2, Duration.EndOfTurn
).setText("Target creature gets +2/+2"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
FlyingAbility.getInstance(), Duration.EndOfTurn
).setText("and gains flying until end of turn"));
this.getSpellAbility().addEffect(new ThwipEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private Thwip(final Thwip card) {
super(card);
}
@Override
public Thwip copy() {
return new Thwip(this);
}
}
class ThwipEffect extends OneShotEffect {
ThwipEffect() {
super(Outcome.Benefit);
staticText = "If it's a Spider, you gain 2 life";
}
private ThwipEffect(final ThwipEffect effect) {
super(effect);
}
@Override
public ThwipEffect copy() {
return new ThwipEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
return permanent != null
&& permanent.hasSubtype(SubType.SPIDER, game)
&& Optional
.ofNullable(source)
.map(Controllable::getControllerId)
.map(game::getPlayer)
.filter(player -> player.gainLife(2, game, source) > 0)
.isPresent();
}
}

View file

@ -0,0 +1,54 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.common.FilterBySubtypeCard;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TombstoneCareerCriminal extends CardImpl {
private static final FilterCard filter = new FilterBySubtypeCard(SubType.VILLAIN);
private static final FilterCard filter2 = new FilterBySubtypeCard(SubType.VILLAIN, "Villain spells");
public TombstoneCareerCriminal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Tombstone enters, return target Villain card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
// Villain spells you cast cost {1} less to cast.
this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter2, 1)));
}
private TombstoneCareerCriminal(final TombstoneCareerCriminal card) {
super(card);
}
@Override
public TombstoneCareerCriminal copy() {
return new TombstoneCareerCriminal(this);
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TwistedSpiderClone extends CardImpl {
public TwistedSpiderClone(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.HUMAN);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When this creature enters, put a +1/+1 counter on each creature you control with a +1/+1 counter on it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE_P1P1
)));
}
private TwistedSpiderClone(final TwistedSpiderClone card) {
super(card);
}
@Override
public TwistedSpiderClone copy() {
return new TwistedSpiderClone(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.v;
import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class VenomBlast extends CardImpl {
public VenomBlast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}");
// Put two +1/+1 counters on target creature you control. It deals damage equal to its power to up to one other target creature.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)));
this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect()
.setText("It deals damage equal to its power to up to one other target creature"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addTarget(new TargetPermanent(
0, 1, StaticFilters.FILTER_ANOTHER_CREATURE_TARGET_2
).setTargetTag(2));
}
private VenomBlast(final VenomBlast card) {
super(card);
}
@Override
public VenomBlast copy() {
return new VenomBlast(this);
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.v;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class VenomsHunger extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
new FilterControlledPermanent(SubType.VILLAIN, "you control a Villain")
);
public VenomsHunger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// This spell costs {2} less to cast if you control a Villain.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true)
).setRuleAtTheTop(true));
// Destroy target creature. You gain 2 life.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addEffect(new GainLifeEffect(2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private VenomsHunger(final VenomsHunger card) {
super(card);
}
@Override
public VenomsHunger copy() {
return new VenomsHunger(this);
}
}

View file

@ -1,12 +1,8 @@
package mage.cards.w; package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.effects.common.continuous.SwitchPowerToughnessSourceEffect; import mage.abilities.effects.common.continuous.SwitchPowerToughnessSourceEffect;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
@ -14,32 +10,35 @@ import mage.abilities.mana.RedManaAbility;
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.SubType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.SubType;
import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.custom.CreatureToken;
import java.util.UUID;
/** /**
*
* @author fireshoes * @author fireshoes
*/ */
public final class WanderingFumarole extends CardImpl { public final class WanderingFumarole extends CardImpl {
public WanderingFumarole(UUID ownerId, CardSetInfo setInfo) { public WanderingFumarole(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},""); super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// Wandering Fumarole enters the battlefield tapped. // Wandering Fumarole enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility()); this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {U} or {R}. // {T}: Add {U} or {R}.
this.addAbility(new BlueManaAbility()); this.addAbility(new BlueManaAbility());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
// {2}{U}{R}: Until end of turn, Wandering Fumarole becomes a 1/4 blue and red Elemental creature with // {2}{U}{R}: Until end of turn, Wandering Fumarole becomes a 1/4 blue and red Elemental creature with
// "0: Switch this creature's power and toughness until end of turn." It's still a land. // "0: Switch this creature's power and toughness until end of turn." It's still a land.
Effect effect = new BecomesCreatureSourceEffect(new WanderingFumaroleToken(), CardType.LAND, Duration.EndOfTurn); this.addAbility(new SimpleActivatedAbility(new BecomesCreatureSourceEffect(new CreatureToken(
effect.setText("{this} becomes a 1/4 blue and red Elemental creature with \"0: Switch this creature's power and toughness until end of turn.\" It's still a land"); 1, 4, "1/4 blue and red Elemental creature " +
this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{2}{U}{R}"))); "with \"{0}: Switch this creature's power and toughness until end of turn.\"", SubType.ELEMENTAL
).withColor("UR").withAbility(new SimpleActivatedAbility(
new SwitchPowerToughnessSourceEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{0}")
)), CardType.LAND, Duration.EndOfTurn).withDurationRuleAtStart(true), new ManaCostsImpl<>("{2}{U}{R}")));
} }
private WanderingFumarole(final WanderingFumarole card) { private WanderingFumarole(final WanderingFumarole card) {
@ -51,24 +50,3 @@ public final class WanderingFumarole extends CardImpl {
return new WanderingFumarole(this); return new WanderingFumarole(this);
} }
} }
class WanderingFumaroleToken extends TokenImpl {
public WanderingFumaroleToken() {
super("", "1/4 blue and red Elemental creature with \"0: Switch this creature's power and toughness until end of turn.\"");
cardType.add(CardType.CREATURE);
subtype.add(SubType.ELEMENTAL);
color.setRed(true);
color.setBlue(true);
power = new MageInt(1);
toughness = new MageInt(4);
addAbility(new SimpleActivatedAbility(new SwitchPowerToughnessSourceEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{0}")));
}
private WanderingFumaroleToken(final WanderingFumaroleToken token) {
super(token);
}
public WanderingFumaroleToken copy() {
return new WanderingFumaroleToken(this);
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.w;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WebUp extends CardImpl {
public WebUp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// When this enchantment enters, exile target nonland permanent an opponent controls until this enchantment leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND));
this.addAbility(ability);
}
private WebUp(final WebUp card) {
super(card);
}
@Override
public WebUp copy() {
return new WebUp(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.w;
import mage.abilities.condition.common.KickedCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.keyword.KickerAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Whoosh extends CardImpl {
public Whoosh(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Kicker {1}{U}
this.addAbility(new KickerAbility("{1}{U}"));
// Return target nonland permanent to its owner's hand. If this spell was kicked, draw a card.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1),
KickedCondition.ONCE, "if this spell was kicked, draw a card"
));
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
}
private Whoosh(final Whoosh card) {
super(card);
}
@Override
public Whoosh copy() {
return new Whoosh(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WildPackSquad extends CardImpl {
public WildPackSquad(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MERCENARY);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// At the beginning of combat on your turn, up to one target creature gains first strike and vigilance until end of turn.
Ability ability = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance())
.setText("up to one target creature gains first strike"));
ability.addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance())
.setText("and vigilance until end of turn"));
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
}
private WildPackSquad(final WildPackSquad card) {
super(card);
}
@Override
public WildPackSquad copy() {
return new WildPackSquad(this);
}
}

View file

@ -216,6 +216,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Meathook Massacre II", 311, Rarity.MYTHIC, mage.cards.m.MeathookMassacreII.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Meathook Massacre II", 311, Rarity.MYTHIC, mage.cards.m.MeathookMassacreII.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Miasma Demon", 109, Rarity.UNCOMMON, mage.cards.m.MiasmaDemon.class)); cards.add(new SetCardInfo("Miasma Demon", 109, Rarity.UNCOMMON, mage.cards.m.MiasmaDemon.class));
cards.add(new SetCardInfo("Midnight Mayhem", 222, Rarity.UNCOMMON, mage.cards.m.MidnightMayhem.class)); cards.add(new SetCardInfo("Midnight Mayhem", 222, Rarity.UNCOMMON, mage.cards.m.MidnightMayhem.class));
cards.add(new SetCardInfo("Monstrous Emergence", 191, Rarity.COMMON, mage.cards.m.MonstrousEmergence.class));
cards.add(new SetCardInfo("Most Valuable Slayer", 144, Rarity.COMMON, mage.cards.m.MostValuableSlayer.class)); cards.add(new SetCardInfo("Most Valuable Slayer", 144, Rarity.COMMON, mage.cards.m.MostValuableSlayer.class));
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Mountain", 283, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 283, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));

View file

@ -0,0 +1,68 @@
package mage.sets;
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.constants.SetType;
/**
* @author TheElk801
*/
public final class MarvelsSpiderMan extends ExpansionSet {
private static final MarvelsSpiderMan instance = new MarvelsSpiderMan();
public static MarvelsSpiderMan getInstance() {
return instance;
}
private MarvelsSpiderMan() {
super("Marvel's Spider-Man", "SPM", ExpansionSet.buildDate(2025, 9, 26), SetType.EXPANSION);
this.blockName = "Marvel's Spider-Man"; // for sorting in GUI
this.hasBasicLands = true;
cards.add(new SetCardInfo("Angry Rabble", 75, Rarity.COMMON, mage.cards.a.AngryRabble.class));
cards.add(new SetCardInfo("Aunt May", 3, Rarity.UNCOMMON, mage.cards.a.AuntMay.class));
cards.add(new SetCardInfo("Beetle, Legacy Criminal", 26, Rarity.COMMON, mage.cards.b.BeetleLegacyCriminal.class));
cards.add(new SetCardInfo("Daily Bugle Reporters", 6, Rarity.COMMON, mage.cards.d.DailyBugleReporters.class));
cards.add(new SetCardInfo("Doc Ock's Henchmen", 30, Rarity.COMMON, mage.cards.d.DocOcksHenchmen.class));
cards.add(new SetCardInfo("Eerie Gravestone", 163, Rarity.COMMON, mage.cards.e.EerieGravestone.class));
cards.add(new SetCardInfo("Flying Octobot", 31, Rarity.UNCOMMON, mage.cards.f.FlyingOctobot.class));
cards.add(new SetCardInfo("Forest", 198, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Guy in the Chair", 102, Rarity.COMMON, mage.cards.g.GuyInTheChair.class));
cards.add(new SetCardInfo("Island", 195, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kapow!", 103, Rarity.COMMON, mage.cards.k.Kapow.class));
cards.add(new SetCardInfo("Kraven's Cats", 104, Rarity.COMMON, mage.cards.k.KravensCats.class));
cards.add(new SetCardInfo("Lurking Lizards", 107, Rarity.COMMON, mage.cards.l.LurkingLizards.class));
cards.add(new SetCardInfo("Masked Meower", 82, Rarity.COMMON, mage.cards.m.MaskedMeower.class));
cards.add(new SetCardInfo("Merciless Enforcers", 58, Rarity.COMMON, mage.cards.m.MercilessEnforcers.class));
cards.add(new SetCardInfo("Mountain", 197, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Origin of Spider-Man", 9, Rarity.RARE, mage.cards.o.OriginOfSpiderMan.class));
cards.add(new SetCardInfo("Oscorp Research Team", 40, Rarity.COMMON, mage.cards.o.OscorpResearchTeam.class));
cards.add(new SetCardInfo("Plains", 194, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Risky Research", 62, Rarity.COMMON, mage.cards.r.RiskyResearch.class));
cards.add(new SetCardInfo("Romantic Rendezvous", 86, Rarity.COMMON, mage.cards.r.RomanticRendezvous.class));
cards.add(new SetCardInfo("Scorpion's Sting", 65, Rarity.COMMON, mage.cards.s.ScorpionsSting.class));
cards.add(new SetCardInfo("Scorpion, Seething Striker", 64, Rarity.UNCOMMON, mage.cards.s.ScorpionSeethingStriker.class));
cards.add(new SetCardInfo("Scout the City", 113, Rarity.COMMON, mage.cards.s.ScoutTheCity.class));
cards.add(new SetCardInfo("Selfless Police Captain", 12, Rarity.COMMON, mage.cards.s.SelflessPoliceCaptain.class));
cards.add(new SetCardInfo("Shock", 88, Rarity.COMMON, mage.cards.s.Shock.class));
cards.add(new SetCardInfo("Shocker, Unshakable", 89, Rarity.UNCOMMON, mage.cards.s.ShockerUnshakable.class));
cards.add(new SetCardInfo("Spectacular Tactics", 15, Rarity.COMMON, mage.cards.s.SpectacularTactics.class));
cards.add(new SetCardInfo("Spider-Bot", 173, Rarity.COMMON, mage.cards.s.SpiderBot.class));
cards.add(new SetCardInfo("Spider-Byte, Web Warden", 44, Rarity.UNCOMMON, mage.cards.s.SpiderByteWebWarden.class));
cards.add(new SetCardInfo("Spider-Gwen, Free Spirit", 90, Rarity.COMMON, mage.cards.s.SpiderGwenFreeSpirit.class));
cards.add(new SetCardInfo("Spider-Ham, Peter Porker", 114, Rarity.RARE, mage.cards.s.SpiderHamPeterPorker.class));
cards.add(new SetCardInfo("Spider-Man, Brooklyn Visionary", 115, Rarity.COMMON, mage.cards.s.SpiderManBrooklynVisionary.class));
cards.add(new SetCardInfo("Spider-Man, Web-Slinger", 16, Rarity.COMMON, mage.cards.s.SpiderManWebSlinger.class));
cards.add(new SetCardInfo("Spider-Rex, Daring Dino", 116, Rarity.COMMON, mage.cards.s.SpiderRexDaringDino.class));
cards.add(new SetCardInfo("Starling, Aerial Ally", 18, Rarity.COMMON, mage.cards.s.StarlingAerialAlly.class));
cards.add(new SetCardInfo("Swamp", 196, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
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("Tombstone, Career Criminal", 70, Rarity.UNCOMMON, mage.cards.t.TombstoneCareerCriminal.class));
cards.add(new SetCardInfo("Venom's Hunger", 73, Rarity.COMMON, mage.cards.v.VenomsHunger.class));
cards.add(new SetCardInfo("Web Up", 21, Rarity.COMMON, mage.cards.w.WebUp.class));
cards.add(new SetCardInfo("Whoosh!", 48, Rarity.COMMON, mage.cards.w.Whoosh.class));
cards.add(new SetCardInfo("Wild Pack Squad", 23, Rarity.COMMON, mage.cards.w.WildPackSquad.class));
}
}

View file

@ -20,11 +20,23 @@ public final class MarvelsSpiderManEternal extends ExpansionSet {
this.blockName = "Marvel's Spider-Man"; // for sorting in GUI this.blockName = "Marvel's Spider-Man"; // for sorting in GUI
this.hasBasicLands = false; // temporary this.hasBasicLands = false; // temporary
cards.add(new SetCardInfo("Alchemax Slayer-Bots", 5, Rarity.COMMON, mage.cards.a.AlchemaxSlayerBots.class));
cards.add(new SetCardInfo("Amateur Hero", 1, Rarity.COMMON, mage.cards.a.AmateurHero.class));
cards.add(new SetCardInfo("Doc Ock, Evil Inventor", 24, Rarity.RARE, mage.cards.d.DocOckEvilInventor.class)); cards.add(new SetCardInfo("Doc Ock, Evil Inventor", 24, Rarity.RARE, mage.cards.d.DocOckEvilInventor.class));
cards.add(new SetCardInfo("Future Flight", 6, Rarity.RARE, mage.cards.f.FutureFlight.class));
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("Grendel, Spawn of Knull", 9, Rarity.UNCOMMON, mage.cards.g.GrendelSpawnOfKnull.class));
cards.add(new SetCardInfo("Lyla, Holographic Assistant", 7, Rarity.UNCOMMON, mage.cards.l.LylaHolographicAssistant.class));
cards.add(new SetCardInfo("MJ, Rising Star", 3, Rarity.UNCOMMON, mage.cards.m.MJRisingStar.class));
cards.add(new SetCardInfo("Prowler, Misguided Mentor", 17, Rarity.UNCOMMON, mage.cards.p.ProwlerMisguidedMentor.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("Sensational Spider-Man", 25, Rarity.RARE, mage.cards.s.SensationalSpiderMan.class));
cards.add(new SetCardInfo("Spider-Man, Miles Morales", 18, Rarity.MYTHIC, mage.cards.s.SpiderManMilesMorales.class));
cards.add(new SetCardInfo("Spider-Man, Peter Parker", 4, Rarity.MYTHIC, mage.cards.s.SpiderManPeterParker.class));
cards.add(new SetCardInfo("Symbiote Spawn", 11, Rarity.COMMON, mage.cards.s.SymbioteSpawn.class));
cards.add(new SetCardInfo("Twisted Spider-Clone", 19, Rarity.COMMON, mage.cards.t.TwistedSpiderClone.class));
cards.add(new SetCardInfo("Venom Blast", 20, Rarity.RARE, mage.cards.v.VenomBlast.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

@ -161,7 +161,6 @@ public class VerifyCardDataTest {
// color // color
// skipListAddName(SKIP_LIST_COLOR, set, cardName); // skipListAddName(SKIP_LIST_COLOR, set, cardName);
skipListAddName(SKIP_LIST_COLOR, "FIN", "Summon: Alexander");
// cost // cost
// skipListAddName(SKIP_LIST_COST, set, cardName); // skipListAddName(SKIP_LIST_COST, set, cardName);
@ -1818,7 +1817,7 @@ public class VerifyCardDataTest {
private void check(Card card, int cardIndex) { private void check(Card card, int cardIndex) {
MtgJsonCard ref = MtgJsonService.cardFromSet(card.getExpansionSetCode(), card.getName(), card.getCardNumber()); MtgJsonCard ref = MtgJsonService.cardFromSet(card.getExpansionSetCode(), card.getName(), card.getCardNumber());
if (ref != null) { if (ref != null) {
if (card instanceof SpellOptionCard && ref.layout.equals("reversible_card")) { if ((card instanceof CardWithSpellOption || card instanceof SpellOptionCard) && ref.layout.equals("reversible_card")) {
// TODO: Remove when MtgJson updated // TODO: Remove when MtgJson updated
// workaround for reversible omen cards e.g. Bloomvine Regent // Claim Territory // Bloomvine Regent // workaround for reversible omen cards e.g. Bloomvine Regent // Claim Territory // Bloomvine Regent
// both sides have main card info // both sides have main card info
@ -2337,11 +2336,7 @@ public class VerifyCardDataTest {
String additionalName; String additionalName;
if (card instanceof CardWithSpellOption) { if (card instanceof CardWithSpellOption) {
// adventure/omen cards // adventure/omen cards
if (card.getName().equals("Bloomvine Regent") || card.getName().equals("Marang River Regent") || card.getName().equals("Scavenger Regent")) { additionalName = ((CardWithSpellOption) card).getSpellCard().getName();
additionalName = null;
} else {
additionalName = ((CardWithSpellOption) card).getSpellCard().getName();
}
} else if (card.isTransformable() && !card.isNightCard()) { } else if (card.isTransformable() && !card.isNightCard()) {
additionalName = card.getSecondCardFace().getName(); additionalName = card.getSecondCardFace().getName();
} else { } else {

View file

@ -10,6 +10,7 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/** /**
* @author North, Susucr * @author North, Susucr
@ -103,7 +104,7 @@ public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
} }
private void makeTriggerPhrase() { private void makeTriggerPhrase() {
String text = getWhen() + "you cast " + filter.getMessage(); String text = getWhen() + "you cast " + CardUtil.addArticle(filter.getMessage());
switch (fromZone) { switch (fromZone) {
case ALL: case ALL:

View file

@ -4,6 +4,9 @@ import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.PutCards; import mage.constants.PutCards;
@ -26,6 +29,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
protected boolean revealPickedCards; protected boolean revealPickedCards;
protected boolean optional; protected boolean optional;
protected boolean upTo; protected boolean upTo;
protected Effect otherwiseEffect = null;
public LookLibraryAndPickControllerEffect(int numberOfCards, int numberToPick, public LookLibraryAndPickControllerEffect(int numberOfCards, int numberToPick,
PutCards putPickedCards, PutCards putLookedCards) { PutCards putPickedCards, PutCards putLookedCards) {
@ -87,6 +91,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
this.revealPickedCards = effect.revealPickedCards; this.revealPickedCards = effect.revealPickedCards;
this.optional = effect.optional; this.optional = effect.optional;
this.upTo = effect.upTo; this.upTo = effect.upTo;
this.otherwiseEffect = effect.otherwiseEffect != null ? effect.otherwiseEffect.copy() : null;
} }
@Override @Override
@ -94,6 +99,11 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
return new LookLibraryAndPickControllerEffect(this); return new LookLibraryAndPickControllerEffect(this);
} }
public LookLibraryAndPickControllerEffect withOtherwiseEffect(Effect otherwiseEffect) {
this.otherwiseEffect = otherwiseEffect;
return this;
}
@Override @Override
protected boolean actionWithLookedCards(Game game, Ability source, Player player, Cards cards) { protected boolean actionWithLookedCards(Game game, Ability source, Player player, Cards cards) {
int number = Math.min(numberToPick, cards.count(filter, source.getControllerId(), source, game)); int number = Math.min(numberToPick, cards.count(filter, source.getControllerId(), source, game));
@ -120,6 +130,15 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
protected boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) { protected boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
boolean result = putPickedCards.moveCards(player, pickedCards, source, game); boolean result = putPickedCards.moveCards(player, pickedCards, source, game);
result |= putLookedCards.moveCards(player, otherCards, source, game); result |= putLookedCards.moveCards(player, otherCards, source, game);
if (!pickedCards.isEmpty() || otherwiseEffect == null) {
return result;
}
game.processAction();
if (otherwiseEffect instanceof OneShotEffect) {
otherwiseEffect.apply(game, source);
} else if (otherwiseEffect instanceof ContinuousEffect) {
game.addEffect((ContinuousEffect) otherwiseEffect, source);
}
return result; return result;
} }
@ -196,6 +215,12 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
sb.append("back "); sb.append("back ");
} }
sb.append(putLookedCards.getMessage(false, plural)); sb.append(putLookedCards.getMessage(false, plural));
if (otherwiseEffect != null) {
sb.append(". If you didn't put a card ");
sb.append(putPickedCards.getMessage(false, false));
sb.append(" this way, ");
sb.append(otherwiseEffect.getText(mode));
}
// get text frame from super class and inject action text // get text frame from super class and inject action text
return setText(mode, sb.toString()); return setText(mode, sb.toString());

View file

@ -4,6 +4,7 @@ import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -12,12 +13,20 @@ import mage.game.permanent.Permanent;
*/ */
public class PutSourceCountersOnTargetEffect extends OneShotEffect { public class PutSourceCountersOnTargetEffect extends OneShotEffect {
private final CounterType counterType;
public PutSourceCountersOnTargetEffect() { public PutSourceCountersOnTargetEffect() {
this((CounterType) null);
}
public PutSourceCountersOnTargetEffect(CounterType counterType) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.counterType = counterType;
} }
private PutSourceCountersOnTargetEffect(final PutSourceCountersOnTargetEffect effect) { private PutSourceCountersOnTargetEffect(final PutSourceCountersOnTargetEffect effect) {
super(effect); super(effect);
this.counterType = effect.counterType;
} }
@Override @Override
@ -32,6 +41,10 @@ public class PutSourceCountersOnTargetEffect extends OneShotEffect {
if (sourcePermanent == null || permanent == null) { if (sourcePermanent == null || permanent == null) {
return false; return false;
} }
if (counterType != null) {
int count = sourcePermanent.getCounters(game).getCount(counterType);
return count > 0 && permanent.addCounters(counterType.createInstance(count), source, game);
}
sourcePermanent sourcePermanent
.getCounters(game) .getCounters(game)
.values() .values()
@ -45,6 +58,7 @@ public class PutSourceCountersOnTargetEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) { if (staticText != null && !staticText.isEmpty()) {
return staticText; return staticText;
} }
return "put its counters on " + getTargetPointer().describeTargets(mode.getTargets(), "that creature"); return "put its" + (counterType != null ? " " + counterType : "") + " counters on " +
getTargetPointer().describeTargets(mode.getTargets(), "that creature");
} }
} }

View file

@ -85,13 +85,9 @@ public class ConniveSourceEffect extends OneShotEffect {
* @return * @return
*/ */
public static boolean connive(Permanent permanent, int amount, Ability source, Game game) { public static boolean connive(Permanent permanent, int amount, Ability source, Game game) {
if (amount < 1) { if (permanent == null || amount < 1) {
return false; return false;
} }
if (permanent == null) {
return false;
}
boolean permanentStillOnBattlefield = game.getState().getZone(permanent.getId()) == Zone.BATTLEFIELD; boolean permanentStillOnBattlefield = game.getState().getZone(permanent.getId()) == Zone.BATTLEFIELD;
Player player = game.getPlayer(permanent.getControllerId()); Player player = game.getPlayer(permanent.getControllerId());
if (player == null) { if (player == null) {

View file

@ -127,7 +127,7 @@ class StationLevelCreatureEffect extends ContinuousEffectImpl {
} }
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
permanent.addCardType(game, CardType.ARTIFACT, CardType.CREATURE); permanent.addCardType(game, CardType.CREATURE);
return true; return true;
case PTChangingEffects_7: case PTChangingEffects_7:
if (sublayer != SubLayer.SetPT_7b) { if (sublayer != SubLayer.SetPT_7b) {

View file

@ -1,6 +1,7 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import mage.MageIdentifier; import mage.MageIdentifier;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@ -10,14 +11,33 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
* 702.185. Warp
* <p>
* 702.185a Warp represents two static abilities that function while the card with warp is on the stack,
* one of which may create a delayed triggered ability. Warp [cost] means
* You may cast this card from your hand by paying [cost] rather than its mana cost and
* If this spells warp cost was paid, exile the permanent this spell becomes at the beginning of the next end step.
* Its owner may cast this card after the current turn has ended for as long as it remains exiled.
* Casting a spell for its warp cost follows the rules for paying alternative costs in rules 601.2b and 601.2fh.
* <p>
* 702.185b Some effects refer to warped cards in exile. A warped card in exile is one
* that was exiled by the delayed triggered ability created by a warp ability.
* <p>
* 702.185c Some effects refer to whether a spell was warped this turn.
* This means that a spell was cast for its warp cost this turn.
*
* @author TheElk801 * @author TheElk801
*/ */
public class WarpAbility extends SpellAbility { public class WarpAbility extends SpellAbility {
@ -41,6 +61,7 @@ public class WarpAbility extends SpellAbility {
this.addCost(new ManaCostsImpl<>(manaString)); this.addCost(new ManaCostsImpl<>(manaString));
this.setAdditionalCostsRuleVisible(false); this.setAdditionalCostsRuleVisible(false);
this.allowGraveyard = allowGraveyard; this.allowGraveyard = allowGraveyard;
this.addWatcher(new WarpAbilityWatcher());
} }
private WarpAbility(final WarpAbility ability) { private WarpAbility(final WarpAbility ability) {
@ -48,15 +69,6 @@ public class WarpAbility extends SpellAbility {
this.allowGraveyard = ability.allowGraveyard; this.allowGraveyard = ability.allowGraveyard;
} }
// The ability sets up a delayed trigger which can't be set up using the cost tag system
public static void addDelayedTrigger(SpellAbility spellAbility, Game game) {
if (spellAbility instanceof WarpAbility) {
game.addDelayedTriggeredAbility(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new WarpExileEffect()), spellAbility
);
}
}
@Override @Override
public ActivationStatus canActivate(UUID playerId, Game game) { public ActivationStatus canActivate(UUID playerId, Game game) {
switch (game.getState().getZone(getSourceId())) { switch (game.getState().getZone(getSourceId())) {
@ -104,6 +116,13 @@ public class WarpAbility extends SpellAbility {
public static String makeWarpString(UUID playerId) { public static String makeWarpString(UUID playerId) {
return playerId + "- Warped"; return playerId + "- Warped";
} }
public static boolean checkIfPermanentWarped(Permanent permanent, Game game) {
return permanent != null
&& game.getPermanentCostsTags()
.getOrDefault(new MageObjectReference(permanent, game, -1), Collections.emptyMap())
.containsKey(WarpAbility.WARP_ACTIVATION_VALUE_KEY);
}
} }
class WarpExileEffect extends OneShotEffect { class WarpExileEffect extends OneShotEffect {
@ -122,8 +141,9 @@ class WarpExileEffect extends OneShotEffect {
} }
} }
WarpExileEffect() { WarpExileEffect(Permanent permanent, Game game) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.setTargetPointer(new FixedTarget(permanent, game));
staticText = "exile this creature if it was cast for its warp cost"; staticText = "exile this creature if it was cast for its warp cost";
} }
@ -138,9 +158,12 @@ class WarpExileEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent == null) {
if (permanent == null || permanent.getZoneChangeCounter(game) != source.getSourceObjectZoneChangeCounter() + 1) { return false;
}
Player player = game.getPlayer(permanent.getOwnerId());
if (player == null) {
return false; return false;
} }
player.moveCardsToExile( player.moveCardsToExile(
@ -155,3 +178,23 @@ class WarpExileEffect extends OneShotEffect {
return true; return true;
} }
} }
class WarpAbilityWatcher extends Watcher {
WarpAbilityWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
return;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (WarpAbility.checkIfPermanentWarped(permanent, game)) {
game.addDelayedTriggeredAbility(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new WarpExileEffect(permanent, game)), permanent.getSpellAbility()
);
}
}
}

View file

@ -0,0 +1,72 @@
package mage.abilities.keyword;
import mage.MageIdentifier;
import mage.abilities.SpellAbility;
import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.cards.Card;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.target.common.TargetControlledPermanent;
import java.util.Set;
/**
* @author LevelX2
*/
public class WebSlingingAbility extends SpellAbility {
public static final String WEB_SLINGING_ACTIVATION_VALUE_KEY = "webSlingingActivation";
private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("tapped creature you control");
static {
filter.add(TappedPredicate.TAPPED);
}
public WebSlingingAbility(Card card, String manaString) {
super(card.getSpellAbility());
this.newId();
this.setCardName(card.getName() + " with Web-slinging");
zone = Zone.HAND;
spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
this.clearManaCosts();
this.clearManaCostsToPay();
this.addCost(new ManaCostsImpl<>(manaString));
this.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.setRuleAtTheTop(true);
}
protected WebSlingingAbility(final WebSlingingAbility ability) {
super(ability);
}
@Override
public boolean activate(Game game, Set<MageIdentifier> allowedIdentifiers, boolean noMana) {
if (!super.activate(game, allowedIdentifiers, noMana)) {
return false;
}
this.setCostsTag(WEB_SLINGING_ACTIVATION_VALUE_KEY, null);
return true;
}
@Override
public WebSlingingAbility copy() {
return new WebSlingingAbility(this);
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder("Web-slinging ");
sb.append(getManaCosts().getText());
sb.append(" <i>(You may cast this spell for ");
sb.append(getManaCosts().getText());
sb.append(" if you also return a tapped creature you control to its owner's hand.)</i>");
return sb.toString();
}
}

View file

@ -1093,6 +1093,13 @@ public final class StaticFilters {
FILTER_SPELL_KICKED_A.setLockedFilter(true); FILTER_SPELL_KICKED_A.setLockedFilter(true);
} }
public static final FilterSpell FILTER_SPELL_MV_4_OR_GREATER = new FilterSpell("spell with mana value 4 or greater");
static {
FILTER_SPELL_MV_4_OR_GREATER.add(new ManaValuePredicate(ComparisonType.OR_GREATER, 4));
FILTER_SPELL_MV_4_OR_GREATER.setLockedFilter(true);
}
public static final FilterSpell FILTER_SPELL_NO_MANA_SPENT = new FilterSpell("a spell, if no mana was spent to cast it"); public static final FilterSpell FILTER_SPELL_NO_MANA_SPENT = new FilterSpell("a spell, if no mana was spent to cast it");
static { static {

View file

@ -1,18 +1,22 @@
package mage.filter.common; package mage.filter.common;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
/** /**
* TODO: Collapse this into FilterCard
*
* @author LevelX2 * @author LevelX2
*/ */
public class FilterBySubtypeCard extends FilterCard { public class FilterBySubtypeCard extends FilterCard {
public FilterBySubtypeCard(SubType subtype) { public FilterBySubtypeCard(SubType subtype) {
super(subtype + " card"); this(subtype, subtype + " card");
}
public FilterBySubtypeCard(SubType subtype, String name) {
super(name);
this.add(subtype.getPredicate()); this.add(subtype.getPredicate());
} }

View file

@ -5,6 +5,8 @@ import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.Optional;
/** /**
* Filters out the id of the enchanted object, if the source is an enchantment * Filters out the id of the enchanted object, if the source is an enchantment
* *
@ -15,8 +17,13 @@ public enum AnotherEnchantedPredicate implements ObjectSourcePlayerPredicate<Per
@Override @Override
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) { public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
Permanent enchantment = input.getSource().getSourcePermanentIfItStillExists(game); return !Optional
return enchantment != null && !input.getObject().getId().equals(enchantment.getAttachedTo()); .ofNullable(input)
.map(ObjectSourcePlayer::getSource)
.map(source -> source.getSourcePermanentOrLKI(game))
.map(Permanent::getAttachedTo)
.filter(input.getObject().getId()::equals)
.isPresent();
} }
@Override @Override

View file

@ -0,0 +1,31 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.abilities.keyword.ReachAbility;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author TheElk801
*/
public final class Spider21Token extends TokenImpl {
public Spider21Token() {
super("Spider Token", "2/1 green Spider creature token with reach");
cardType.add(CardType.CREATURE);
color.setGreen(true);
subtype.add(SubType.SPIDER);
power = new MageInt(2);
toughness = new MageInt(1);
this.addAbility(ReachAbility.getInstance());
}
private Spider21Token(final Spider21Token token) {
super(token);
}
public Spider21Token copy() {
return new Spider21Token(this);
}
}

View file

@ -8,7 +8,6 @@ import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.keyword.BestowAbility; import mage.abilities.keyword.BestowAbility;
import mage.abilities.keyword.PrototypeAbility; import mage.abilities.keyword.PrototypeAbility;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.abilities.keyword.WarpAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.*; import mage.constants.*;
import mage.counters.Counter; import mage.counters.Counter;
@ -422,7 +421,6 @@ public class Spell extends StackObjectImpl implements Card {
} else { } else {
MageObjectReference mor = new MageObjectReference(getSpellAbility()); MageObjectReference mor = new MageObjectReference(getSpellAbility());
game.storePermanentCostsTags(mor, getSpellAbility()); game.storePermanentCostsTags(mor, getSpellAbility());
WarpAbility.addDelayedTrigger(getSpellAbility(), game);
return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
} }
} }

View file

@ -149,4 +149,5 @@ Vanishing|number|
Vigilance|instance| Vigilance|instance|
Ward|cost| Ward|cost|
Warp|card, manaString| Warp|card, manaString|
Web-slinging|card, manaString|
Wither|instance| Wither|instance|

View file

@ -176,6 +176,7 @@ Magic Origins|MagicOrigins|
Magic Player Rewards|MagicPlayerRewards| Magic Player Rewards|MagicPlayerRewards|
Magic: The Gathering-Commander|Commander| Magic: The Gathering-Commander|Commander|
Magic: The Gathering-Conspiracy|Conspiracy| Magic: The Gathering-Conspiracy|Conspiracy|
Marvel's Spider-Man|MarvelsSpiderMan|
Marvel's Spider-Man Eternal|MarvelsSpiderManEternal| Marvel's Spider-Man Eternal|MarvelsSpiderManEternal|
Masterpiece Series|MasterpieceSeries| Masterpiece Series|MasterpieceSeries|
Masterpiece Series Amonkhet|MasterpieceSeriesAmonkhet| Masterpiece Series Amonkhet|MasterpieceSeriesAmonkhet|

View file

@ -59102,6 +59102,26 @@ Vault of the Archangel|Tarkir: Dragonstorm Commander|410|R||Land|||{T}: Add {C}.
Windbrisk Heights|Tarkir: Dragonstorm Commander|411|R||Land|||Hideaway 4$This land enters tapped.${T}: Add {W}.${W}, {T}: You may play the exiled card without paying its mana cost if you attacked with three or more creatures this turn.| Windbrisk Heights|Tarkir: Dragonstorm Commander|411|R||Land|||Hideaway 4$This land enters tapped.${T}: Add {W}.${W}, {T}: You may play the exiled card without paying its mana cost if you attacked with three or more creatures this turn.|
Woodland Cemetery|Tarkir: Dragonstorm Commander|412|R||Land|||This land enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.| Woodland Cemetery|Tarkir: Dragonstorm Commander|412|R||Land|||This land enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.|
Yavimaya Coast|Tarkir: Dragonstorm Commander|413|R||Land|||{T}: Add {C}.${T}: Add {G} or {U}. This land deals 1 damage to you.| Yavimaya Coast|Tarkir: Dragonstorm Commander|413|R||Land|||{T}: Add {C}.${T}: Add {G} or {U}. This land deals 1 damage to you.|
Amateur Hero|Marvel's Spider-Man Eternal|1|C|{2}{W}|Creature - Human Hero|3|3|When this creature enters, you gain 2 life.|
Amazing Alliance|Marvel's Spider-Man Eternal|2|R|{1}{W}{W}|Enchantment|||Creatures you control get +1/+1.$Whenever you attack with one or more legendary creatures, you gain that much life.|
MJ, Rising Star|Marvel's Spider-Man Eternal|3|U|{2}{W}|Legendary Creature - Human Performer|2|3|Vigilance$Whenever you gain life, put a +1/+1 counter on MJ.|
Spider-Man, Peter Parker|Marvel's Spider-Man Eternal|4|M|{3}{W}{W}|Legendary Creature - Spider Human Hero|4|4|Flying$Whenever you gain life, put a +1/+1 counter on target creature you control. It gains indestructible until end of turn.|
Alchemax Slayer-Bots|Marvel's Spider-Man Eternal|5|C|{2}{U}|Artifact Creature - Robot Villain|2|2|When this creature enters, tap target creature an opponent controls and put a stun counter on it.|
Future Flight|Marvel's Spider-Man Eternal|6|R|{2}{U}{U}|Enchantment - Aura|||Enchant creature$When this Aura enters, draw two cards.$Enchanted creature gets +2/+0 and has flying.|
Lyla, Holographic Assistant|Marvel's Spider-Man Eternal|7|U|{3}{U}|Legenday Artifact Creature - Illusion Advisor|2|2|Whenever you draw a card, put a +1/+1 counter on target creature.|
Spider-Man 2099, Miguel O'Hara|Marvel's Spider-Man Eternal|8|M|{4}{U}|Legendary Creature - Spider Human Hero|4|4|When Spider-Man 2099 enters, return up to one target creature to its owner's hand.$Whenever one or more creatures you control deal combat damage to a player, draw a card.|
Grendel, Spawn of Knull|Marvel's Spider-Man Eternal|9|U|{3}{B}|Legendary Creature - Symbiote Dragon Villain|3|3|Flying$Deathtouch|
Lethal Protection|Marvel's Spider-Man Eternal|10|R|{3}{B}|Sorcery|||Destroy target creature. Return up to one target creature card from your graveyard to your hand.|
Symbiote Spawn|Marvel's Spider-Man Eternal|11|C|{2}{B}|Creature - Symbiote Villain|3|2|When this creature dies, each opponent loses 2 life and you gain 2 life.|
Venom, Eddie Brock|Marvel's Spider-Man Eternal|12|M|{4}{B}{B}|Legendary Creature - Symbiote Villain|6|4|Menace$Whenever another creature dies, put a +1/+1 counter on Venom. If that creature was a Villain, draw a card.|
Double Trouble|Marvel's Spider-Man Eternal|13|R|{4}{R}|Instant|||Double the power of each creature you control until end of turn.|
Ghost-Spider, Gwen Stacy|Marvel's Spider-Man Eternal|14|M|{3}{R}{R}|Legendary Creature - Spider Human Hero|4|4|Menace$Whenever Ghost-Spider attacks, she deals X damage to defending player, where X is the number of attacking creatures.|
The Mary Janes|Marvel's Spider-Man Eternal|15|U|{3}{R}|Legendary Creature - Human Bard Performer|3|3|This spell costs {1} less to cast for each creature that attacked this turn.$Menace|
Rampaging Classmate|Marvel's Spider-Man Eternal|16|C|{2}{R}|Creature - Lizard Berserker|3|2|Whenever this creature attacks, it gets +1/+0 until end of turn for each other attacking creature.|
Prowler, Misguided Mentor|Marvel's Spider-Man Eternal|17|U|{2}{G}|Legendary Creature - Human Rogue Villain|3|3|Prowler can't be blocked by creatures with power 2 or less.$Whenever Prowler deals combat damage to a player, put a +1/+1 counter on another target creature you control.|
Spider-Man, Miles Morales|Marvel's Spider-Man Eternal|18|M|{4}{G}{G}|Legendary Creature - Spider Human Hero|5|5|Vigilance, trample$Whenever Spider-Man enters or attacks, put a +1/+1 counter on each other creature you control. Those creatures gain trample until end of turn.|
Twisted Spider-Clone|Marvel's Spider-Man Eternal|19|C|{3}{G}|Creature - Spider Human|4|4|When this creature enters, put a +1/+1 counter on each creature you control with a +1/+1 counter on it.|
Venom Blast|Marvel's Spider-Man Eternal|20|R|{2}{G}{G}|Sorcery|||Put two +1/+1 counters on target creature you control. It deals damage equal to its power to up to one other target creature.|
Grasping Tentacles|Marvel's Spider-Man Eternal|21|R|{1}{U}{B}|Sorcery|||Target opponent mills eight cards. You may put an artifact card from that player's graveyard onto the battlefield under your control.| Grasping Tentacles|Marvel's Spider-Man Eternal|21|R|{1}{U}{B}|Sorcery|||Target opponent mills eight cards. You may put an artifact card from that player's graveyard onto the battlefield under your control.|
Venom, Deadly Devourer|Marvel's Spider-Man Eternal|22|R|{2}{B}{G}|Legendary Creature - Symbiote Villain|4|4|Vigilance, menace${3}: Exile target creature card from a graveyard. When you do, put X +1/+1 counters on target Symbiote, where X is the exiled card's toughness.| Venom, Deadly Devourer|Marvel's Spider-Man Eternal|22|R|{2}{B}{G}|Legendary Creature - Symbiote Villain|4|4|Vigilance, menace${3}: Exile target creature card from a graveyard. When you do, put X +1/+1 counters on target Symbiote, where X is the exiled card's toughness.|
Green Goblin, Nemesis|Marvel's Spider-Man Eternal|23|R|{2}{B}{R}|Legendary Creature - Goblin Human Villain|3|3|Flying$Whenever you discard a nonland card, put a +1/+1 counter on target Goblin you control.$Whenever you discard a land card, create a tapped Treasure token.| Green Goblin, Nemesis|Marvel's Spider-Man Eternal|23|R|{2}{B}{R}|Legendary Creature - Goblin Human Villain|3|3|Flying$Whenever you discard a nonland card, put a +1/+1 counter on target Goblin you control.$Whenever you discard a land card, create a tapped Treasure token.|
@ -59700,3 +59720,62 @@ Viridescent Bog|Edge of Eternities Commander|190|R||Land|||{1}, {T}: Add {B}{G}.
Wastes|Edge of Eternities Commander|191|C||Basic Land|||{T}: Add {C}.| Wastes|Edge of Eternities Commander|191|C||Basic Land|||{T}: Add {C}.|
Avatar Aang|Avatar: The Last Airbender|363|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.| Avatar Aang|Avatar: The Last Airbender|363|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.|
Aang, Master of Elements|Avatar: The Last Airbender|363|M||Legendary Creature - Avatar Ally|6|6|Flying$Spelsl you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.| Aang, Master of Elements|Avatar: The Last Airbender|363|M||Legendary Creature - Avatar Ally|6|6|Flying$Spelsl you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.|
Aunt May|Marvel's Spider-Man|3|U|{W}|Legendary Creature - Human Citizen|0|2|Whenever another creature you control enters, you gain 1 life. If it's a Spider, put a +1/+1 counter on it.|
Daily Bugle Reporters|Marvel's Spider-Man|6|C|{3}{W}|Creature - Human Citizen|2|3|When this creature enters, choose one --$* Puff Piece -- Put a +1/+1 counter on each of up to two target creatures.$* Investigative Journalism -- Return target creature card with mana value 2 or less from your graveyard to your hand.|
Origin of Spider-Man|Marvel's Spider-Man|9|R|{1}{W}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Create a 2/1 green Spider creature token with reach.$II -- Put a +1/+1 counter on target creature you control. It becomes a legendary Spider Hero in addition to its other types.$III -- Target creature you control gains double strike until end of turn.|
Peter Parker|Marvel's Spider-Man|10|M|{1}{W}|Legendary Creature - Human Scientist Hero|0|1|When Peter Parker enters, create a 2/1 green Spider creature token with reach.${1}{G}{W}{U}: Transform Peter Parker. Activate only as a sorcery.|
Amazing Spider-Man|Marvel's Spider-Man|10|M|{1}{G}{W}{U}|Legendary Creature - Spider Human Hero|4|4|Vigilance, reach$Each legendary spell you cast that's one or more colors has web-slinging {G}{W}{U}.|
Selfless Police Captain|Marvel's Spider-Man|12|C|{1}{W}|Creature - Human Detective|1|1|This creature enters with a +1/+1 counter on it.$When this creature leaves the battlefield, put its +1/+1 counters on target creature you control.|
Spectacular Tactics|Marvel's Spider-Man|15|C|{1}{W}|Instant|||Choose one --$* Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.$* Destroy target creature with power 4 or greater.|
Spider-Man, Web-Slinger|Marvel's Spider-Man|16|C|{2}{W}|Legendary Creature - Spider Human Hero|3|3|Web-slinging {W}|
Starling, Aerial Ally|Marvel's Spider-Man|18|C|{4}{W}|Legendary Creature - Human Hero|3|4|Flying$When Starling enters, another target creature you control gains flying until end of turn.|
Thwip!|Marvel's Spider-Man|20|C|{W}|Instant|||Target creature gets +2/+2 and gains flying until end of turn. If it's a Spider, you gain 2 life.|
Web Up|Marvel's Spider-Man|21|C|{2}{W}|Enchantment|||When this enchantment enters, exile target nonland permanent an opponent controls until this enchantment leaves the battlefield.|
Wild Pack Squad|Marvel's Spider-Man|23|C|{2}{W}|Creature - Human Mercenary|2|3|At the beginning of combat on your turn, up to one target creature gains first strike and vigilance until end of turn.|
Beetle, Legacy Criminal|Marvel's Spider-Man|26|C|{3}{U}|Legendary Creature - Human Rogue Villain|3|3|Flying${1}{U}, Exile this card from your graveyard: Put a +1/+1 counter on target creature. It gains flying until end of turn. Activate only as a sorcery.|
Doc Ock, Sinister Scientist|Marvel's Spider-Man|29|C|{4}{U}|Legendary Creature - Human Scientist Villain|4|5|As long as there are eight or more cards in your graveyard, Doc Ock has base power and toughness 8/8.$As long as you control another Villain, Doc Ock has hexproof.|
Doc Ock's Henchmen|Marvel's Spider-Man|30|C|{2}{U}|Creature - Human Villain|2|1|Flash$Whenever this creature attacks, it connives.|
Flying Octobot|Marvel's Spider-Man|31|U|{1}{U}|Artifact Creature - Robot Villain|1|1|Flying$Whenever another Villain you control enters, put a +1/+1 counter on this creature. This ability triggers only once each turn.|
Oscorp Research Team|Marvel's Spider-Man|40|C|{3}{U}|Creature - Human Scientist|1|5|{6}{U}: Draw two cards.|
Spider-Byte, Web Warden|Marvel's Spider-Man|44|U|{2}{U}|Legendary Creature - Spider Avatar Hero|2|2|When Spider-Byte enters, return up to one target nonland permanent to its owner's hand.|
Unstable Experiment|Marvel's Spider-Man|47|C|{1}{U}|Instant|||Target player draws a card, then up to one target creature you control connives.|
Whoosh!|Marvel's Spider-Man|48|C|{1}{U}|Instant|||Kicker {1}{U}$Return target nonland permanent to its owner's hand. If this spell was kicked, draw a card.|
Merciless Enforcers|Marvel's Spider-Man|58|C|{1}{B}|Creature - Human Mercenary Villain|2|1|Lifelink${3}{B}: This creature deals 1 damage to each opponent.|
Risky Research|Marvel's Spider-Man|62|C|{2}{B}|Sorcery|||Surveil 2, then draw two cards. You lose 2 life.|
Scorpion, Seething Striker|Marvel's Spider-Man|64|U|{3}{B}|Legendary Creature - Scorpion Human Villain|3|3|Deathtouch$At the beginning of your end step, if a creature died this turn, target creature you control connives.|
Scorpion's Sting|Marvel's Spider-Man|65|C|{1}{B}|Instant|||Target creature gets -3/-3 until end of turn.|
Spider-Man Noir|Marvel's Spider-Man|67|U|{4}{B}|Legendary Creature - Spider Human Hero|4|4|Menace$Whenever a creature you control attacks alone, put a +1/+1 counter on it. Then surveil X, where X is the number of counters on it.|
Tombstone, Career Criminal|Marvel's Spider-Man|70|U|{2}{B}|Legendary Creature - Human Villain|2|2|When Tombstone enters, return target Villain card from your graveyard to your hand.$Villain spells you cast cost {1} less to cast.|
Venom, Evil Unleashed|Marvel's Spider-Man|71|C|{4}{B}|Legendary Creature - Symbiote Villain|4|5|Deathtouch${2}{B}, Exile this card from your graveyard: Put two +1/+1 counters on target creature. It gains deathtouch until end of turn. Activate only as a sorcery.|
Venom's Hunger|Marvel's Spider-Man|73|C|{4}{B}|Sorcery|||This spell costs {2} less to cast if you control a Villain.$Destroy target creature. You gain 2 life.|
Angry Rabble|Marvel's Spider-Man|75|C|{1}{R}|Creature - Human Citizen|2|2|Trample$Whenever you cast a spell with mana value 4 or greater, this creature deals 1 damage to each opponent.${5}{R}: Put two +1/+1 counters on this creature. Activate only as a sorcery.|
Electro's Bolt|Marvel's Spider-Man|77|C|{2}{R}|Sorcery|||Electro's Bolt deals 4 damage to target creature.$Mayhem {1}{R}|
Masked Meower|Marvel's Spider-Man|82|C|{R}|Creature - Spider Cat Hero|1|1|Haste$Discard a card, Sacrifice this creature: Draw a card.|
Romantic Rendezvous|Marvel's Spider-Man|86|C|{1}{R}|Sorcery|||Discard a card, then draw two cards.|
Shock|Marvel's Spider-Man|88|C|{R}|Instant|||Shock deals 2 damage to any target.|
Shocker, Unshakable|Marvel's Spider-Man|89|U|{4}{R}{R}|Legendary Creature - Human Rogue Villain|5|5|During your turn, Shocker has first strike.$Vibro-Shock Gauntlets -- When Shocker enters, he deals 2 damage to target creature and 2 damage to that creature's controller.|
Spider-Gwen, Free Spirit|Marvel's Spider-Man|90|C|{2}{R}|Legendary Creature - Spider Human Hero|2|3|Reach$Whenever Spider-Gwen becomes tapped, you may discard a card. If you do, draw a card.|
Spider-Islanders|Marvel's Spider-Man|91|C|{3}{R}|Creature - Spider Horror Citizen|4|3|Mayhem {1}{R}|
Stegron the Dinosaur Man|Marvel's Spider-Man|95|C|{4}{R}|Legendary Creature - Dinosaur Villain|5|4|Menace$Dinosaur Formula -- {1}{R}, Discard this card: Until end of turn, target creature you control gets +3/+1 and becomes a Dinosaur in addition to its other types.|
Taxi Driver|Marvel's Spider-Man|97|C|{1}{R}|Creature - Human Pilot|3|1|{1}, {T}: Target creature gains haste until end of turn.|
Grow Extra Arms|Marvel's Spider-Man|101|C|{1}{G}|Instant|||This spell costs {1} less to cast if it targets a Spider.$Target creature gets +4/+4 until end of turn.|
Guy in the Chair|Marvel's Spider-Man|102|C|{2}{G}|Creature - Human Advisor|2|3|{T}: Add one mana of any color.$Web Support -- {2}{G}, {T}: Put a +1/+1 counter on target Spider. Activate only as a sorcery.|
Kapow!|Marvel's Spider-Man|103|C|{2}{G}|Sorcery|||Put a +1/+1 counter on target creature you control. It fights target creature an opponent controls.|
Kraven's Cats|Marvel's Spider-Man|104|C|{1}{G}|Creature - Cat Villain|2|2|{2}{G}: This creature gets +2/+2 until end of turn. Activate only once each turn.|
Lurking Lizards|Marvel's Spider-Man|107|C|{1}{G}|Creature - Lizard Villain|1|3|Trample$Whenever you cast a spell with mana value 4 or greater, put a +1/+1 counter on this creature.|
Scout the City|Marvel's Spider-Man|113|C|{1}{G}|Sorcery|||Choose one --$* Look Around -- Mill three cards. You may put a permanent card from among them into your hand. You gain 3 life.$* Bring Down -- Destroy target creature with flying.|
Spider-Ham, Peter Porker|Marvel's Spider-Man|114|R|{1}{G}|Legendary Creature - Spider Boar Hero|2|2|When Spider-Ham enters, create a Food token.$Animal May-Ham -- Other Spiders, Boars, Bats, Bears, Birds, Cats, Dogs, Frogs, Jackals, Lizards, Mice, Otters, Rabbits, Raccoons, Rats, Squirrels, Turtles, and Wolves you control get +1/+1.|
Spider-Man, Brooklyn Visionary|Marvel's Spider-Man|115|C|{4}{G}|Legendary Creature - Spider Human Hero|4|3|Web-slinging {2}{G}$When Spider-Man enters, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.|
Spider-Rex, Daring Dino|Marvel's Spider-Man|116|C|{4}{G}{G}|Legendary Creature - Spider Dinosaur Hero|6|6|Reach, trample$Ward {2}|
SP//dr, Piloted by Peni|Marvel's Spider-Man|147|U|{3}{W}{U}|Legendary Artifact Creature - Spider Hero|4|4|Vigilance$When SP//dr enters, put a +1/+1 counter on target creature.$Whenever a modified creature you control deals combat damage to a player, draw a card.|
Spider-Man 2099|Marvel's Spider-Man|150|R|{U}{R}|Legendary Creature - Spider Human Hero|2|3|From the Future -- You can't cast Spider-Man 2099 during your first, second, or third turns of the game.$Double strike, vigilance$At the beginning of your end step, if you've played a land or cast a spell this turn from anywhere other than your hand, Spider-Man 2099 deals damage equal to his power to any target.|
Eerie Gravestone|Marvel's Spider-Man|163|C|{2}|Artifact|||When this artifact enters, draw a card.${1}{B}, Sacrifice this artifact: Mill four cards. You may put a creature card from among them into your hand.|
Mechanical Mobster|Marvel's Spider-Man|168|C|{3}|Artifact Creature - Human Robot Villain|2|1|When this creature enters, exile up to one target card from a graveyard. Target creature you control connives.|
Spider-Bot|Marvel's Spider-Man|173|C|{2}|Artifact Creature - Spider Robot Scout|2|1|Reach$When this creature enters, you may search your library for a basic land card, reveal it, then shuffle and put that card on top.|
Plains|Marvel's Spider-Man|194|C||Basic Land - Plains|||({T}: Add {W}.)|
Island|Marvel's Spider-Man|195|C||Basic Land - Island|||({T}: Add {U}.)|
Swamp|Marvel's Spider-Man|196|C||Basic Land - Swamp|||({T}: Add {B}.)|
Mountain|Marvel's Spider-Man|197|C||Basic Land - Mountain|||({T}: Add {R}.)|
Forest|Marvel's Spider-Man|198|C||Basic Land - Forest|||({T}: Add {G}.)|
Peter Parker|Marvel's Spider-Man|232|M|{1}{W}|Legendary Creature - Human Scientist Hero|0|1|When Peter Parker enters, create a 2/1 green Spider creature token with reach.${1}{G}{W}{U}: Transform Peter Parker. Activate only as a sorcery.|
Amazing Spider-Man|Marvel's Spider-Man|232|M|{1}{G}{W}{U}|Legendary Creature - Spider Human Hero|4|4|Vigilance, reach$Each legendary spell you cast that's one or more colors has web-slinging {G}{W}{U}.|

View file

@ -176,6 +176,7 @@ Masters 25|A25|
Magic: The Gathering-Commander|CMD| Magic: The Gathering-Commander|CMD|
Magic: The Gathering-Conspiracy|CNS| Magic: The Gathering-Conspiracy|CNS|
Media Inserts|MBP| Media Inserts|MBP|
Marvel's Spider-Man|SPM|
Marvel's Spider-Man Eternal|SPE| Marvel's Spider-Man Eternal|SPE|
March of the Machine|MOM| March of the Machine|MOM|
March of the Machine Commander|MOC| March of the Machine Commander|MOC|